I have a problem with aligning numbers from a multidimensional array. I want to print the following result:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
And I want all of the numbers to be aligned with the second digit of the next rows. However my result is that:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
I did this in C# by using:
for (int col = 0; col < matrix.GetLength(1); col++)
{
Console.Write("{0,4}", matrix[row, col]);
}
But how can I receive this result in PHP?
You can use str_pad
$arr = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
$test = '';
foreach ($arr as $key => $value) {
if ($key % 4 == 0) {
$test .= "\n";
}
$test .= str_pad($value, 4, ' ', STR_PAD_LEFT);
}
echo "<pre>$test</pre>";
The result would be:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
I have a problem with gradually calculating a value in PHP.
This is just an example. A user can level up, and when he reaches level 5 he unlocks the ability to play missions. The difficulty of a new generated mission is defined by a number: from 1 that is an easy mission to 10 that is a very difficult mission. See this table:
o 5: 1, 1, 2, 2, 3, 3, 3, 3, 3, 3 and so on
o 6: 1, 2, 2, 2, 3, 3, 3, 3, 3, 3
o 7: 2, 2, 2, 3, 3, 3, 3, 3, 3, 3
o 8: 2, 2, 3, 3, 4, 4, 4, 4, 4, 4
o 9: 2, 3, 3, 4, 4, 4, 4, 4, 4, 4
o 10: 3, 3, 4, 4, 5, 5, 5, 5, 5, 5
o 11: 3, 4, 4, 5, 6, 6, 6, 6, 6, 6
o 12: 4, 4, 5, 6, 7, 7, 7, 7, 7, 7
o 13: 4, 5, 6, 7, 8, 8, 8, 8, 8, 8
o 14: 5, 6, 7, 8, 9, 9, 9, 9, 9, 9
o 15: 6, 7, 8, 9, 10, 10, 10, 10, 10, 10
o 16: 7, 8, 9, 10, 10, 10, 10, 10, 10, 10
o 17: 8, 9, 10, 10, 10, 10, 10, 10, 10, 10
o 18: 9, 10, 10, 10, 10, 10, 10, 10, 10, 10
o 19: 10, 10, 10, 10, 10, 10, 10, 10, 10, 10
o 20: same as 19
This means: in level 5 the first mission is very easy (difficulty 1), the second one too, and the third mission is difficulty 2. And when the player is level 18: the first mission has a difficulty of 9 and the second and following missions have a difficulty of 10.
But: how to generate the difficulty of the missions?
I have two variables:
<?php
$current_player_level
$current_mission_in_level
?>
So:
<?php
$current_player_level=8;
$current_mission_in_level=3;
//This should return: 3
?>
So I need a function that returns the difficulty when the two variables above are provided.
I don't have any code because I don't know how to begin.
I'd suggest storing the difficulties in a 2-dimensional array (also called a "matrix" sometimes). The code would look like so:
$matrix_val = array(5 => array(1, 1, 2, 2, 3),
6 => array(1, 2, 2, 2, 3),
7 => array(2, 2, 2, 3, 3),
8 => array(2, 2, 3, 3, 4),
9 => array(2, 3, 3, 4, 4),
10 => array(3, 3, 4, 4, 5),
11 => array(3, 4, 4, 5, 6),
12 => array(4, 4, 5, 6, 7),
13 => array(4, 5, 6, 7, 8),
14 => array(5, 6, 7, 8, 9),
15 => array(6, 7, 8, 9, 10),
16 => array(7, 8, 9, 10, 10),
17 => array(8, 9, 10, 10, 10),
18 => array(9, 10, 10, 10, 10),
19 => array(10, 10, 10, 10, 10));
Then all you have to do is:
$difficulty = $matrix_val[$current_player_level][$current_mission_in_level];
NOTE: The "current mission in level" assumes 0 is the first index. So the third mission in level 13 would be referenced as $matrix_val[13][2] (notice [2]). If you want to shift this you can either add individual keys to each level, or simply "pad" a meaningless entry at the start of each inner array. (If this is confusing, let me know and I'll expand.)
For reference, check out the official Array PHP documentation, then you might want to read up on 2-dimensional arrays, too.
You should use arrays.
You can use 2D array (like a table) to store your levels and difficulties, and then get the right value according to the position you want.
For example:
$table = array(
5 => array(1, 1, 2, 2, 3),
6 => array(1, 2, 2, 3, 3),
7 => array(2, 2, 3, 3, 4)
);
I'm not showing the all array here.
So if you want to know for example the difficuly, you can use:
$current_difficulty = $table[$current_player_level][$current_mission_in_level];
The is no much math here, just knowing arrays.
// Filling 2D array with linear gradient from left top to right bottom
// There are some math for this. But i'm not sure it is needed
$MIN = 5.0; // min difficalty
$MAX = 9.0; // max difficalty
$M = 15.0; // Level legnth - 1
$N = 7.0; // Levels count -1
$res = array();
for($y = 0; $y <= $N; $y++)
for($x = 0; $x <= $M; $x++)
{
$y1 = ($N*$y-$M*$x+$M*$M)*$N/($M*$M+$N*$N);
$res[$N-$y][$x] = round($MAX - $y1/$N*($MAX-$MIN));
}
for($i=0; $i <= $N; $i++) {
$line = $res[$i];
echo implode(' ', $line)."\n";
}
Output:
5 5 5 6 6 6 6 7 7 7 7 7 8 8 8 8
5 5 6 6 6 6 6 7 7 7 7 8 8 8 8 8
5 5 6 6 6 6 7 7 7 7 7 8 8 8 8 8
5 6 6 6 6 6 7 7 7 7 7 8 8 8 8 9
5 6 6 6 6 7 7 7 7 7 8 8 8 8 8 9
6 6 6 6 6 7 7 7 7 7 8 8 8 8 9 9
6 6 6 6 6 7 7 7 7 8 8 8 8 8 9 9
6 6 6 6 7 7 7 7 7 8 8 8 8 9 9 9
I have searched a number of different items but I have not found any answers. Chances are I just don't know how to word this correctly.
Anyway, I have set up a system in PHP/SQL to allow instantaneous scanning of thousands of results. Each data entry has 4 numbers, and it can easily scan for entries that match all 4 of these numbers. What I am trying to achieve is to have the script search the database for entries that match exactly 3 out of the 4 entries with the other being incorrect, kind of like a lottery.
For example, we have the entries:
Steve - 1, 4, 10, 13
Bill - 3, 4, 10, 13
Tom - 1, 17, 20, 39
Jill - 1, 4, 13, 21
Jane - 5, 10, 13, 18
Now, I would scan based on the results 1, 4, 10, 13, and would like to return the following results, as these matched 3 of the 4 entries:
Bill - 3, 4, 10, 13
Jill - 1, 4, 13, 21
How would I achieve this?
Many thanks
EDIT: Sorry yes the table has the structure
Name - Number1 - Number2 - Number3 - Number4
So yes, stored as separate fields
You can do this by counting the matches and setting this equal to 3:
select t.*
from t
where (val1 in (1, 4, 10, 13) +
val2 in (1, 4, 10, 13) +
val3 in (1, 4, 10, 13) +
val4 in (1, 4, 10, 13)
) = 3;
In MySQL a TRUE boolean expression evaluates to 1. You can add these together to get the number of matches.
I have the following type of array :
$foo = array(
"a" => 1,
"b" => 1,
"c" => 2,
"d" => 2,
"e" => 3,
"f" => 3,
"g" => 4,
"h" => 4,
"i" => 5,
"j" => 5,
"k" => 10,
"l" => 12,
"m" => 15,
"n" => 20
);
I need to sort the array in this way :
$foo = array(1,2,3,4,5,12,20,15,10,5,4,3,2,1);
As you can see, the best value needs to be in the middle of the array. And the min-values in the start/end of array. The key needs to be linked to the original value.
Thank's for the help! sorry for my English.
If the input is already sorted, you can use two loops to first push every item with an odd offset in ascending order and then every item with an even offset in descending order into your array:
$keys = array_keys($foo);
$n = count($keys);
$result = array();
for ($i=0; $i<$n; $i+=2) {
$result[$keys[$i]] = $foo[$keys[$i]];
}
for ($i=$n-$n%2-1; $i>0; $i-=2) {
$result[$keys[$i]] = $foo[$keys[$i]];
}
First arrange all the integers in ascending order.
Lets say $foo_as is the new array you got in ascending order.
$a=a new empty array of size $n
$n=number of integers.
$c=0;
for ($i=$n-1;$i>0;$i--){
if (i%2==0){
$a(i/2)+c=$foo_as($n-$c)
}
else{
$a(i+1/2)-c=$foo_as($n-$c)
}
$c++
}
Explanation: I'm putting the largest integer in the middle. After that I'm filling the alternate indexes around the middle one with the integers in descending order.
- - - - - 11 - - - - -
- - - - 10 11 - - - - -
- - - - 10 11 9 - - - -
- - - 8 10 11 9 - - - -
- - - 8 10 11 9 7 - - -
- - 6 8 10 11 9 7 - - -
- - 6 8 10 11 9 7 5 - -
- 4 6 8 10 11 9 7 5 - -
- 4 6 8 10 11 9 7 5 3 -
2 4 6 8 10 11 9 7 5 3 -
2 4 6 8 10 11 9 7 5 3 1
I have used a basic algorithm to demonstrate this. If at some point, my php syntax is incorrect, please omit that.
A overkill version:
<?php
$foo = array(
"a" => 1,
"b" => 1,
"c" => 2,
"d" => 2,
"e" => 3,
"f" => 3,
"g" => 4,
"h" => 4,
"i" => 5,
"j" => 5,
"k" => 10,
"l" => 12,
"m" => 15,
"n" => 20
);
$arrayKeys = array_keys($foo);
$arrayValues = array_values($foo);
$array_count = count($foo);
for ($idx =0; $idx < round($array_count/2); $idx+=2) {
$tmpA = $arrayKeys[$idx];
$arrayKeys[$idx] = $arrayKeys[$array_count - $idx -1];
$arrayKeys[$array_count - $idx -1] = $tmpA;
$tmpB = $arrayValues[$idx];
$arrayValues[$idx] = $arrayValues[$array_count - $idx -1];
$arrayValues[$array_count - $idx -1] = $tmpB;
}
$tmpArray = array_combine($arrayKeys, $arrayValues);
$ascent = array_slice($tmpArray, 0, round($array_count/2));
$descent = array_slice($tmpArray, round($array_count/2));
asort($ascent);
arsort($descent);
$foobar = array_merge($ascent, $descent);
var_dump($foo, $foobar);
?>
The code in question comes from MathGuard, a PHP anti-spam CAPTCHA script that requires the user to answer a simple math problem. It displays the digits and operator symbols as 3x5 matrices of random characters. I understand how the code works in the sense that I can follow the code and understand what it's doing; I just don't understand how one would come to this solution.
This function takes an integer that describes one line of the 3x5 matrix and converts it into a line of random characters:
function decToBin($dec) {
$pattern = "123456789ABCDEFGHIJKLMNOPQRTSTUWXYZ";
$output = " ";
$i = 0;
do {
if ($dec % 2) {
$rand = rand() % 34;
$output { 2 - $i } = $pattern { $rand };
} else {
$output { 2 - $i } = " ";
}
$dec = (int) ($dec / 2);
$i++;
} while ($dec > 0);
$output = str_replace(" ", " ", $output);
return $output;
}
Here are the digit descriptors:
$number = array (
array ( 7, 5, 5, 5, 7 ), // 0
array ( 2, 6, 2, 2, 7 ), // 1
array ( 7, 1, 7, 4, 7 ), // 2
array ( 7, 1, 7, 1, 7 ), // 3
array ( 4, 5, 7, 1, 1 ), // 4
array ( 7, 4, 7, 1, 7 ), // 5
array ( 7, 4, 7, 5, 7 ), // 6
array ( 7, 1, 1, 1, 1 ), // 7
array ( 7, 5, 7, 5, 7 ), // 8
array ( 7, 5, 7, 1, 7 ) // 9
);
My question is: how does one come to this conclusion and method of generation and know that, for example, 7 will generate a full line of random characters, and 5 only the outermost characters?
Is this just a form of code obfuscation? What makes this method better than, say, storing the digits as a string (111101101101111 as 0, for example) and replacing each 1 with a random character?
Looks like a simple bitmap to me.
7 = 1 1 1
5 = 1 0 1
5 = 1 0 1
5 = 1 0 1
7 = 1 1 1
2 = 0 1 0
6 = 1 1 0
2 = 0 1 0
2 = 0 1 0
7 = 1 1 1