devnull
devnull

Reputation: 123478

Obfuscated scientific calculator. Please explain how it works

I was trying to understand how does the following program work. It is a command-line scientific calculator. The source is taken from here. It seemed pretty readable for an IOCCC entry but apparently it's not.

#include <stdio.h>
#include <math.h>
#define clear 1;if(c>=11){c=0;sscanf(_,"%lf%c",&r,&c);while(*++_-c);}\
  else if(argc>=4&&!main(4-(*_++=='('),argv))_++;g:c+=
#define puts(d,e) return 0;}{double a;int b;char c=(argc<4?d)&15;\
  b=(*_%__LINE__+7)%9*(3*e>>c&1);c+=
#define I(d) (r);if(argc<4&&*#d==*_){a=r;r=usage?r*a:r+a;goto g;}c=c
#define return if(argc==2)printf("%f\n",r);return argc>=4+
#define usage main(4-__LINE__/26,argv)
#define calculator *_*(int)
#define l (r);r=--b?r:
#define _ argv[1]
#define x

double r;
int main(int argc,char** argv){
  if(argc<2){
    puts(
      usage: calculator 11/26+222/31
      +~~~~~~~~~~~~~~~~~~~~~~~~calculator-\
      !                          7.584,367 )
      +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
      ! clear ! 0 ||l   -x  l   tan  I (/) |
      +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
      ! 1 | 2 | 3 ||l  1/x  l   cos  I (*) |
      +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
      ! 4 | 5 | 6 ||l  exp  l  sqrt  I (+) |
      +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
      ! 7 | 8 | 9 ||l  sin  l   log  I (-) |
      +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(0
    );
  }
  return 0;
}

It compiles without warnings on gcc 4.7.2 (Linux) with -Wall. I attempted to simplify it but any further changes to the slightly modified form given below start to produce unexpected results (incorrect output).

#include <stdio.h>
#include <math.h>
#define clear 1;if(c>=11){c=0;sscanf(_,"%lf%c",&r,&c);while(*++_-c);}\
  else if(argc>=4&&!main(4-(*_++=='('),argv))_++;g:c+=
#define puts(d,e) return 0;}{double a;int b;char c=(argc<4?d)&15;\
  b=(*_%__LINE__+7)%9*(3*e>>c&1);c+=
#define I(d) (r);if(argc<4&&*#d==*_){a=r;r=usage?r*a:r+a;goto g;}c=c
#define return if(argc==2)printf("%f\n",r);return argc>=4+
#define usage main(4-__LINE__/26,argv)
#define calculator *_*(int)
#define l (r);r=--b?r:
#define _ argv[1]
#define x

double r;
int main(int argc,char** argv){
  if(argc<2){
    puts(
      usage: calculator 11/26+222/31
      +calculator-\
      !                          7.584,367 )
      +
      ! clear ! 0 ||l   -x  l   tan  I (/) |
      +
      ! 1 | 2 | 3 ||l  1/x  l   cos  I (*) |
      +
      ! 4 | 5 | 6 ||l  exp  l  sqrt  I (+) |
      +
      ! 7 | 8 | 9 ||l  sin  l   log  I (-) |
      +(0);
  }
  return 0;
}

Can somebody please explain how it works?

Upvotes: 1

Views: 544

Answers (1)

ams
ams

Reputation: 25579

It expands to look like this:

double r;
int
main (int argc, char **argv)
{
  if (argc < 2)
    {
      if (argc == 2)
    printf ("%f\n", r);
      return argc >= 4 + 0;
    }
  {
    double a;
    int b;
    char c = (argc < 4 ? main (4 - 21 / 26,
                   argv) : *argv[1] * (int) 11 / 26 + 222 / 31 +
          ~~~~~~~~~~~~~~~~~~~~~~~~*argv[1] * (int) -!7.584) & 15;
    b = (*argv[1] % 21 + 7) % 9 * (3 * 367 >> c & 1);
    c += +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+!1;
    if (c >= 11)
      {
    c = 0;
    sscanf (argv[1], "%lf%c", &r, &c);
    while (*++argv[1] - c);
      }
    else if (argc >= 4 && !main (4 - (*argv[1]++ == '('), argv))
      argv[1]++;
  g:c += !0 || (r);
    r = --b ? r : -(r);
    r = --b ? r : tan (r);
    if (argc < 4 && *"/" == *argv[1])
      {
    a = r;
    r = main (4 - 23 / 26, argv) ? r * a : r + a;
    goto g;
      }
    c = c | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+!1 | 2 | 3 || (r);
    r = --b ? r : 1 / (r);
    r = --b ? r : cos (r);
    if (argc < 4 && *"*" == *argv[1])
      {
    a = r;
    r = main (4 - 25 / 26, argv) ? r * a : r + a;
    goto g;
      }
    c = c | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+!4 | 5 | 6 || (r);
    r = --b ? r : exp (r);
    r = --b ? r : sqrt (r);
    if (argc < 4 && *"+" == *argv[1])
      {
    a = r;
    r = main (4 - 27 / 26, argv) ? r * a : r + a;
    goto g;
      }
    c = c | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+!7 | 8 | 9 || (r);
    r = --b ? r : sin (r);
    r = --b ? r : log (r);
    if (argc < 4 && *"-" == *argv[1])
      {
    a = r;
    r = main (4 - 29 / 26, argv) ? r * a : r + a;
    goto g;
      }
    c = c | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(0);
  }
  if (argc == 2)
    printf ("%f\n", r);
  return argc >= 4 + 0;
}

It's still not exactly readable, but at least now nothing's hidden from you. You should be able to do your simplifications without being bitten so badly.

I'm not going to go into a full explanation for the same reason @cmaster said.

Upvotes: 4

Related Questions