用脚本解决C语言问题

vvoodyxiyoulinux上提出了一个C语言的问题,这个问题我之前见过,所以不想自己想了,想让计算机帮我完成。于是费了一番功夫写了个脚本帮我完成。(哎,老了,写代码慢了~~)

先贴“答案”,应该是总共8个结果(下面的9个中有两个明显是等价的):

int i,n=99;main(){for(i=0;i<n;i—){printf(“#”);}}
int i,
n=99;main(){for(i=0;i<n;i—){printf(“#”);}}
int i,n=99;main(){for(i=0;-i<n;i—){printf(“#”);}}
int i,n=99;main(){for(i=0;~i<n;i—){printf(“#”);}}
int i,n=99;main(){for(i=0;i<&n;i—){printf(“#”);}}
int i,n=99;main(){for(i=0;i<n;i—);{printf(“#”);}}
int*i,n=99;main(){for(i=0;i<n;i—){printf(“#”);}}
int i,n=99;main(){for(i=0;i+n;i—){printf(“#”);}}
int i,n=99;main(){for(i=0;i<n;n—){printf(“#”);}}

用时:

real 1m3.881s
user 0m44.097s
sys 0m17.436s

最让我吃惊的结果是那个溢出的,很巧妙,脚本运行到那里停了大约4,5秒钟的样子。

最后放脚本,包括两部分,一部分用bash完成,另一部分用Perl完成。其实完全用bash或者完全用Perl都是可行的,而且完全用Perl应该是最快的。

[bash]

!/bin/bash

TEST_VAR=’int i,n=99;main(){for(i=0;i<n;i—){printf("#");}}'

Generated by Python with

''.join(map(lambda x: '' if chr(x).isupper() else chr(x), range(32, 127)))

except '$','(',')', '{','}', '[', ']', '@', "`", """, "#", "'", "\", ' '

possible_chars='!'"%&*+,-./0123456789:;?^_abcdefghijklmnopqrstuvwxyz|~”
len=${#TEST_VAR}
num_chars=${#possible_chars}
tmpfile=$(mktemp /tmp/test-$$.XXXXXXX)
outfile=”/tmp/test_sh.out”

function is_valid_and_ok()
{
echo $1 > $tmpfile
if gcc -xc -c -o $outfile.o $tmpfile &>/dev/null;
then
gcc -o $outfile $outfile.o &>/dev/null
if [[ $? -ne 0 ]]; then
return 0
fi

    #nohup $outfile &gt; $resultfile 2&gt; /dev/null &amp;
    #sleep 1 &amp;&amp; killall $outfile 2&gt; /dev/null
    n=$(./get_run_result.pl $outfile)
    echo $n
    if [[ $n -eq 99 ]] || [[ $n -eq 100 ]] || [[ $n -eq 1 ]]
    then
        return 1
    fi
fi
return 0

}

main

i=8
while(($i $tmp” 1>&2
fi
i=$(($i+1))
done;

i=4
while (($i < $len - 14));
do
j=0
while(($j $tmp” 1>&2
fi
j=$(($j+1))
done
i=$(($i+1))
if (($i == 11)) ; then
i=17
fi
done;

i=0
while(($i<$len - 16));
do
j=0
while(($j $tmp” 1>&2
fi
j=$(($j+1))
done
i=$(($i+1))
if (($i == 11)) ; then
i=17
fi
done;
[/bash]
[perl]

!/usr/bin/perl -w

use strict;
use warnings;

my $n;
my $chars;

open(my $in_file, “$ARGV[0]|”) or exit 1;
$n = read($in_file, $chars, 101);
print “$nn”;
close $in_file;
[/perl]