“First time” test

What is the shortest C expression that is defined to evaluated to false the first time and true for every time after that:

Reference implementation:

bool b = false;  // you get this for free.

(b ? true : b = true, false)  // only this line is measured.
• Since the task description in fact states that it should return true for every time after the initial false, I'd say that solutions that work only a limited time (even if it's 500+ years) don't count as correct solutions. – Joey Jan 26 '12 at 21:35

3 chars:

As Keith Randall suggested in a comment, if we can use floats or doubles, this should do the trick:

float b = 0;  // free

b++

Eventually, as b is incremented repeatedly, two things may happen: either the addition overflows (and thus evaluates to HUGE_VAL, which may be infinite or a large positive value) or, more likely, the roundoff step size simply grows larger than one, turning the increment into a no-op. In either case, the expression should continue to evaluate as true.

• That will happen at ~1/ε en.wikipedia.org/wiki/Machine_epsilon – BCS Jan 27 '12 at 15:34
• I think that is valid and I don't think anything smaller is going to work (there are no mutating single char unary operators). OTOH coercion a floating point to bool offends my sensibilities (as well as FP-ops being slower than int-ops). – BCS Jan 27 '12 at 15:38
• To be precise, b stops growing at 16777216.0 (=2^24), as there are only 23 bits of mantissa in a float. – Keith Randall Jan 27 '12 at 21:56
• BTW: I'm not sure but ++ on a bool might work as well: stackoverflow.com/a/3450554/1343 – BCS Feb 16 '12 at 19:18

6 characters

int i = 0; //free
i||i++

OTOH: I like Peter Taylor's solution as it has no branch so it may be faster (depending on compiler details).

p.s. I came up with that after posting the question (honest!).

• After the first time, the left side of the || will be true and short-circuit evaluation will prevent the right side from getting evaluated so nothing gets updated. – BCS Jan 26 '12 at 21:37
• Argh, indeed. I take that back :) – Joey Jan 26 '12 at 21:38

With:

long long b = 0;

then three characters are enough for many applications:

b++

Evaluates false first and true for a long time thereafter ;-)

• I'd say it'll be true for a long, long time. – Kris Harper Jan 26 '12 at 15:47
• It evaluates true only 18446744073709551614 times, not forever :-/ – copy Jan 26 '12 at 15:53
• Use a double and it will be true forever! – Keith Randall Jan 26 '12 at 16:48
• And unless you make that unsigned, it is undefined behavior. – BCS Jan 26 '12 at 18:16
• 18446744073709551614 times. Assuming we could perform this operation 1 billion times per second, it would take about 585 years. – Steven Rumbalski Jan 26 '12 at 20:09

7 characters

As Peter Taylor suggested, still int a = 2;

!(a/=2)

8 characters (old)

!(a>>=1)

Another version of this: int b = 0x40000000;

!(b<<=1)
• The first one is portable. The second isn't. But doesn't !(a/=2) work? – Peter Taylor Jan 26 '12 at 18:32
• @PeterTaylor yeah, you're right. Thinking too complicated ... – copy Jan 26 '12 at 19:03
• The left shift works and is defined if you go with unsigned ints and use 0xD... which I think you can get in a portable way via ~((~0u)>>2). – BCS Jan 27 '12 at 15:43
• @BCS thanks for the info, but I'll just leave it at that because the other two versions are shorter anyway. – copy Jan 27 '12 at 22:08

9 chars:

b=0;//free
(b&(b=1))

at least if it's valid c (not undefined behavior)

12 chars

(b?b:!(b=1))

this is valid c

!b|(b=0)

bit-wise or works as well since in first trial 0|0 yields 0 and in other trials !0|0 yields !0 which is guaranteed to be true. It is also ANSI-compliant, I've tried the following code with GCC 4.6.1 with -ansi flag:

#include <stdio.h>
main () {
int b=1, i=0;
for (;i<5;++i)
printf ("%d",!b|(b=0));
}
• This is undefined behavior. The compiler could evaluate b=0 first and !b later, making it true the first time. – ugoren Jun 19 '12 at 6:40

11 10 chars

I can't beat the three char approach, but make it different:

int b = 0;  // free

b?b:0*(b=1) // 11 characters
b||0*(b=1)  // one character less thanks to breadbox
• That wound count as 11 and doesn't work as it is two different expressions. – BCS Jan 31 '12 at 15:10
• @BCS I thought the first initialization was for free (so, the chars do not count), and the second one is an expression to be evaluated. I fail to see why wouldn't it work. – Alpha Jan 31 '12 at 22:36
• I was summing you were considering the expression in the first line to be the "gives false" and the other to be the "gives true". ---- The expression will evaluate to 1 (i.e. true) every time, including the first. The spec is that the expression is true the first time and false there after. – BCS Feb 1 '12 at 3:26
• @BCS Got it! Will update now to reflect your correction and will think a little bit about it. I'll see if I can give it a twist. Thanks! – Alpha Feb 1 '12 at 5:20
• b?b=1:0*(b=1) actually works. – walpen Jun 17 '12 at 16:35

APL (5 or 6)

If I'm only allowed to initialize the variable to 0, it's 6 characters:

A←0    ⍝ free
⊃A←⍴⍴A

How it works: ⍴A is the size of A (which is the empty list the first time around, because 0 is a scalar), so ⍴⍴A is the size of the size of A (which is  the first time, because a one-dimensional empty list has zero values in one dimension). This is then assigned to A (A←) and the first element is returned ().

1. A is 0, ⍴A is [], then A is set to ⍴⍴A which is , and the first element is returned (0).
2. A is , ⍴A is , then A is set to ⍴⍴A which is , and the first element is returned (1).
3. A is , so ⍴A remains , so A is set to ⍴⍴A which remains  and it returns 1.

If I'm allowed to initialise the variable to anything I want, I can set it to the empty list and drop one of the s to make it 5 characters:

A←⍬    ⍝ free, set to empty list
⊃A←⍴A

9 chars

b=1; //free
!b||(b=0)

edited: no longer undefined behavior

• that very similar to a=a++ which is undefined – ratchet freak Jan 26 '12 at 2:46
• now defined, +3 chars :( – AShelly Jan 26 '12 at 3:54
bool b = false; // for free?
b = b?b:!b;

bool b = false;

!b+b++
• I think that is undefined behavior (and it will overflow and reset) – BCS Feb 16 '12 at 0:14
• Why do you think so? What exactly is undefined? plusplusing a boolean? Or the priority of post-increment operation? – Vanuan Feb 16 '12 at 12:26
• 1) The value depends on order of evaluation which is undefined behavior. 2) Either that will eventually overflow (and both hit undefined behavior as well as return false) or the 3 char solution (b++) works with bool as well: stackoverflow.com/a/3450554/1343 – BCS Feb 16 '12 at 19:17
• The answer in the link you provided quotes C++03 standard. Does this standard apply to C99 as well? – Vanuan Feb 16 '12 at 20:14
• I'm reasonably sure that it is undefined in C as well. – BCS Feb 17 '12 at 0:28

1 Character

Since you didn't specify which compiler and/or which command line options are to be used, here's my 1 character solution:

bool b = false;

X

Compile with

gcc -DX='(b ? true : b = true, false)'
• As a general rule, codegolf counts special command-line options towards the score. So this would be 41+ characters. – Peter Taylor Feb 20 '12 at 22:18