echo "1" . (print '2') + 3; returns 214. How does the script end up with *14?
When you do
echo "1" . (print '2') + 3;
PHP will do (demo)
line # * op fetch ext return operands
---------------------------------------------------------------------------------
2 0 > PRINT ~0 '2'
1 CONCAT ~1 '1', ~0
2 ADD ~2 ~1, 3
3 ECHO ~2
4 > RETURN 1
In words:
print 2, return 1
concat "1" with returned 1 => "11"
add "11" + 3 => 14
echo 14
and that's 214.
The operators + - . have equal Operator Precedence, but are left associative:
For operators of equal precedence, left associativity means that evaluation proceeds from left to right, and right associativity means the opposite.
Edit: since all the other answers claim PHP does 1+3, here is further proof that it doesnt:
echo "1" . (print '2') + 9;
gives 220, e.g. 11+9 and not 1 . (1+9). If the addition had precedence over the concatenation, it would have been 2110, but for that you'd had to write
echo "1" . ((print '2') + 9);
echo "1" . (print '2') + 3;
You need to think of it in a logical order, of what happens first.
Before we can echo anything, the - "1" . (print '2') + 3 - we need to evaluate it to solve it.
First we write 1 down on a scrap of paper as the first part of our calculation.
Scrap paper: 1
Answer Sheet:
We calculate "print '2'", which as a function writes the number 2 to our sheet of answer paper and returns a 1, which we write on our scrap piece of paper.
Scrap paper: 1 . 1 +3
Answer Sheet: 2
After this we want to concatenate the next piece on to the end, due to the "."
Scrap paper: 11 + 3
Answer Sheet: 2
Now we put it together
Scrap paper: 11 + 3
Scrap paper: 14
Answer Sheet: 2
Then we echo out our scrap data to our answer sheet
Answer Sheet: 214
echo "1" . (print '2') + 3;
1.
Code--: echo "1" . (print '2') + 3;
Result:
2.
Code--: echo "1" . 1 + 3;
Result: 2
3.
Code--: echo 11 + 3;
Result: 2
4.
Code--: echo 14;
Result: 2
5.
Code--:
Result: 214
I hope that makes some sense, and remember the return of print is always 1, and any function that prints or echo's while inside another execution will echo/print before it's caller/parent does.
The 1 in between is actually a true statement.
Because print statement actually returns a true.
So you get 2 (from print), 1 (from echo print), and 4 (from 1+3)
print is executed first because of the parenthesis, so it print's 2 first, but it returns 1. Then, your echo gets executed, printing 1. You then concatenate to it the result of print (which is 1) with 3 added to it. That's 4.
print always return 1 according to: http://php.net/manual/en/function.print.php
So, because arithmetic operator has precedence over one for concatenation, so you get:
"1" . (1+3)
... that is "14" ;). And because print sends string directly to output you get '2' in front of everything....
Related
I want to get my output like this
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
I am trying like this:
<?php
for($a=1; $a<=16; $a++)
{
for($b=$a; $b>=1; $b--)
{
echo "$b";
}
echo "<br>";
}
?>
The above code gives me the wrong output.
Let's debug.
You are starting from 1 in your outer loop and in your inner loop, you are going from $a till 1 times.
This doesn't comply with your requirements because we have to print an increasing sequence in each row.
You can also notice that every number in a row differs by 4.
So, logic would be like below:
Pseudocode:
rows = 4
starting_number = 1
loop from 1 to rows
number = starting_number
loop from 1 to 4 // since each row has 4 numbers
print number
number += 4
print new_line
starting_number++
Demo: https://3v4l.org/9YjIP
I'm learning basics in php, and I was trying to add multiple arguments in echo command. But the variable after <br> is not showing.
$number1=10;
echo "number 1 is: ".$number1."<br>";
$number2=20;
echo "number 2 is: ".$number2;
echo "<br> ".$number1+$number2;
and the output should be:
number 1 is: 10
number 2 is: 20
30
But the output is:
number 1 is: 10
number 2 is: 2020
So what's the error?
used this code
$number1=10;
echo "number 1 is: ".$number1."<br>";
$number2=20;
echo "number 2 is: ".$number2;
$total= $number1+$number2;
echo "<br> ".$total;
?>
The output will be:
number 1 is: 10
number 2 is: 20
30
The other answers just state a solution, this answer explains whats happening and how to prevent the unexpected behavior in 2 ways.
The dot operator has the same precedence as + and -.
Considering
$number1 = 10;
$number2 = 20;
echo "<br> ".$number1+$number2;
The dot you've used is a string operator, not a numeric operator.
What's happening:
"<br>" and 10 are concatenated with the dot operator to "<br>10".
"<br>10" is added to $number2 (20) with the numeric + operator.
Non-empty, non-numeric strings are converted to 0. Meaning "<br>10" = 0.
0+20 results in 20 which makes line 3: echo 20;
This can be solved by changing the precedences by using brackets echo "<br> ". ($number1 + $number2); or the less seen option, by passing more arguments to the echo language construct: echo "<br> ", $number1 + $number2; (Note the comma instead of a dot). Each argument will be evaluated first before outputting them all together.
Personally I use the second option (multiple arguments) in cases like this.
Just add the braces to the sum operation.
$number1=10;
echo "number 1 is: ".$number1."<br>";
$number2=20;
echo "number 2 is: ".$number2;
echo "<br> ".($number1+$number2);
The output will be:
number 1 is: 10
number 2 is: 20
30
You should revise code within bracket
echo "<br> ". ($number1 + $number2);
to get the result you want.
Reason: each operation has precendence level
Get reference: http://interactivepython.org/runestone/static/pythonds/BasicDS/InfixPrefixandPostfixExpressions.html
the output of the following code?
echo '1' . (print '2') + 3;
I tested and the result is 214, but why 214?
if I code:
echo (print '2') + 3;
the result is 24
Then, echo '1' . '24'; should be 124.
Confused...
When the expression is parsed, the "print" statement is immediately writing its output. So there's the first 2. By definition its return value is 1.
So then the remaining expression is the character 1, followed by the numeric expression 1+3. Therefore 1 and 4.
214
I have this php code with me and i am not able to figure it out could anyone help on this.
$x = 3 - 5 % 3;
echo $x;
gives 1 in out put.
Thanks
5 % 3 = 2.
3 - 2 = 1.
There's a specific operator precedence, that causes modulo to be evaluated before minus.
It' s simple math!
% / * operators are first calculated and then
+ -
5 % 3 = 2
3 - 2 = 1
If you want to "prevent" this simply add some brackets:
$x = (3 - 5) % 3;
Of course the answer is correct. PHP parses the code like this 3 - (5 % 3)
5 % 3 is 2 and 3 - 2 gives you 1
5 % 3 is the remainder of 5 /3
It's the order of operations. Without parenthesis around the subtraction, the modulo is being evaluated first. Try this:
$x = (3 - 5) % 3;
echo $x;
% has higher presedence then -. Check out operator precedence
BODMAS - Brackets Order[^] Division Multiplication Addition Substracion .
For,
3 - 5 % 3
first,
5 % 3 gives remainder as 1
second,
3 - 1,
this gives 2.
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. :(