Thread: Let's Disect

  1. #1
    Registered User linuxdude's Avatar
    Join Date
    Mar 2003
    Location
    Louisiana
    Posts
    926

    Let's Disect

    Hey I have seen this code a couple of times I have used indent to make it more readable. It prints the twelve days of christmas.
    Code:
    #include <stdio.h>
    
    main (t, _, a)
         char *a;
    {
      return !0 < t ? t < 3 ? main (-79, -13, a + main (-87, 1 - _,
                                main (-86, 0, a + 1) + a)) : 1, t < _? main (t + 1,
    _, a) : 3, main (-94, -27 + t, a) && t == 2 ? _ < 13 ? main (2, _ + 1, "%s %d %d
    \n") : 9 : 16 : t < 0 ? t < -72 ? main (_, t, "@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,
    /*{*+,/w{%+,/w#q#n+,/#{l,+,/n{n+\
    ,/+#n+,/#;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l q#'+d'K#!/\
    +k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# ){n\
    l]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#\
    n'wk nw' iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c \
    ;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;\
    #'rdq#w! nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/")
        : t < -50 ? _ == *a ? putchar (a[31]) : main (-65, _, a + 1) : main ((*a ==
    '/') + t, _, a + 1) : 0 < t ? main (2, 2, "%s") : *a == '/' || main (0, main (-6
    1, *a, "!ek;dc \
    i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry"), a + 1);
    }
    If anyone can indent it better than that, that would be nice. I just thought we could disect this and see how it works. All I see is that it uses recursions!?! It returns a boolean expression I think and the programmer has a variable _ (I think just for confusion) I think t is an int I know a is a char * (Isn't this the old way of defining functions(K&R))

  2. #2
    Registered User
    Join Date
    Feb 2002
    Posts
    465
    Code:
    /*
     * christmas.c 
     * a program that prints out the twelve days of chrismas
     *   in clear and obvious fashion
     *
     * adopted from the obfuscated version by Michael Bayne <[email protected]>
    * and Paul Phillips <[email protected]>
    */
    
    
    #include <stdio.h>
    
    #define babble1 "@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w\
    {%+,/w#q#n+,/#{l+,/n{n+,/+#n+,/#;#q#n+,/+k#;*+,/'r :'d*'3,}\
    {w+K w'K:'+}e#';dq#'l q#'+d'K#!/+k#;q#'r}eKK#}w'r}eKK\
    {nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# ){nl]!/n{n#'; r{#w'r \
    nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#n'wk nw' iwk{KK{nl]!/w\
    {%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c ;;{nl'-{}rw]'/+,}\
    ##'*}#nc,',#nw]'/+kd'+e}+;#'rdq#w! nr'/ ') }+}{rl#'{n' ')#}'+}\
    ##(!!/"
    
    #define babble2 "!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-\
    O;m .vpbks,fxntdCeghiry"
    
    int main (int arg1, int arg2, char* arg3)
    {
        /* if (!0 < arg1) { */
        if (arg1 > 1) {
            int rv;
    
            /* arg1 == 2, start printing day #arg2 */
            /* if (arg1 < 3) { */
            if (arg1 == 2) {
                int rv1, rv2;
    
                /* prints out 'On the ' */
                /* arg3 ignored, results in call to main(0, -86, babble1) */
                rv1 = main(-86, 0, arg3 + 1);
    
                /* prints out the ordinal date (ie. tenth) */
                /* arg3 ignored, results in call to main(1-day, -87, babble1) */
                rv2 = main(-87, 1 - arg2, rv1 + arg3);
    
                /* prints out 'day of Christmas my true love gave to me' */
                /* arg3 ignored, results in call to main(-13, -79, babble1) */
                main(-79, -13, arg3 + rv2);
            } /* else 1; */
    
            /* here we stack up a bunch of calls to ourself in 'phrase printing'
               mode to print out each successive phrase (partridge in a pear tree,
               and, two turtle doves). each call prints out the successively
               previous phrase, and we keep recursing until we've made one call
               for each day */
            if (arg1 < arg2) {
                main(arg1 + 1, arg2, arg3);
            } /* else 3; */
    
            /* this call causes us to print out the (-27 + arg1) th phrase in the
               phrase buffer, there are 26 phrases, so arg1 varies from 2 to 13 in
               order to print out each of the day's' gifts */
            /* arg3 ignored, results in call to main(-27 + arg1, -94, babble1) */
    
            rv = main(-94, -27 + arg1, arg3);
    
            /* rv is always 16 (hence true). see below where we return 16 instead
               of advancing to the next day */
    
            /* we don't execute this on the stacked up recursive calls made above
               (where we pass in arg1 values from 3 to the number of the current
               day), but only on the primary call (where we passed in 2), because
               this code causes us to write out the next day */
            if (rv && (arg1 == 2)) {
    
                /* here's where we decide how many days to print */
                if (arg2 < 13) {
    
                    /* 2 means we're a main recursive call that does a new day
                       arg2 + 1 increments the day
                       "%s %d %d" is to confuse us (it's ignored) */
                    return main(2, arg2 + 1, "%s %d %d\n");
    
                } else {
                    /* this is the return value of the command  --
                       echo $status after running this  [:-)] */
                    return 9;
                }
    
            } else {
                /* this is the return value of the above described recursive
                   calls, must be non-zero in original code because its return
                   value is checked */
                return 16;
            }
    
        } else {
            if (arg1 < 0) {
    
                if (arg1 < -72) {
                    /* this is the stealthy switch of the first two arguments and
                       replacement of argument 3 with a pointer to the word
                       buffer */
                    return main(arg2, arg1, babble1);
    
                } else {
                    /* if we're here, we want to translate and print out a
                       character */
                    if (arg1 < -50) {
    
                        /* if arg2 (the untranslated character we want to print)
                           is equal to *arg3 (some character in the translation
                           buffer */
                        if (arg2 == *arg3) {
    
                            /* if so, we're all set, print out the translated
                               version of the character (which is 31 characters up
                               the translation table) */
                            return putchar(arg3[31]);
    
                        } else {
                            /* if not, call ourselves with the printout magic
                               number, the same untranslated character and the
                               next character up in the translation table */
                            return main(-65, arg2, arg3 + 1);
                        }
    
                    /* if we're here, we want to print out a phrase. we start
                       out with arg3 pointing to babble1, and arg1 being -(the
                       number of phrases to skip before printing out a
                       phrase), we increment the pointer, incrementing arg1
                       each time we pass a slash, so when arg1 equals zero,
                       we've skipped the appropriate number of slashes
                       (phrases) and we end up down in the phrase printing
                       part of the code */
                    } else {
                        /* pushes babble1 pointer forward (skipping slashes) and
                           incrementing arg1 (every time a slash is seen) until
                           arg1 == 0. this positions a pointer in the babble2
                           buffer at the beginning of the -arg1 th
                           (slash-seperated) string */
                        return main((*arg3 == '/') + arg1, arg2, arg3+1);
                    }                    
                }
    
            } else {
                /* if (0 < arg1) { */
                if (arg1 == 1) {
    
                    /* this is the original call, since we are originally called
                       with arg1 == 1 (argc) */
                    return main(2, 2, "%s");
    
                } else { /* arg1 == 0 */
                    /* we've got a correctly positioned pointer into babble2 in
                       arg3  */
                    if (*arg3 == '/') {
    
                        /* we've hit the end of the phrase that we wanted to
                           translate and print */
                        return 1;
    
                    } else {
                        /* -61 could be any number greater than -72 but less than
                           -50 to cause us to go into printing out mode
                           *arg2 is a pointer to the untranslated character that we
                           want to print */
                        int rv = main(-61, *arg3, babble2);
    
                        /* we call ourselves again with the next character in the
                           word buffer, we'll end up right back here until we hit
                           a '/' at which point, we'll return (1) all the way up */
                        return main(0, rv, arg3+1);
                    }
                }
            }
        }
    }
    i got this from:

    http://www.cs.rit.edu/usr/local/pub/...09/christmas.c
    Last edited by ...; 12-19-2003 at 04:32 AM.
    I came up with a cool phrase to put down here, but i forgot it...

Popular pages Recent additions subscribe to a feed