I having difficulties to get the next specific value from an array.
while (list($index, $day) = each($user['days'])) {
}
in $user['days] I have all of the date from a specific month in the key and in the value i have to type of values: 480 or 4 K .
for instance:
$user[1] = 480
$user[2] = 480
$user[3] = 4 K
......
$user[25] = 4 K
$user[26] = 480
.....
$user[30] = 4 K
so If I have two 4 K , the first will become 480 and next will become 8 F
if I have 4 of 4 K I will have two 480 and two 8 F
and if in the final it remains a 4 K I have to change on the next month to become 8 F and in the current month should remain 480. Can someone help me with this ?
I almost did not understand, but maybe this function help you
array_keys ( $user, '4 K');
it will return array (3,25,30). It's length gives you a count of '4 K', and values will be the keys of user array
Related
I have a a list of data that has a value attached to it that constantly gets doubled as it goes up:
0 = value 0
1 = value 1
2 = value 2
4 = value 3
8 = value 4
16 = value 5
32 = value 6
64 = value 7
128 = value 8
256 = value 9
512 = value 10
I have also been given the number x
say x = 76.
Visually, I can see that value 7 (64), value 4 (8), and value 3 (4) all sum up to 76.
What I need to be able to do, is take x, run it through a function, and return an array of the values.
I've tried looping through all the numbers in reverse and taking off what value has been used, but i got confused with lots of if statements.
Is there a built in PHP function to do this? Or am I looking at it the wrong way?
Thanks
May be you are looking for this-
function getArray($x){
$ar = array();
for($i = 0 ; $i < 16; $i++){
if( ($x&(1<<$i)) != 0 ){
array_push($ar, (1<<$i));
// if you need positions; you should use it instead of above line
//array_push($ar, ($i+1));
}
}
return $ar;
}
print_r( getArray(76) );
Output:
Array (
[0] => 4
[1] => 8
[2] => 64
)
The alternate output will be (if you use array_push($ar, ($i+1));)-
Array
(
[0] => 3
[1] => 4
[2] => 7
)
Explanation:
In binary 76 presents 00000000 01001100 in 16 bit. I ran a loop from Least Significant Bit (LSB) to Most Significant Bit (MSB) (0-16). In each loop, I'm generating a new number which contains only i'th bit as 1 and rest of the bits are 0. To generate it I used shifting operator (1 << i) which is actually 2^i. Now I did a bit wise AND operation between x and the new number. If this operation returns any nonzero number that means i'th bit of x is 1 and I'm pushing that position/value inside the array. Finally I'm returning that arry.
What I'm doing here is probably stupid and useless, but it turned out to be a great way to learn php, I appreciate your help.
I came up with a cipher which wraps text in a spiral much like Ulam's spiral maps numbers.
Refer to this image:
I consider the whole spiral as a cube, so if the string is too short to form a full cube, the remaining characters are left as empty spaces (in my picture example there is one space left, because the string is 24 characters and the next full cube is at 25 characters.
I want to add a further step of obfuscation, reading the array diagonally, so the output would be like this:
What is an easy/efficient way to achieve this? I'm storing the data in a 2D array, so it looks like this:
field[0][0]='l';
Bonus tangent question: How easily would something like this be deciphered?
Thank you!
This is the schema for a 5x5 square:
yx yx yx yx yx
0 1 2 3 4 a > 00
0 a b c d e b > 10 01
1 b c d e f c > 20 11 02
2 c d e f g d > 30 21 12 03
3 d e f g h e > 40 31 22 13 04
4 e f g h i f > 41 32 23 14
g > 42 33 24
h > 43 34
i > 44
As you can see, we have:
9 groups (= cols+rows-1 or keys+keys+1);
in each line, the y+x sum is the same, increasing from 0 to 8;
in each line, the y decreases, while the x increases.
each line ends when x reaches initial y
Based on these assumptions, we can write a single loop, using $sum and $startY as criteria to change line: when the decreasing $x has same value of $startY, we increment $sum and we set next $startY to the lowest value between $sum and the higher $array key, then we set next $x to the difference between $sum and $y:
$sum = $startY = $y = $x = 0;
while( $sum < 2*count($array)-1 )
{
echo $array[$y][$x];
if( $x == $startY )
{
$sum++;
$startY = $y = min( $sum, count($array)-1 );
$x = $sum - $y;
}
else
{
$y--;
$x++;
}
}
The result for above square is:
abbcccddddeeeeeffffggghhi
Looking at this eval.in demo you can see three different examples.
Just use for loops. It doesn't matter what language you are learning, you need to learn how to use for loops (or while loops or foreach loops or any good control structure).
You are going 00, then 10, 01, then 20, 11, 02, then 30, 21, 12, 03, etc... YOu can see that the first number decreases by 1 and the second number increases by 1. That goes until you hit n0...0n. That covers the first half of the square...
// Assume $n is the width/height of the square
for($m=0; $m<=$n; $m++)
{
for($a=$n; $a>=0; $a--)
{
for($b=0; $b<=$n; $b++)
{
//Do whatever you want with $array[$a][$n]...
}
}
}
Now, the second half of the square hits 41, 32, 23, 14 on the first stripe. It hits 42, 33, 24 on the second stripe. It hits 43, 34, and finally 44. You can see they both step up until they hit $n
for($m=1; $m<=$n; $m++)
{
for($b=$m; $b<=$n; $b++) // Put B on the outside because it is the limitation
{
for($a=4; $b<=$n; $a--)
{
//Do what you want with $a and $b
}
}
}
Now... can this be deciphered easily? Yes. You are just scrambling up the letters. No matter how you scramble it, it is deciphered easily. You need to substitute the letters with a replacement set that changes. Optimally, you want a completely new replacement set per letter you replace - which is difficult to use. So, most ciphers use a set of replacement sets, say 32 sets of replacement letters or symbols, that cycle through as randomly as possible.
I want to make the calculation of personal number by date of birth.
The calculation is done in this manner:
Ex. 8 (day) +12 (month) + 1 + 9 + 7 + 1 (year) = 38 = 3 + 8 = 11 = 1 + 1 = 2
(the final number)
This final number must not be greater than nine.
So:
The first number comes is 38 greater than 9 and it should make 3 + 8
The second number comes is 11 greater than 9 it should make 1 + 1
The third number comes is 2 less than 9 so it is the final number.
Taking all these calculations should let out the number 2.
How can I get it with php calculation?
I suppose, you can split date to array. Then
$arr = array(8,12,1,9,7,1);
// sum array, split sum to array per digit untill more than 1 digit in sum
while (count($arr = str_split(array_sum($arr))) != 1) {}
echo $arr[0]; // 2
$array = array(1, 2, 3, 4, 5, ..., N);
Also there is a number D = 10%. What is the fastest way to sort the array in such way that:
$sorted_array = {a[i]}
contains exactly the elements of $array in a mixed order, but also:
abs(a[i + 1] - a[i]) >= N * 10%
for any [i] and look randomized as much as possible.
For example,
// assume D = 25%
$array = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// so the difference between any neighbors is >= 4 = 10 * 25%.
$sorted_array = array(4, 8, 3, 7, 1, 5, 9, 2, 6, 10);
Of course if D is large, it is impossible to sort the array I want. I don't need the 100% perfect result, but I want the numbers to look "randomized" and most of them to be different at least for 10%.
I have a strange task but it has a practical area to use. I want to extract randomized lines from the image and they should be different as much as possible. Of course, the neighbor lines on the digital images (photos etc) look very similar.
Did I explain it properly?
I know it's not a good idea just to provide code, but I was intrigued by this question. Here's how I would do it:
$d = 0.3;
$random = array();
// Populate the original array
for ($n=1; $n <= 10; $n++) {
$arr[] = $n;
}
$count = count($arr);
// Loop through array
foreach (array_keys($arr) as $key) {
if (!isset($prev_key)) {
$prev_key = array_rand($arr);
}
$possibles = array(); // This stores the possible values
echo "Trying: $prev_key";
echo ":\n";
// Loop through the array again and populate $possibles with all possible
// values based on the previous values
foreach (array_keys($arr) as $n) {
if ($arr[$n] < $prev_key - $count * $d || $arr[$n] > $prev_key + $count * $d) {
$possibles[] = $n;
echo $arr[$n]." is valid\n";
}
else {
echo $arr[$n];
echo " outside range\n";
}
}
// If there is nothing outside that range, just return the remaining values
if (count($possibles) == 0) {
$possibles = array_keys($arr);
echo "Nothing within range so just returning whole array\n";
}
echo "\n";
// Choose random value from the possible values array
$rand_key = $possibles[array_rand($possibles)];
$random[] = $arr[$rand_key];
$prev_key = $arr[$rand_key];
// Unset this value from the original array since we can only use the
// values once
unset($arr[$rand_key]);
}
print_r($random);
This will produce output like this:
Trying: 8:
1 is valid
2 is valid
3 is valid
4 is valid
5 outside range
6 outside range
7 outside range
8 outside range
9 outside range
10 outside range
Trying: 2:
1 outside range
3 outside range
4 outside range
5 outside range
6 is valid
7 is valid
8 is valid
9 is valid
10 is valid
Trying: 9:
1 is valid
3 is valid
4 is valid
5 is valid
6 outside range
7 outside range
8 outside range
10 outside range
Trying: 5:
1 is valid
3 outside range
4 outside range
6 outside range
7 outside range
8 outside range
10 is valid
Trying: 10:
1 is valid
3 is valid
4 is valid
6 is valid
7 outside range
8 outside range
Trying: 4:
1 outside range
3 outside range
6 outside range
7 outside range
8 is valid
Trying: 8:
1 is valid
3 is valid
6 outside range
7 outside range
Trying: 3:
1 outside range
6 outside range
7 is valid
Trying: 7:
1 is valid
6 outside range
Trying: 1:
6 is valid
Array
(
[0] => 2
[1] => 9
[2] => 5
[3] => 10
[4] => 4
[5] => 8
[6] => 3
[7] => 7
[8] => 1
[9] => 6
)
The only drawback is that since it randomly gets rows, there is a chance that the values near the end may not be outside the defined range. By my tests, this happens to about 4% using the above $d = 0.25 and 1000 values. One way to get around this is just to insert these values back in at random places instead of appending them like I have done.
Also note, this method is not that efficient. It has to loop through the array count($arr) ^ 2 times. So for 1000 values, you're looking at 1,000,000 iterations. Fortunately the array gets progressively smaller.
I am doing this programming challenge which can be found at www.interviewstreet.com (its the first challenge worth 30 points).
When I submitted the solution, I was returned a result which said that the answer was wrong because it only passed 1/11 test cases. However, I feel have tested various cases and do not understand what I am doing wrong. It would be helpful to know what those test cases could be so that I can test my program.
Here is the question (in between the grey lines below):
Quadrant Queries (30 points)
There are N points in the plane. The ith point has coordinates (xi, yi). Perform the following queries:
1) Reflect all points between point i and j both including along the X axis. This query is represented as "X i j"
2) Reflect all points between point i and j both including along the Y axis. This query is represented as "Y i j"
3) Count how many points between point i and j both including lie in each of the 4 quadrants. This query is represented as "C i j"
Input:
The first line contains N, the number of points. N lines follow.
The ith line contains xi and yi separated by a space.
The next line contains Q the number of queries. The next Q lines contain one query each, of one of the above forms.
All indices are 1 indexed.
Output:
Output one line for each query of the type "C i j". The corresponding line contains 4 integers; the number of points having indices in the range [i..j] in the 1st,2nd,3rd and 4th quadrants respectively.
Constraints:
1 <= N <= 100000
1 <= Q <= 100000
You may assume that no point lies on the X or the Y axis.
All (xi,yi) will fit in a 32-bit signed integer
In all queries, 1 <=i <=j <=N
Sample Input:
4
1 1
-1 1
-1 -1
1 -1
5
C 1 4
X 2 4
C 3 4
Y 1 2
C 1 3
Sample Output:
1 1 1 1
1 1 0 0
0 2 0 1
Explanation:
When a query says "X i j", it means that take all the points between indices i and j both including and reflect those points along the X axis. The i and j here have nothing to do with the co-ordinates of the points. They are the indices. i refers to point i and j refers to point j
'C 1 4' asks you to 'Consider the set of points having index in {1,2,3,4}. Amongst those points, how many of them lie in the 1st,2nd,3rd and 4th quads respectively?'
The answer to this is clearly 1 1 1 1.
Next we reflect the points between indices '2 4' along the X axis. So the new coordinates are :
1 1
-1 -1
-1 1
1 1
Now 'C 3 4' is 'Consider the set of points having index in {3,4}. Amongst those points, how many of them lie in the 1st,2nd,3rd and 4th quads respectively?' Point 3 lies in quadrant 2 and point 4 lies in quadrant 1.
So the answer is 1 1 0 0
I'm coding in PHP and the method for testing is with STDIN and STDOUT.
Any ideas on difficult test cases to test my code with? I don't understand why I am failing 10 / 11 test cases.
Also, here is my code if you're interested:
// The global variable that will be changed
$points = array();
/******** Functions ********/
// This function returns the number of points in each quadrant.
function C($beg, $end) {
// $quad_count is a local array and not global as this gets reset for every C operation
$quad_count = array("I" => 0, "II" => 0, "III" => 0, "IV" => 0);
for($i=$beg; $i<$end+1; $i++) {
$quad = checkquad($i);
$quad_count[$quad]++;
}
return $quad_count["I"]." ".$quad_count["II"]." ".$quad_count["III"]." ".$quad_count["IV"];
}
// Reflecting over the x-axis means taking the negative value of y for all given points
function X($beg, $end) {
global $points;
for($i=$beg; $i<$end+1; $i++) {
$points[$i]["y"] = -1*($points[$i]["y"]);
}
}
// Reflecting over the y-axis means taking the negative value of x for all given points
function Y($beg, $end) {
global $points;
for($i=$beg; $i<$end+1; $i++) {
$points[$i]["x"] = -1*($points[$i]["x"]);
}
}
// Determines which quadrant a given point is in
function checkquad($i) {
global $points;
$x = $points[$i]["x"];
$y = $points[$i]["y"];
if ($x > 0) {
if ($y > 0) {
return "I";
} else {
return "IV";
}
} else {
if ($y > 0) {
return "II";
} else {
return "III";
}
}
}
// First, retrieve the number of points that will be provided. Make sure to check constraints.
$no_points = intval(fgets(STDIN));
if ($no_points > 100000) {
fwrite(STDOUT, "The number of points cannot be greater than 100,000!\n");
exit;
}
// Remember the points are 1 indexed so begin key from 1. Store all provided points in array format.
for($i=1; $i<$no_points+1; $i++) {
global $points;
list($x, $y) = explode(" ",fgets(STDIN)); // Get the string returned from the command line and convert to an array
$points[$i]["x"] = intval($x);
$points[$i]["y"] = intval($y);
}
// Retrieve the number of operations that will be provied. Make sure to check constraints.
$no_operations = intval(fgets(STDIN));
if($no_operations > 100000) {
fwrite(STDOUT, "The number of operations cannot be greater than 100,000!\n");
exit;
}
// Retrieve the operations, determine the type and send to the appropriate functions. Make sure i <= j.
for($i=0; $i<$no_operations; $i++) {
$operation = explode(" ",fgets(STDIN));
$type = $operation[0];
if($operation[1] > $operation[2]) {
fwrite(STDOUT, "Point j must be further in the sequence than point i!\n");
exit;
}
switch ($type) {
case "C":
$output[$i] = C($operation[1], $operation[2]);
break;
case "X":
X($operation[1], $operation[2]);
break;
case "Y":
Y($operation[1], $operation[2]);
break;
default:
$output[$i] = "Sorry, but we do not recognize this operation. Please try again!";
}
}
// Print the output as a string
foreach($output as $line) {
fwrite(STDOUT, $line."\n");
}
UPDATE:
I finally found a test case for which my program fails. Now I am trying to determine why. This is a good lesson on testing with large numbers.
10
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
12
C 1 10
X 1 3
C 5 5
Y 2 10
C 10 10
C 1 10
X 1 3
C 5 5
Y 2 10
C 10 10
X 3 7
C 9 9
I am going to test this properly by initializing an error array and determining which operations are causing an issue.
I discovered a test case that failed and understood why. I am posting this answer here so it's clear to everyone.
I placed a constraint on the program so that j must be greater than i, otherwise an error should be returned. I noticed an error with the following test case:
10
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1
C 2 10
The error returned for the operation C. Essentially the program believed that "2" was greater than "10". The reason for this I discovered was the following:
When using fgets(), a string is returned. If you perform string operations such as explode() or substr() on that line, you are converting the numbers in that initial string into a string again. So this means that the 10 becomes "10" and then after string operations becomes "0".
One solution to this is to use the sscanf() function and basically tell the program to expect a number. Example: for "C 2 10" you could use:
$operation_string = fgets(STDIN);
list($type, $begpoint, $endpoint) = sscanf($operation_string, "%s %d %d");
I submitted the new solution using sscanf() and now have 3/11 test cases passed. It did not check any more test cases because the CPU time limit was exceeded. So, now I have to go back and optimize my algorithm.
Back to work! :)
To answer, "What are those test cases?" Try this "solution":
<?php
$postdata = http_build_query(
array(
'log' => file_get_contents('php://stdin')
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($opts);
file_get_contents('http://myserver/answer.php', false, $context);
?>
On your server:
<?php
$fp = fopen('/tmp/answers.log', 'a');
fputs($fp, $_POST['log']."\n");
fclose($fp);
?>
Edit:
I did that. And came up with this being your main problem (I think):
$operation = explode(" ",fgets(STDIN));
Change that to:
$operation = explode(" ",trim(fgets(STDIN)));
Because otherwise "9" > "41 " due to string comparison. You should make that fix in any place you read a line.
As far as I guess, this solution won't work. Even if you solve the Wrong Answer problem, the solution will time out.
I was able to figure out a way for returning the quadrants count in O(1) time.
But not able to make the reflections in lesser time. :(