while ( (i=t-i%10 ? i/10 : !printf("%d\n",j)) || (i=++j<0?-j:j)<101 );
I came across this on codegolf
Please explain the usage of ? and : and why is there no statement following the while loop? As in why is there a ; after the parenthesis.
There is a boolean operation going on inside the parentheses of the while loop:
while (boolean);
Since the ternary operator is a boolean operator, it's perfectly legal.
So what's this doing? Looks like modular arithmetic, printing going on over a range up to 101.
I'll agree that it's cryptic and obscure. It looks more like a code obfuscation runner up. But it appears to be compilable and runnable. Did you try it? What did it do?
The ?: is a ternary operator.
An expression of form <A> ? <B> : <C> evaluates to:
If <A> is true, then it evaluates to <B>
If <A> is false, then it evaluates to <C>
The ; after the while loop indicates an empty instruction. It is equivalent to writing
while (<condition>) {}
The code you posted seems like being obfuscated.
Please explain the usage of ? and :
That's the conditional operator. a ? b : c evaluates a and converts it to a boolean value. Then it evaluates b if its true, or c if its false, and the overall value of the expression is the result of evaluating b or c.
So the first sub-expression:
assigns t-i%10 to i. The result of that expression is the new value of i.
if i is not zero, the result of the expression is i/10
otherwise, print j, and the result of the expression is zero (since printf returns a non-zero count of characters printed, which ! converts to zero).
Then the second sub-expression, after ||, is only evaluated if the result of the first expression was zero. I'll leave you to figure out what that does.
why is there no statement following the while loop?
There's an empty statement, ;, so the loop body does nothing. All the action happens in the side effects of the conditional expression. This is a common technique when the purpose of the code is to baffle the reader; but please don't do this sort of thing when writing code that anyone you care about might need to maintain.
This is the Conditional Operator (also called ternary operator).
It is a one-line syntax to do the same as if (?) condition doA else (:) doB;
In your example:
(i=t-i%10 ? i/10 : !printf("%d\n",j)
Is equivalent to
if (i=t-i%10)
i/10;
else
!printf("%d\n",j);
?: is the short hand notation for if then else
(i=t-i%10 ? i/10 : !printf("%d\n",j)<br>
equals to
if( i= t-i%10 )
then { i/10 }
else { !printf("%d\n",j) }
Your while loop will run when the statement before the || is true OR the statement after the || is true.
notice that your code does not make any sense.
while ( (i=t-i%10 ? i/10 : !printf("%d\n",j)) || (i=++j<0?-j:j)<101 );
in the most human-readable i can do it for u, it's equivalent to:
while (i < 101)
{
i = (t - i) % 10;
if (i > 0)
{
i = i / 10;
}
else
{
printf("%d\n",j);
}
i = ++j;
if (i < 0)
{
i = i - j;
}
else
{
i = j;
}
}
Greetings.
I am the proud perpetrator of that code. Here goes the full version:
main()
{
int t=getchar()-48,i=100,j=-i;
while ((i=t-i%10?i/10:!printf("%d\n",j)) || (i=++j<0?-j:j)<101 );
}
It is my submission to a programming challenge or "code golf" where you are asked to create the tinniest program that would accept a digit as a parameter and print all the numbers in the range -100 to 100 that include the given digit. Using strings or regular expressions is forbidden.
Here's the link to the challenge.
The point is that it is doing all the work into a single statement that evaluates to a boolean. In fact, this is the result of merging two different while loops into a single one. It is equivalent to the following code:
main()
{
int i,t=getchar()-'0',j=-100;
do
{
i = j<0? -j : j;
do
{
if (t == i%10)
{
printf("%d\n",j);
break;
}
}
while(i/=10);
}
while (j++<100);
}
Now lets dissect that loop a little.
First, the initialisation.
int t=getchar()-48,i=100,j=-i;
A character will be read from the standard input. You are supposed to type a number between 0 and 9. 48 is the value for the zero character ('0'), so t will end up holding an integer between 0 and 9.
i and j will be 100 and -100. j will be run from -100 to 100 (inclusive) and i will always hold the absolute value of j.
Now the loop:
while ((i=t-i%10?i/10:!printf("%d\n",j)) || (i=++j<0?-j:j)<101 );
Let's read it as
while ( A || B ) /* do nothing */ ;
with A equals to (i=t-i%10?i/10:!printf("%d\n",j)) and B equals to (i=++j<0?-j:j)<101
The point is that A is evaluated as a boolean. If true, B won't be evaluated at all and the loop will execute again. If false, B will be evaluated and in turn, if B is true we'll repeat again and once B is false, the loop will be exited.
So A is the inner loop and B the outer loop. Let's dissect them
(i=t-i%10?i/10:!printf("%d\n",j))
It's a ternary operator in the form i = CONDITION? X : Y; It means that first CONDITION will be evaluated. If true, i will be set to the value of X; otherwise i will be set to Y.
Here CONDITION (t-i%10) can be read as t - (i%10). This will evaluate to true if i modulo 10 is different than t, and false if i%10 and t are the same value.
If different, it's equivalent to i = i / 10;
If same, the operation will be i = !printf("%d\n",j)
If you think about it hard enough, you'll see that it's just a loop that checks if any of the decimal digits in the integer in i is equal to t.
The loop will keep going until exhausting all digits of i (i/10 will be zero) or the printf statement is run. Printf returns the number of digits printed, which should always be more than zero, so !printf(...) shall always evaluate to false, also terminating the loop.
Now for the B part (outer loop), it will just increment j until it reaches 101, and set i to the absolute value of j in the way.
Hope I made any sense.
Yes, I found this thread by searching for my code in google because I couldn't find the challenge post.
Related
I am attempting to solve a hw problem in which I need to write down what the program will output. I am stuck however, on the syntax "if ( !(i%3)). What does that really mean? Does it mean that the program is checking for any i that is divisible by three? aka, is the if statement only runs if i is divisible by three?
int main () {
for (int i=0; i<10; (i<3?i++;i+=2)) {
if (!(i%3)) {
continue;
}
else if (i%7 ==0) {
break;
}
cout << i<< endl;
}
Does it mean that the program is checking for any i that is divisible by three? aka, is the if statement only runs if i is divisible by three?
Correct. The longer version of that check would be
if (i % 3 == 0)
continue;
The most common use case for such branching is probably FizzBuzz.
İt means if i is not(!) divisible by 3 continue.
For example if i is 3,6,9 it won't continue otherwise it will continue.
if (x) where x is int implicitly compared with zero. I.e. if (x) equals to if (x != 0). ! is negation. So if (!x) equals to if (x == 0). And the last step is if (!(i%3)) equals to if ((i%3) == 0) what is the same with check, that i deivisible by 3
The if() statement is false only if the result inside the parentheses is 0 (false). Take a look at your program:
i%3 may return 0 (false), 1 (true), or 2 (true)
The negation operator ! changes the result of the operation (i%3). So, if the i is divisible with 3 the statement will return 0 (false). Being negate, ! it will result in True. Otherwise the result of (i%3) will be true and with the operator ! the result of the hole statement will be false. Basically this code is checking if the value of i is divisible with 3.
Other options will be:
if (0==i%3)
{
/*code*/
}
Your code can be simplified as below
int main() {
for (int i=0; i<10;)
{
if (i % 3 == 0) {
continue;
}
else if (i % 7 == 0) {
break;
}
cout << i << endl;
i = i<3 ? i+1 : i+2;
}
}
When you write a integer variable like i as a condition, what happens is that if i==0 then the result of the condition is false, otherwise it would be true.
Let's check it out in your program, if(!(x%3)), let's name condition= !(x%3), when this condition is true? when x%3 == 0, note that the negation operator ! is behind x%3, so in this case the condition would be equal to true, more formally the condition is equal to :
if(x%3==0)
these kinds of conditions are common, check this example out :
int t = 10;
while(t--){
cout<<t<<endl;
}
The above condition i.e if(!(i%3)) will true when " i is not disvisable by 3"
Hope this helps.
In java and other languages there is a special type to represent booleans and evaluate expressions; in c and its variants there is no such thing, instead an expression is considered "true" if -taken as a integer number- is equal to 0; false for every other value. (Fun fact: this is why you usually end the code by return 0)
So if(x%3) in c is equivalent to if(x%3==0) in other languages. That said, if(x%3) execute the if body when the remainder of x/3 is 0, that is when x is a multiple of 3.
In your code you have the ! before, that -as you may know- "inverts" the expression. That means that if(!(x%3)) can be read as "If the remainder of the integer division of x by 3 is not 0", or alternatively: "If x is not a multiple of 3".
So, basically, you saw it right.
Hope I helped!
Here is a part of code
int main()
{
int x=5,y=10;
if(x=!y)
{
cout<<"h";
}
else
{
cout<<"p";
}
getch();
}
The output was p, please explain, how the code works and the meaning of x=!y.
Looks like a typo that produces valid code. Expanding it helps--
if (x = (!y))
Since y is 10, !y == 0, and assignments themselves produce a value. In particular the value of x = 0 is 0, so the test evaluates to 0 and that's why you get the result.
But this is a crazy thing to write in this context, presumably what was, or what should have been intended was
if (x != y)
I.e., not-equals.
x=!y is an assignment.
x is being assigned the value of !y expression, which is a logical "NOT" operation. This operation returns true if the operand is zero, or false otherwise. The value true becomes 1 when assigned back to int; false becomes zero.
In C and C++ it is OK to use assignment expressions inside if conditionals and other control statements, such as for and while loops. The value being assigned is used to evaluate the condition, and the assignment itself is performed as a side effect. In this case, the condition is !y.
This question already has an answer here:
The Definitive C++ Book Guide and List
(1 answer)
Closed 7 years ago.
I'm less than a year into C++ development (focused on other languages prior to this) and I'm looking at a guy's code who's been doing this for two decades. I've never seen this syntax before and hopefully someone can be of some help.
bool b; // There exists a Boolean variable.
int i; // There exists an integer variable.
sscanf(value, "%d", &i); // The int is assigned from a scan.
b = (i != 0); // I have never seen this syntax before.
I get that the boolean is being assigned from the int that was just scanned, but I don't get the (* != 0) aspects of what's going on. Could someone explain why this person who knows the language much better than I is doing syntax like this?
Have a read here:
http://en.cppreference.com/w/cpp/language/operator_comparison
The result of operator != is a bool. So the person is saying "compare the value in i with 0". If 'i' is not equal to 0, then the '!=' returns true.
So in effect the value in b is "true if 'i' is anything but zero"
EDIT: In response to the OP's comment on this, yes you could have a similar situation if you used any other operator which returns bool. Of course when used with an int type, the != means negative numbers evaluate to true. If > 0 were used then both 0 and negative numbers would evaluate to false.
The expression (i != 0) evaluates to a boolean value, true if the expression is true (i.e. if i is non-zero) and false otherwise.
This value is then assigned to b.
You'd get the same result from b = i;, if you prefer brevity to explicitness, due to the standard boolean conversion from numeric types which gives false for zero and true for non-zero.
Or b = (i != 0) ? true : false; if you like extraneous verbosity.
(i != 0) is an expression that evaluates to true or false. Hence, b gets the value of true/false depending on the value of i.
This is fairly fundamental syntax. The != operator performs a "not equal to" comparison.
You may be being confused by the shorthand of initialising a bool directly from the result of a comparison operator, but the syntax itself is not esoteric.
The program is essentially equivalent to:
bool b;
int i;
sscanf(value, "%d", &i);
if (i != 0)
b = true;
else
b = false;
The key is that i != 0 is itself an expression that evaluates to true or false, not some magic that may only be used in an if statement.
Basically, if the condition (i not_equal_to 0 ) is satisfied, b gets the value "true". Else b gets the value "false".
Here, "i != 0" is a boolean expression that will be true if "i" is non-zero and false if it is zero.
All that is happening here is the result of that expression is being assigned to a variable.
You could also do things like...
boolean canDrinkAlcohol = (person.age() >= 18 && person.country.equals("UK") || person.age() >= 21 && person.county.equals("US"));
...
if(canDrinkAlcohol) {
...
}
or something
printf("What do you do?\n1. Walk Away.\n2. Jump.\n3. Open Door.\n\n");
scanf("%d",&Choice);
printf("\n\n\n");
while(4<=Choice,Choice<=0);
{
printf("That is not a choice.\n");
printf("What do you do?\n1. Walk Away.\n2. Jump.\n3. Open Door.\n\n");
scanf("%d",&Choice);
printf("\n\n\n");
}
So this is my program. It works but what I want it to do is to repeat until an answer of 1, 2, or 3 is put in. But no matter what the answer is it has it go through the while loop then continue regardless of the next choice. (Also, I did declare "Choice"; I just didn't want to show the whole program.)
There are two problems in your code. Your while-loop expression is incorrect. The comma does not do what you think it does: in C/C++, the comma executes the left-hand expression and evaluates to the right-hand expression, meaning that in your case you are only checking the second condition. You probably want:
while(4<=Choice || Choice<=0)
The || is the OR operator, which returns true if either of the expressions around it are true.
Secondarily, there is a misplaced semicolon at the end of the while loop:
while(4<=Choice,Choice<=0); //<-- this should not be here
This marks the end of the loop, meaning that your code is parsed as:
while(4<=Choice,Choice<=0); //loop body is empty
{
//and we have a random unnamed block following it
}
Remove the semicolon and your while loop should execute correctly.
C and C++ have a comma operator, which has the lowest precedence of all operators. It evaluates the left operand and throws the result away, and then evaluates the right operand. Thus, your while condition is equivalent to:
while (Choice <= 0)
You also have a bug because there is a semicolon immediately after the condition, which makes for an infinite loop if Choice is not strictly positive (because nothing in the loop changes the value of Choice).
What you probably intended to write was:
while (Choice >= 4 || Choice <= 0)
{
...
}
The comma operator , doesn't test both conditions, it simply returns the second of the two. So your while loop is the equivalent of:
while(Choice<=0) ;
and since there's a ; following the statement, it is in fact an infinite loop if the condition is met. Good thing you didn't enter a choice of -1.
what is the correct syntax for checking a varable value and then setting a varable in the same condition also checking that new set varables var, all in one if statement?
so basically something like
if(this->somevar > 0 && this->newvar = this->GetNewVar(this->somevar),this->newvar > 0)
i know that is not the correct syntax or at least its not working for me anyway, hence the topic, i am using that as an example, so if this->somevar is null or 0, i don't want it to execute the next condition which is && this->newvar = this->GetNewVar(this->somevar,this->newvar but instead skip the statement and ignore that part.
what is the correct syntax for something like this?
&& is an operator with short circuit evaluation, right part is not executed if left part is true.
But why don't you simply write:
if(this->somevar > 0)
{
this->newvar = this->GetNewVar(this->somevar);
if (this->newvar > 0)
{
...
This will certainly makes things clearer ...
the logical AND && operator is short-circuited if this->somevar evaluates to zero, meaning the rest of your if expression would not be evaluated in that situation
The expression after the comma is not necessary. Also, there is one thing missing, parentheses arround the assignment:
if(this->somevar > 0 && (this->newvar = this->GetNewVar(this->somevar)) > 0)
Without the parentheses you may end up setting this->newvar to the value of the boolean expression
this->GetNewVar(this->somevar),this->newvar > 0, which will be evaluated to a boolean result (true/false which, in turn, may be converted to 0 or 1 or -1 depending on the compiler, when cast to the type of this->newvar).
I think only the bit after the comma is evaluated for the if condition. The expression on the left of the comma is ignored.
int main() {
if( false, true) { cout << " got to if( false, true ) "; }
if ( true, false ) { cout << "got to if( true, false ) "; }
}
to answer your question, you can put anything on the left of the comma and do whatever you like, as long as the expression you want to evaluate is the last expression in the list.
so if ( exp1, exp2, exp3 , exp4 ) dowhatever(); only gets run if exp4 is true. You should really run exp1 to exp3 outside the if condition for readability.