13

Original formulation is given here (you can try also your program for correctness) .

Additional rules:
1. The program should read from standard input and write to standard output.
2. The program should return zero to the calling system/program.
3. The program should compile and run with gcc -O2 -lm -s -fomit-frame-pointer.

The challenge has some history: the call for short implementations has been announced at the Polish programming contest blog in September 2009. After the contest, the shortest code was 81 chars long. Later on the second call has been made for even shorter code and after the year matix2267 published his solution in 78 bytes:

main(c){read(0,&c,1)?c-41&&main(c-40&&(c%96<27||main(c),putchar(c))):exit(0);}

Anyone to make it even shorter or prove this is impossible?

Cœur
  • 37,241
  • 25
  • 195
  • 267
kuszi
  • 2,069
  • 29
  • 36

3 Answers3

13

Here's a way to reduce the code down to 76 chars:

main(c){read(0,&c,1)?c-41&&main(c-40&&putchar(c,c%96>26&&main(c))):exit(0);}

A longer, commented version for clarity:

int main(int c)
{
   if (read(0,&c,1)) {          /* read char */
       if (c-41) {              /* if not ')' */
           if (c-40) {          /* then if not '(' */
               if (c%96>26) {   /* then if operator (not alphabet or <LF>) */
                   main(c);     /* recurse */
               }
               putchar(c);      /* print */
           }
           main(c);             /* recurse */
       }        
   } else exit(0);              /* end program */
}
makes
  • 6,438
  • 3
  • 40
  • 58
4

I'm not out to break any records but I'll post this anyway:

#define x(z) while(p>##z s)putchar(*p--);
main(c){
int s[9],*p=s-1;
for(;read(0,&c,1);){
isalpha(c)?putchar(c):c=='('?(c=0):c==')'?(c=1):isdigit(c)?:(*++p=c);
if(c==0){x()main(0);}
if(c==1) break;}
x(=)return 0;}

Edit: Fixed correctness issues pointed out by kuszi's comment.

makes
  • 6,438
  • 3
  • 40
  • 58
  • If you like this sort of puzzles You can have a look at [this contest](http://www.spoj.pl/SHORTEN/) for more (variety of programming languages allowed). – kuszi Jan 07 '11 at 08:37
  • Your program should not output the number of test cases, and it lacks the new line character after the test case. See [the working example](http://ideone.com/ihrpz) – kuszi Jan 12 '11 at 13:07
4

Well, the real winner is the one who wrote this small code you provided, but you can slightly modify it to remove the exit:

main(c){read(0,&c,1)?c-41&&main(c-40&&(c%96<27||main(c),putchar(c))):0;}

I tried and it works.

Benoit Thiery
  • 6,325
  • 4
  • 22
  • 28
  • Was going to agree, but I tried it out and the result was almost the same but not quite. Using the example input from http://www.spoj.pl/problems/ONP/ you get an extra trailing "3". – Shawn Chin Jan 12 '11 at 10:19
  • I don't have this extra "3" with gcc 3.4.4. Which one are you using? – Benoit Thiery Jan 12 '11 at 10:22
  • gcc version 3.4.6 20060404 (Red Hat 3.4.6-11). That said, I tried it out on gcc 4.1.2 and it works just fine. – Shawn Chin Jan 12 '11 at 10:26
  • OK it seems it depends on the version of gcc. Not sure it is worth a downvote, but that means it is not a good solution. I am surprised different versions of gcc are providing different results by the way. – Benoit Thiery Jan 13 '11 at 08:54
  • I agree, it's definitely not worth a downvote. If anything, it highlights the issue of code portability. +1 for a good attempt. – Shawn Chin Jan 13 '11 at 13:17
  • @Benoit, as I understand, the program interprets the numbers on first line of input as operators. When input runs out, a matching number of actual operators and operands has been printed. The "stray" number should still be in the recursion tree, unprinted, when `exit(0)` kills the whole program. If `exit` doesn't happen, execution happily climbs down the recursion tree and prints all remaining characters on its way. Are you sure the stray `3` isn't overwritten by your command prompt or something? Otherwise I gotta try 3.4.4 too `:)` – makes Jan 13 '11 at 15:58
  • 1
    @mizo, you're right, it should not work on any gcc version. I don't know why the 3 was not displayed with gcc 3.4.4 and when trying again, it sometimes appears, sometimes not, depending on the input provided. Strange... – Benoit Thiery Jan 14 '11 at 08:43