1

My friend sent me a exercise that he can't do:
(C++)

int main()
{
    unsigned int x = 0xB0FF14a5;
    unsigned int y = 0x7340c00e;
    // enter code here
    if(x==0x7340c00e && y==0xB0FF14a5) victory();
    return 0;
}

The main goal is to run victory() function.
Assumptions:
-max 11 chars
-You can't use: "main", "victory", "asm", "&", "*", "(", "/"
-You can use only one semicolon

I tried with #define and some other things, but nothing (I'm not C++ master) :/
I have no idea how to solve this; thanks for helping!

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
  • 4
    No practical use of this question (and the idea behind it). So voted to close. – Nawaz Aug 16 '12 at 14:28
  • Well, you have to swap the values of x and y – Bartek Banachewicz Aug 16 '12 at 14:28
  • @juanchopanza: that's 15 chars – Cornstalks Aug 16 '12 at 14:30
  • @juanchopanza: it's longer than 11 chars... – Patryk Wychowaniec Aug 16 '12 at 14:30
  • @juanchopanza you can't use `(` – Bartek Banachewicz Aug 16 '12 at 14:30
  • @Bartek Banachewicz: I tried, but my solutions were longer than 11 chars... – Patryk Wychowaniec Aug 16 '12 at 14:31
  • @close voters: the question is concrete, specific, complete, narrow and sincere, and has been answered in its current form. Please re-open. – TemplateRex Aug 16 '12 at 14:46
  • @rhalbersma: But it's an artificial puzzle, not a [practical, answerable questions based on actual problems that you face](http://stackoverflow.com/faq#dontask), so it's not really suitable for this site. – Mike Seymour Aug 16 '12 at 14:51
  • @MikeSeymour I believe that part of the FAQ is aimed at vague questions, not at entertaining questions. There are scores of language-lawyer questions that are as impractical as this one, and they never get closed (and for good reason). One man's puzzle is another man's optimization. – TemplateRex Aug 16 '12 at 14:54
  • @MikeSeymour "Stack Overflow is for professional and **enthusiast** programmers". I bet this question has put a smile on most readers out there. It's similar to ball players showing off their impractical and artificial ball-handling skills. It's harmless and lightens up the place. – TemplateRex Aug 16 '12 at 14:58

4 Answers4

12

Use the XOR swap algorithm:

x^=y^=x^=y;

This is equivalent (usually, see below) to:

          //x==A,   y==B
x ^= y;   //x==A^B, y==B
y ^= x;   //x==A^B, y==A
x ^= y;   //x==B,   y==A

It works because XORing by the same number twice gives you the original number.

In C++03 the single-expression version is undefined behavior so may not work correctly on all compilers/platforms. This is because there is no sequence point between modification and use of variables.

In C++11, it is well-defined. The standard says (5.17.1):

In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression.

interjay
  • 107,303
  • 21
  • 270
  • 254
  • 6
    Equivalent, apart from the fact that it modifies and uses each variable with no intervening sequence point, so the behaviour is undefined. – Mike Seymour Aug 16 '12 at 14:33
  • I tried to do something similar, but my solutions were longer than the limit. This works, thank you! :) – Patryk Wychowaniec Aug 16 '12 at 14:33
  • I think there was something about right-associative operators and left-associative operators... – Alexander Chertov Aug 16 '12 at 14:46
  • Yep, according to [this](http://msdn.microsoft.com/en-us/library/126fe14k%28v=vs.80%29.aspx) operator ^= has right-to-left associativity so the behaviour is well defined. – Alexander Chertov Aug 16 '12 at 14:52
  • 2
    @AlexanderChertov: This is undefined behavior as Mike says because there are no sequence points between the variable accesses. Operator associativity only tells the parser how to parse the expression (i.e. it determines that the expression is parsed as `x^=(y^=(x^=y));`) and is not really relevant. – interjay Aug 16 '12 at 14:59
  • @AlexanderChertov: Associativity determines the order of evaluation of subexpressions. It doesn't determine when side effects (such as assignment) are applied; the only guarantee is that they happen some time before the next sequence point. – Mike Seymour Aug 16 '12 at 15:03
  • 1
    @MikeSeymour: Actually, I looked in the standard and I believe this is well-defined in C++11, see my edit. – interjay Aug 16 '12 at 15:10
  • @interjay: You're right; my knowledge is a bit dated. – Mike Seymour Aug 16 '12 at 16:57
  • @interjay, if the parser has the expression with brackets as you have put it, how is this not relevant? @MikeSeymour, I have never heard about side-effects of operator "^=", is it a standard term? According to [Wikipedia](http://en.wikipedia.org/wiki/Operator_associativity), `associativity (or fixity) of an operator is a property that determines how operators of the same precedence are grouped in the absence of parentheses`. For some reason we write `a=b=c=GetMeANumber();` and expect it to work, don't we? – Alexander Chertov Aug 17 '12 at 03:08
  • 1
    @AlexanderChertov: Yes, "side effect" is a well-defined term for changes to the program state caused by evaluating an expression. Evaluating an assignment expression does two things: calculating the value of the expression (e.g. the value to be assigned to `a` in `a=b=c;`), and the side effect of modifying the *lvalue* being assigned to. Before 2011, only the value calculation, not the side effect, was guaranteed to be sequenced before evaluating the rest of the expression, so modifying the *same* object twice in one expression had undefined behaviour. Apparently, it is well-defined now. – Mike Seymour Aug 17 '12 at 06:24
  • @MikeSeymour, thanks. That's something new for me. So for user-defined types with `operator+()` this expression is OK and for `int` it's undefined behavior in C++03? – Alexander Chertov Aug 17 '12 at 07:21
  • 1
    This isn't well-defined in C++11 either. There's no sequencing relationship between the reading of the value of `x` for the first `^=` and the store made by the third `^=`. – T.C. Mar 28 '15 at 08:36
  • @T.C. It's well-defined. The last assignment is sequenced after the value computation of its right operand, which is the value computation of the second assignment. Repeating that for the second assignment shows you that it is sequenced after the value computation of the first assignment, which is sequenced after the value computation of its left operand `x`. – interjay Mar 28 '15 at 12:21
  • By "first" I meant "leftmost" and "third" "rightmost". See http://stackoverflow.com/questions/29315133/swap-integers-via-xor-in-single-line-is-it-really-allowed-in-c11/29315672#29315672. – T.C. Mar 28 '15 at 12:30
  • 1
    the thing is, the **only** difference between `x=x op y` and `x op = y` is that x is *evaluated* only once (§5.17.7). this matters for things like `*++p`, but it does not imply extra sequencing. – sp2danny Mar 29 '15 at 19:03
8

Undefined behaviour, but Works On My Computer:

x^=y^=x^=y;

UPDATE: apparently, this is well-defined since 2011; see interjay's answer.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
4

13 characters and violates other rules, but gets the job done and too cute not to post:

#include<iostream>

void victory()
{
   std::cout << "Yes we can\n";
}

int main()
{
    unsigned int x = 0xB0FF14a5;
    unsigned int y = 0x7340c00e;
    #define if(x)
    if(x==0x7340c00e && y==0xB0FF14a5) victory();
    return 0;
}

Output on Ideone

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
1

Look at this algorithm: XOR swap algorithm But you will get a compile warning like:

warning: operation on ‘x’ may be undefined

if you use this algorithm in just one line

x ^= y ^= x ^= y;
tuxtimo
  • 2,730
  • 20
  • 29