Chinaunix首页 | 论坛 | 博客
  • 博客访问: 166695
  • 博文数量: 33
  • 博客积分: 2143
  • 博客等级: 大尉
  • 技术积分: 807
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-31 10:24
个人简介

Show me the money

文章分类

全部博文(33)

文章存档

2015年(1)

2013年(1)

2011年(12)

2010年(14)

2009年(2)

2008年(2)

2005年(1)

我的朋友

分类: C/C++

2011-09-08 15:29:00

1.         分析代码,当t < -72-72 <= t < -50的时候,程序都会进入相同的分支,因此大胆揣测main(-81…) main(-87…) main(-79…) 实现相同的功能;main(-61…)main(-64…)也实现相同的功能。于是,将程序修改为:

const char *coding1 = "@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' ')# }'+}##(!!/";

const char *coding2 = "!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry";

int main(int t, int p, char *str)

{

    int result, n;

    if( t > 1 )  {

        if(t < 3 ) {

            n = main(-80, 0, str +1);

            n = main(-80, 1-p, n + str );

            result = main(-80, -13, str + n) ;

        } else

            result = 1;

        if(t < p )

            main( t+1, p , str) ;

        if( main(-80, -27+t, str) && t == 2 )

            if (p < 13)

                main (2, p +1, "%s %d %d\n");

        return result;

    } else if(t < 0) {

        if(t < -72)

            result = main(p , t, coding1) ;

        else {

            if(t < -50) {

                if(p == *str )

                    result = putchar(31[ str ]);

                else

                    result = main(-61, p , str +1);

            } else

                result = main((* str == '/') + t, p , str + 1 ) ;

        }

    } else if( t == 1 )

        result = main (2, 2 , "%s") ;

    else { /* t == 0 */

        if( *str == '/' ) {

            result = 1;

        } else {

            n = main(-61, *str , coding2);

            result = !! main(0, n, str+1);

        }

    }

    return result;

}

经过验证,我们的想法是正确的。(不知道怎么验证?修改过的程序和原始程序的运行结果做diff…

 

2.         然后,我们继续分析代码。注意到t < -50 这个分支,只要某一次传入的参数进入这个分支,之后就会一直递归进入此分支,直到满足 p == *str 递归才结束。发挥一下想象力,这个像不像一个for循环?从字符串str中找到一个字符等于p,然后输出str[31]。于是,我们又把程序修改为:

const char *coding1 = "@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' ')# }'+}##(!!/";

const char *coding2 = "!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry";

int main(int t, int p, char *str)

{

    int result, n;

    if( t > 1 )  {

        if(t < 3 ) {

            n = main(-80, 0, str +1);

            n = main(-80, 1-p, n + str );

            result = main(-80, -13, str + n) ;

        } else

            result = 1;

        if(t < p )

            main( t+1, p , str) ;

        if( main(-80, -27+t, str) && t == 2 )

            if (p < 13)

                main (2, p +1, "%s %d %d\n");

        return result;

    } else if(t < 0) {

        if(t < -72)

            result = main(p , t, coding1) ;

        else {

            if(t < -50) {

                int i;

                for(i=0; ;i++) {

                    if(str[i] == p) {

                        result = putchar(str[31 + i]);

                        break;

                    }

                }

            } else

                result = main((* str == '/') + t, p , str + 1 ) ;

        }

    } else if( t == 1 )

        result = main (2, 2 , "%s") ;

    else { /* t == 0 */

        if( *str == '/' ) {

            result = 1;

        } else {

            n = main(-61, *str , coding2);

            result = !! main(0, n, str+1);

        }

    }

    return result;

}

 

 

3.         继续,注意到t < -72这个分支,它的功能就是交换参数t, p的位置,以及将第3个参数换成coding1。于是,我们将程序修改为:

const char *coding1 = "@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' ')# }'+}##(!!/";

const char *coding2 = "!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry";

int main(int t, int p, char *str)

{

    int result, n;

    if( t > 1 )  {

        if(t < 3 ) {

            n = main(0, -80, coding1);

            n = main(1-p, -80, coding1 );

            result = main(-13, -80, coding1 ) ;

        } else

            result = 1;

        if(t < p )

            main( t+1, p , str) ;

        if( main(-27+t, -80, coding1) && t == 2 )

            if (p < 13)

                main (2, p +1, "%s %d %d\n");

        return result;

    } else if(t < 0) {

        if(t < -50) {

            int i;

            for(i=0; ;i++) {

                if(str[i] == p) {

                    result = putchar(str[31 + i]);

                    break;

                }

            }

        } else /* -50 <= t < 0 */

            result = main((* str == '/') + t, p , str + 1 ) ;

    } else if( t == 1 )

        result = main (2, 2 , "%s") ;

    else { /* t == 0 */

        if( *str == '/' ) {

            result = 1;

        } else {

            n = main(-61, *str , coding2);

            result = !! main(0, n, str+1);

        }

    }

    return result;

}

 

4.         继续,观察 -50 <= t < 0这个分支,如果 *str != '/'t的值不变,str+1;如果*str == '/'str+1;随着t的值不断增长,最终t=0;这实际上也相当于一个for循环,通过t去定位str中子字符串的位置,然后调用main(0…)去完成相应的功能。所以,程序可以简化为:

const char *coding1 = "@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' ')# }'+}##(!!/";

const char *coding2 = "!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry";

int main(int t, int p, char *str)

{

    int result, n;

    if( t > 1 )  {

        if(t < 3 ) {

            n = main(0, -80, coding1);

            n = main(1-p, -80, coding1 );

            result = main(-13, -80, coding1 ) ;

        } else

            result = 1;

        if(t < p )

            main( t+1, p , str) ;

        if( main(-27+t, -80, coding1) && t == 2 )

            if (p < 13)

                main (2, p +1, "%s %d %d\n");

        return result;

    } else if(t < 0) {

        if(t < -50) {

            int i;

            for(i=0; ;i++) {

                if(str[i] == p) {

                    result = putchar(str[31 + i]);

                    break;

                }

            }

        } else { /* -50 <= t < 0 */

            int i;

            char *x;

            for(i = t, x = str; i < 0 ; i++)

                while( *x++ != '/' ) {}

            result = echo(0, p , x) ;

        }

    } else if( t == 1 )

        result = main (2, 2 , "%s") ;

    else { /* t == 0 */

        if( *str == '/' ) {

            result = 1;

        } else {

            n = main(-61, *str , coding2);

            result = !! main(0, n, str+1);

        }

    }

    return result;

}

 

5.         继续整理,删除一些无用代码,并提取函数

const char *coding1 = "@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' ')# }'+}##(!!/";

const char *coding2 = "!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry";

int echo1(int p, const char *str)

{

    int i;

    for(i=0; ;i++)

       if(str[i] == p)

           return putchar(str[31 + i]);

}

int echo(int t, int p, const char *str)

{

    int result, n;

    if( t > 1 )  {

       if(t < 3 ) {

           echo(0, -80, coding1);

           echo(1-p, -80, coding1 );

           result = echo(-13, -80, coding1 ) ;

       } else

           result = 1;

       if(t < p )

           echo( t+1, p , str) ;

       if( echo(-27+t, -80, coding1) && t == 2 )

           if (p < 13)

              echo (2, p +1, "%s %d %d\n");

       return result;

    } else if(t < 0) {

       if(t < -50) {

           result = echo1(p, str);

       } else { /* -50 <= t < 0 */

           int i;

           const char *x;

           for(i = t, x = str; i < 0 ; i++)

              while( *x++ != '/' ) {}

           result = echo(0, p , x) ;

       }

    } else if( t == 1 )

       result = echo (2, 2 , "%s") ;

    else { /* t == 0 */

       if( *str == '/' ) {

           result = 1;

       } else {

           echo1(*str , coding2);

           result = !! echo(0, 0, str+1);

       }

    }

    return result;

}

int main()

{

    return echo(1, 1, "");

}

 

6.         分析t==0这个分支,如果*str != '/',则一直递归输出*str;如果*str == '/',则返回1。将递归改成for循环:

const char *coding1 = "@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' ')# }'+}##(!!/";

const char *coding2 = "!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry";

int echo1(int p, const char *str)

{

    int i;

    for(i=0; ;i++)

        if(str[i] == p)

            return putchar(str[31 + i]);

}

int echo(int t, int p, const char *str)

{

    int result, n;

    if( t > 1 )  {

        if(t < 3 ) {

            echo(0, -80, coding1);

            echo(1-p, -80, coding1 );

            result = echo(-13, -80, coding1 ) ;

        } else

            result = 1;

        if(t < p )

            echo( t+1, p , str) ;

        if( echo(-27+t, -80, coding1) && t == 2 )

            if (p < 13)

                echo (2, p +1, "%s %d %d\n");

        return result;

    } else if(t < 0) {

        if(t < -50) {

            result = echo1(p, str);

        } else { /* -50 <= t < 0 */

            int i;

            const char *x;

            for(i = t, x = str; i < 0 ; i++)

                while( *x++ != '/' ) {}

            result = echo(0, p , x) ;

        }

    } else if( t == 1 )

        result = echo (2, 2 , "%s") ;

    else { /* t == 0 */

        if( *str == '/' ) {

            result = 1;

        } else {

            const char *x = str;

            while(*x != '/') {

                echo1(*x, coding2);

                x++;

            }

            result = !! 1;

        }

    }

    return result;

}

int main()

{

    return echo(1, 1, "");

}

 

阅读(2168) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~