Хотя у меня пока, учитывая возраст блога, есть некоторое ощущение «разговора с пустотой», все же я не могу не поздравить всех немногочисленных моих посетителей с 0×100-ым днем в году. Это тот самый день когда нужно или не работать совсем, или сворачивать горы. У меня получилось второе: напланировал кучу дел, приехал на работу и через полтора часа уже все сделал. Остается только пожелать всем побольше таких ошибок в планировании. Или это все же сакральное влияние даты?
О серьезных вещах сегодня писать — кощунство, поэтому буду писать о полусерьезных.
В далекие-далекие годы, когда еще только-только стали появляться компьютеры на полупроводниках, а в лесах можно было встретить динозавров, появился UNIX. Дорог он нам не только фактом своего существования, но главным образом сложившейся вокруг него культурой. Ну, знаете, там были такие волосатые очкарики, которые все свое время просиживали за терминалом (при наличии такового), пили колу и разговаривали друг с другом на языке инопланетян. Эти ненормальные идентифицировали себя «хакерами», все время писали какой-то код и ни во что не ставили интеллектуальную собственность. Кстати, все ли знают, что UNIX изначально создавался Томпсоном как средство запуска игры Space Travel на компьютере PDP-7?
Но нужно отдать должное этим нечесаным парням: в их развлечениях родилось много полезных штук, и, в частности, язык Си. Создали его изначально не для развлечений (хотя кто-то пытается это опровергать), а для тотального переписывания Юникса. Но хакеров ведь хлебом не корми — дай любую попавшую в руки сущность разобрать, понять как работает, перекроить и раздать друзьям. Поэтому, учитывая специфику C, нетрудно было догадаться, что мерилом профессионализма, наряду с длиной волос и диоптриями близорукости, станет способность написать самую необычную, изящную, умопомрачительную и непонятную простым смертным программу. Например, такую:
typedef struct n{int a:3,
b:29;struct n*c;}t;t*
f();r(){}m(u)t*u;{t*w,*z;
z=u->c,q(z),u->b=z->b*10,
w=u->c=f(),w->a=1,w->c=z->
c;}t*k;g(u)t*u;{t*z,*v,*p,
*x;z=u->c,q(z),u->b=z->b,v
=z->c,z->a=2,x=z->c=f(),x
->a=3,x->b=2,p=x->c=f(),p
->c=f(),p->c->a=1,p->c->c=
v;}int i;h(u)t*u;{t*z,*v,*
w;int c,e;z=u->c,v=z->c,q(
v),c=u->b,e=v->b,u->b=z->b
,z->a=3,z->b=c+1,e+9>=c&&(
q(z),e=z->b,u->b+=e/c,w=f(
),w->b=e%c,w->c=z->c,u->c=
w);}int(*y[4])()={r,m,g,h};
char *sbrk();main(){t*e,*p,*o;
o=f(),o->c=o,o->b=1,e=f(),
e->a=2,p=e->c=f(),p->b=2,
p->c=o,q(e),e=e->c,(void)write
(1,"2.",2);for(;;e=e->c){q(e),
e->b=write(1,&e->b["0123456789"],
1);}}t*f(){return i||(i=1000,
k=(t*)sbrk(i*sizeof(t))),k+--i;
}q(p)t*p;{(*y[p->a])(p);}
Эта программа, например, вычисляет и выводит на stdout значение числа e с неограниченной точностью (точнее, ограниченной размером стека или терпением пользователя). Понятно, что нанимателям таких программистов очень не нравился подобный стиль. История умалчивает, сколько хакеров было уволено, пока, наконец, в 1984 году не был организован IOCCC, или, по-нашенски, Международный Конкурс На Самую Запутанную Программу На C. Это было настоящей отдушиной для недосамовыраженных профессионалов, и работодатели снова могли спать спокойно.
Среди победителей IOCCC оказалось немало известных в компьютерном мире людей. Например, Дэвид Корн (создатель оболочки ksh) в 1987 году стал одним из победителей с такой программой:
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
Основная интрига в том, что должно появиться на экране. Ничего сложно здесь нет, если помнить о том, что следующие две строки с точки зрения C идентичны:
Плюс еще нужно знать, что unix — предопределенный символ, эквивалентный 1, если использовать gcc. В этом можно убедиться с помощью следующей команды:
$ touch foo.h; cpp -dM foo.h
...
#define unix 1
...
Если сложить два и два, получится, что программа выводит строку «unix».
Одна из моих любимых программ-чемпионов, написанная Марком Биггаром, выглядит так:
Вот оно, настоящее Дао! Эта программа, в отличие от всех остальных победителей, умеет делать все. Ее нужно просто правильно скомпилировать. Например, можно заставить ее вывести «Hello, world»:
$ cc -DP="main() { printf(\"Hello, world\\n\"); }" -o beggar beggar.c
$ ./beggar
Hello, world
Нетрудно придумать, как научить программу делать и любые другие действия.
Кстати, на этом же соревновании засветился и Ларри Уолл, написавший некую линвистическую чуду-юду. Теперь понятно, откуда у Perl ноги растут. Оказывается, Уолл просто сделал язык, на котором непонятные программы писать гораздо проще, чем на C.
Пожалуй, на этом праздничный пост пора завершать. На досуге можете посмотреть исходники других победителей IOCCC, гарантированно получите массу удовольствия.




(4 голосов, средний: 4,50 из 5)
Loading ...