2019年Best one-liner:http://ioccc.org/2019/burton/hint.html
这个程序只有一行:
e,n,j,o,y;main(){for(++o;n=-~getchar();e+=11==n,y++)o=n>0xe^012>n&&'`'^n^65?!n:!o?++j:o;printf("%8d%8d%8dn",e^n,j+=!o&&y,y);}
功能就是统计一个文件里的行数、单词数、字母数。
加上换行格式化后是这样的:
e, n, j, o, y;
main()
{
for (++o; n = -~getchar(); e += 11 == n, y++)
o = n > 0xe ^ 012 > n && '`' ^ n ^ 65 ? !n : !o ? ++j : o;
printf("%8d%8d%8dn", e ^ n, j += !o && y, y);
}
编译指令:
WARN="-Wno-implicit-int -Wno-missing-variable-declarations -Wno-parentheses"
clang -Wall -Wextra -Weverything -pedantic $WARN -include stdio.h -o prog prog.c
这块儿我也不熟,但看字面意思应该就是说把默认的变量设为int,然后加上stdio.h
然后就是代码说明了:
先看循环条件:
n=-~getchar()//getchar函数不断读取字符,到结尾后返回EOF(-1),而-~(-1) =0;所以就可以跳出循环
e += 11 == n, y++//e:行数统计 遇到换行符+1 y:字符统计 直接+1
可以看到行数信息和字符数信息很容易就实现了。
然后就是for中的循环语句,嵌套了两次三元运算符,主要功能就是统计单词个数。
![6c016d7ec8d8ccfaaceeb669fc51e2fe.png](https://i-blog.csdnimg.cn/blog_migrate/ac3a5b4ddc976cd4b6b262c82cbd41f8.png)
逻辑是这样的:
如果当前字符为空格(或者换行,水平定位,垂直定位,换页等)等分割字符,且前一个字符不是分割字符,那么单词数加1.
o这个变量这里就是用来记录前一个是否是特殊字符的。
具体解释:
(n > 0xe) ^ (012 > n)://输入字符为ascii中的9 到13时为假 其余为真
//即水平定位、换行、垂直定位、换页、归位;在ascii表中正好是连在一起的
'`' ^ n ^ 65//输入为空格时为假
所以 n > 0xe ^ 012 > n && '`' ^ n ^ 65合起来就是分割字符时为假,其余为真
!n//恒等于0;用来迷惑人的
连起来就是说,
- 所以如果当前字符是正常字符,就把o标记为0;
- 如果当前字符是分割字符,
- 且当前的o=0(表示前一个字符不是分割字符),那么单词数加一,o的值变为非0(这里是把j的值赋给了o)
- 否则o的值不变
最后一行就是打印了,循环退出的时候n=0;所以e^n就是e;
j += !o && y这个里面的y也是一定大于0的,只是用来混淆的。