PHP - Check duplicated array - php

I have for example one array:
1,2,3,4,5,5,6,7,8,9
Now this array gets sorted into three arrays (randomly)
For example:
1,2,3
4,5,6
7,8,9
Now I have to create 3 arrays again with the same numbers (1-9)
But the new arrays should not include any same numbers as in the past array;
1,3,5 (incorrect, 3 has already been with 1)
1,5,7 (correct, all numbers are new to eachother)
Now I found a way to detect this using loops, below you see a part of the code.
$temp_plr are the new random created numbers (3 numbered array).
$team_check is on of the previous 3 numbered arrays.
This check gets executed untill it found a new combination that didnt show up before.
It works, but it is really slow sometimes, which makes the browser time-out or it just loops forever.
If you need more explanation please tell me.
if((in_array($temp_plr[0], $team_check) && in_array($temp_plr[1],$team_check))
|| (in_array($temp_plr[0],$team_check) && in_array( $temp_plr[2],$team_check))
|| (in_array($temp_plr[1],$team_check) && in_array( $temp_plr[2],$team_check))
) {
$okey = false;
}
$temp_plr includes 3 values and $team_check also includes 3 values.
image of the end result I have made with this code:
http://i57.tinypic.com/9hqv4w.png
Like you see, alle numbers in each 3 numbered team are different from eachother in each round.

It would be easier to look at it differently.
Get your first trio of arrays as you are doing already.
Then, instead of just generating a new trio and seeing if it fits the rules, make it fit the rules.
To do this, build your new trio by picking one number from the first row of the old trio, then one from the second row, then one from the third.
For instance, if your first trio is:
1 2 3
4 5 6
7 8 9
You can generate a new trio by picking a random number from each row:
1 5 9
2 4 7
3 6 8
This is guaranteed to fit the rule, and is capable of generating all such results from any given "old trio".

Related

how do i determine which questions to ask a user in a quiz based on previous answers

I have a list of questions in a category, and want to choose a subset of them to ask the user based on which ones they answered right/wrong previously.
I want to make it random, but in a way that the ones they have more trouble with are asked more frequently.
EDIT: I'm trying to figure out how to calculate the weight/bias/score for each question based on the number of times they've answered it right/wrong.
I came up with the following, but it seems odd to me:
I assign a score to each question based on how many times they answered it right/wrong
Obviously, if they've never been asked that question I need to assign an arbitrary score (I chose 5)
For all other question, I use the formula
score = wrong*2-right
so if I had the following 10 questions, the "score" would be calculated for each of them (R=# of times they got it right, W=# of times they got it wrong and S=score). From there, I take the lowest score and assign that a probability of 1 (in this case it was id=5 with a score of -7). I then take the difference between the lowest score and the second lowest score (id=1 with -5, a difference of 2) and assign it a probability of 1 + the difference = 3.
I continue this for every question, and then at the end I can just choose a random number between Min(1) and Max(82) and select the question that has the highest P where random < P. So if my random # was 79 I would choose id=2.
But this seems long and convoluted. Is there an easier way to do this (I'm using PHP and mysql, But I plan to do this within an app with a local datastore as well)
id R W S P
1 5 0 -5 3
2 3 5 7 82
3 6 2 -2 8
4 2 2 2 23
5 9 1 -7 1
6 3 1 -1 14
7 0 0 5 68
8 7 5 3 33
9 6 5 4 44
10 3 4 5 56
EDIT: to clarify, I'm stuck on the issue of "weight" (P value in my example)...I'm trying to find a good (and fast) way of calculating the "weight" for each problem, given the number of right and wrong answers they've given for the question
I am not sure if I understand your answer correctly but it seems you are looking for a sort of "weighted" random number generator. In essense what you want to do is give the problems they are having issues with more weight. Perhaps create a class called questions with a property of weight in it. That property can hold how much weight you put in it. Then when you select a random number generator use something like this.
http://codetheory.in/weighted-biased-random-number-generation-with-javascript-based-on-probability/
After doing some research, I realize that my initial method of calculating a weight is bit slow. After using the formula, I end up with some -ve weights. I then have to go through each one and add ABS(MIN(S)) to each weight, which is unnecessary.
My new formula would be S = CEILING(Wrong * 5 / Right)
Obviously I'd need to account for 0 values, so the code would be:
if (R == 0 AND W == 0) S = 10
else if (R == 0) S = W*5
else if (W == 0) S = CEILING(5/R)
else S = CEILING(W * 5 / R)
I've worked out the numbers for a few sample sets and this gives me fairly good results. It also allows me to keep the SCORE value updated in the database, so it doesn't need to be recalculated every time (just updated whenever that question is answered)
Once I have a set of 60 or so questions and I want to choose 5 or 10 of them, I can just create a random # between 1-SUM(SCORE) and then use a binary search to figure out which question that represents.
If anyone has a better suggestion for calculating the score/weight/bias or whatever it's called, I'd appreciate it.

How to make a Random Walk, PHP?

I've been trying for several hours to make a random walk (a path) like this one.
From top to down.
x 1 x
x 2 3
x x 4
7 6 5
8 x x
9 10 x
My greatest difficulty is to calculate the displacement from right to left because the cycles (for, while..) go from left to right.
I am not proficient in math, so I'm using a simple approach.
I have two arrays. One with the position of the previous row.
$previousRow=array(1=>"x",2=>"1",3=>"x");
One with the current row I have to fill.
$currentRow=array(1=>"",2=>"",3=>"");
$p //Is the current position. 1, 2 or 3. Example $currentRow[$p]
$last //the last number that increases each time the path has a new step.
I'm using some cycles and conditions to set the displacement.
Is this approach wrong?
EDIT: further specifications as requested from comments:
Start point is located in the middle point of the first row
End point is located in the last row
End point can be located in any column of the last row
per each field you have three possibilities: left, right, forward.
some cases reduce this, e.g. there is no field to the left or right or that field was visited already.
so find out about possible moves, pick one at random and go on.

How do I group sum of variables in php that are closest to a value, but also unique

Let's say I have an array (5,3,5,7,10)
the number desired is 12
So i want the first stack to be:
------------------------ first output --------
7+5 = 12 (the best combination with lower number of variables) - exclude 7 and 5, don't ever use it
------------ second output ------------
10 - because it's the second variable closest to 12. (then exclude 10, don't ever use it)
------------ third output ----------
5+3 = 8 - because it's the third closest to 12
I searched all the internet but i don't find a clue
THankyou
This problem is a harder version of the Subset Sum Problem
The successive sub-problems are essentially the approximation version on a smaller subset. Solving this problem for large arrays exactly will be brutally slow.

MySQL traverse graph data and get non-cyclic path

This one is a hard one for me to solve, basically I have data in a table looking like this:
id a b
1 2 4
2 4 2
3 5 2
4 2 5
5 6 2
6 2 6
7 8 6
8 6 8
9 5 6
...
You can see how complex the structure gets if you try to establish what parent has what children:
[2->[4->[2->RECURSIVE], 5->[2->RECURSIVE], 6->[2->RECURSIVE, 8->[6->[8->RECURSIVE]]]], ...]
I fear MySQL alone can't manage to efficiently find a path, but considering I write this in PHP maybe I could write some way for it to maybe first query the 800 lines of code then program an efficient way to parse the data.
The idea is that this function that I am trying to make, let's call it makePath() takes two parameters and returns an array with sub-arrays and the id's referring to a line in the data table.
For example makePath(2,8) would return:
array(array(2,6,8), array(2,5,6,8))
Since these are the only paths going from 2 to 8 without backtracking (i.e. going [2,5,2,6,8] and infinite other combinations of paths.)
I am stuck on how to start all this, hopefully someone brighter than me on the graph and cyclic theory could explain how I should start my code -thanks for your time!
You should be able to do this with a depth-first search on a directed graph structure. A basic outline would look like:
Create the graph. You'll need at a minimum a list of children and a visiting flag per node.
Call visit with the initial node. For your visit function, you'll need to know the destination node, have a reference to the result array, and keep track of the nodes visited along the current path in a stack.
If the current node is the final node, then add the path traveled (by going through the stack) to the result array.
If the node is being visited, then return.
If the node is not being visited, then
mark the node as being visited
call visit(recursion) with each child
unmark the node as being visited
If you need help with any of the steps, then please ask.

php (fuzzy) search matching

if anyone has ever submitted a story to digg, it checks whether or not the story is already submitted, I assume by a fuzzy search.
I would like to implement something similar and want to know if they are using a php class that is open source?
Soundex isnt doing it, sentences/strings can be up to 250chars in length
Unfortunately, doing this in PHP is prohibitively expensive (high CPU and memory utilization.) However, you can certainly apply the algorithm to small data sets.
To specifically expand on how you can create a server meltdown: couple of built-in PHP functions will determine "distance" between strings: levenshtein and similar_text.
Dummy data: (pretend they're news headlines)$titles = <<< EOF
Apple
Apples
Orange
Oranges
Banana
EOF;
$titles = explode("\n", $titles );
At this point, $titles should just be an array of strings. Now, create a matrix and compare each headline against EVERY other headline for similarity. In other words, for 5 headlines, you will get a 5 x 5 matrix (25 entries.) That's where the CPU and memory sink goes in.
That's why this method (via PHP) can't be applied to thousands of entries. But if you wanted to:
$matches = array();
foreach( $titles as $title ) {
$matches[$title] = array();
foreach( $titles as $compare_to ) {
$matches[$title][$compare_to] = levenshtein( $compare_to, $title );
}
asort( $matches[$title], SORT_NUMERIC );
}
At this point what you basically have is a matrix with "text distances." In concept (not in real data) it looks sort of like this table below. Note how there is a set of 0 values that go diagonally - that means that in the matching loop, two identical words are -- well, identical.
Apple Apples Orange Oranges Banana
Apple 0 1 5 6 6
Apples 1 0 6 5 6
Orange 5 6 0 1 5
Oranges 6 5 1 0 5
Banana 6 6 5 5 0
The actual $matches array looks sort of like this (truncated):
Array
(
[Apple] => Array
(
[Apple] => 0
[Apples] => 1
[Orange] => 5
[Banana] => 6
[Oranges] => 6
)
[Apples] => Array
(
...
Anyhow, it's up to you to (by experimentation) determine what a good numerical distance cutoff might mostly match - and then apply it. Otherwise, read up on sphinx-search and use it - since it does have PHP libraries.
Orange you glad you asked about this?
I would suggest taking the users submitted URLs and storing them in multiple parts; domain name, path and query string. Use the PHP parse_url() function to derive the parts of the submitted URL.
Index at least the domain name and path. Then, when a new user submits URL you search your database for a record matching the domain and path. Since the columns are indexed, you will be filtering out first all records that are not in the same domain, and then searching through the remaining records. Depending on your dataset, this should be faster that simply indexing the entire URL. Make sure your WHERE clause is setup in the right order.
If that does not meet your needs I would suggest trying Sphinx. Sphinx is an open source SQL full text search engine that is far faster that MySQL's built in full-text search. It supports stemming and some other nice features.
http://sphinxsearch.com/
You could also take the title or text content of the users submission, run it through a function to generate keywords, and search the database for existing records with those or similar keywords.
You could (depending on the size of your dataset) use mySQL's FULLTEXT search, and look for item(s) that have a high score and are within a certain timeframe, and suggest this/these to the user.
More about score here: MySQL Fulltext Search Score Explained

Categories