habrahabr

Маленькие программки на С — победители конкурса IOCCC

  • среда, 28 мая 2025 г. в 00:00:16
https://habr.com/ru/companies/ruvds/articles/910418/


Международный конкурс запутанного кода на С (IOCCC) — известное соревнование по программированию, которое проводилось до 2020 года.

В отличие от традиционных чемпионатов по спортивному программированию, здесь не нужно решать задачи на скорость. У участников сколько угодно времени, но размер программы ограничен 1536 байтами (не считая пробелы, табы и прочие служебные символы), в сумме обычно получается не более 2 кб.

Но программки делают реально сложные вещи: например, победитель 2004 года — это операционная система, исходный код 166 строк.

Посмотрим на шедевры разных лет и откуда вообще взялся этот конкурс.

Критерием победы на IOCCC является не только минимальный размер, но и креативность обфускации, а установленные правила не высечены в камне: наоборот, «взлом правил — это традиция», как сказал автор конкурса Курт Нолл.

Программы зачастую использовали необычные трюки, иногда очень зрелищно. Например, в 2004 году номинацию «Лучшее надругательство над препроцессором С» присудили программе vik2, которая превращает препроцессор в 11-битное АЛУ.

Конкурсанты зачастую использовали недокументированные особенности компиляторов в нечётко прописанных местах стандарта С, что приводило к неожиданным результатам. К сожалению, в современных компиляторах такой код не компилируется или валит систему.

Обфускации включают оригинальное форматирование кода в форме ASCII-искусства, когда страница текста визуально напоминает какое-то изображение. Иногда встречался самомодифицирующийся код (СМК), при котором приложение создаёт или изменяет часть своего программного кода во время выполнения.

В правилах намеренно предусмотрены лазейки, которые можно найти и использовать. А на следующий год правила могли скорректировать, с учётом тех «взломов».

Детище Курта Нолла


История IOCCC берёт начало в 1984 году. Идея принадлежит двум системным программистам из компании National Semiconductor, которая занимается производством полупроводников. Это одна из отраслей, где используется встроенное ПО и действительно необходима оптимизация кода на ассемблере. Каждый байт критически важен.

В начале 80-х один из соорганизаторов конкурса Курт Нолл приобрёл известность в компьютерных и математических кругах, когда нашёл 25-е и 26-е простые числа Мерсенна $M_p$, это $(2^21701-1)2^21700$ и $(2^23209-1)2^23208$, соответственно. На то время это были самые большие простые числа, известные в математике, и два из семи мировых рекорда по простым числам, которые побил Нолл, попав в Книгу рекордов Гиннесса.

В реализации теста Люка — Лемера на проверку $M_p$ самым сложным этапом стало возведение в квадрат, которое Курт Нолл с коллегой реализовали следующим образом, из научной работы:



Курт Нолл портировал тест для суперкомпьютера CDC Cyber 174, произвёл вычисления и нашёл сразу два простых числа Мерсенна.


Консоль суперкомпьютера Cyber 70

Самые большие простые числа, по годам:



Благодаря такому организатору конкурс IOCCC со старта приобрёл авторитет, о нём написали тематические издания.

IOCCC проводился ежегодно с 1984 до 1996 года, потом с большими перерывами до 2020 года. По правилам, победителей определяет «анонимное жюри», хотя, не такое уж анонимное, ведь организатор конкурса всем известен. Каждый год для участников придумывают оригинальные смешные категории, например, «Максимальное злоупотребление препроцессором» или «Самое большое количество выдаваемых ошибок в процессе работы».

В последующие годы Курт Нолл ещё несколько раз отметился в научной и технической областях. В частности, как соавтор простой хэш-функции Фаулера−Нолла−Фо (FNV) и соавтор системы именования больших степеней 10 (с Джоном Конвеем, который, в свою очередь, известен изобретением игры «Жизнь»).

Фрагмент таблицы с английскими наименованиями первых 10 000 степеней 10:

Степень 10 (количество 0 после 1) Латинская степень
(количество 000 после 1)
Префикс (определяет буквы перед иллионом) Американская система с тире
109996 3332 3 1000 300 1 и 30 one tre-millia-trecen-un-trigin-tillion
109997 3332 3 1000 300 1 и 30 ten tre-millia-trecen-un-trigin-tillion
109998 3332 3 1000 300 1 и 30 one hundred tre-millia-trecen-un-trigin-tillion
109999 3333 3 1000 300 2 и 30 one tre-millia-trecen-do-trigin-tillion
1010000 3333 3 1000 300 2 и 30 ten tre-millia-trecen-do-trigin-tillion
Соавторам IOCCC идея конкурса пришла после того, как они обсудили явные примеры плохого кода того времени, который им приходилось исправлять, вроде командной оболочки sh из UNIX или глючной версии finger из 4BSD, об этом рассказывается в FAQ. Инженеры Курт Болл (Landon Curt Noll) Ларри Бассел (Larry Bassel) в то время работали над встроенной ОС GENIX для проприетарной системы NS SYS16 в своей компании National Semiconductor, вот и переписывали код.

Вот так и родилась идея конкурса для «максимально запутанного» кода, немного шуточная. Однако в итоге конкурс превратился в выставку шедевров программирования. Среди ярких победителей IOCCC можно выделить несколько выдающихся примеров.

Самый маленький куайн в мире


Куайн — компьютерная программа, которая выдаёт на выходе точную копию своего исходного текста, примерно как живое существо при размножении.

На конкурсе 1994 года был представлен самый маленький в мире куайн, побить рекорд которого принципиально невозможно, поскольку его размер 0 байт.

После того случая в правилах IOCCC прописали минимальный размер программы 1 байт.

Мини-ОС


О победителе 2004 года мы уже упоминали в начале статьи. Эту операционную систему можно загрузить с дискеты или в QEMU. Исходный код на C: 166 строк.

gavin.c
int main(int t, char **q, char **d) { return cain(t, (int)q, (int)d); }
#define G(n) int n(int t, int q, int d)
#define X(p,t,s) (p>=t&&p<(t+s)&&(p-(t)&1023)<(s&1023))
#define U(m) *((signed char *)(m))
#define F if(!--q){
#define I(s) (int)cain-(int)s
#define P(s,c,k) for(h=0; h>>14==0; h+=129)Y(16*c+h/1024+Y(V+36))&128>>(h&7)?U(s+(h&15367))=k:k

G (B)
{
  Z;
  F D = E (Y (V), C = E (Y (V), Y (t + 4) + 3, 4, 0), 2, 0);
  Y (t + 12) = Y (t + 20) = i;
  Y (t + 24) = 1;
  Y (t + 28) = t;
  Y (t + 16) = 442890;
  Y (t + 28) = d = E (Y (V), s = D * 8 + 1664, 1, 0);
  for (p = 0; j < s; j++, p++)
    U (d + j) = i == D | j < p ? p--, 0 : (n = U (C + 512 + i++)) < ' ' ? p |=
      n * 56 - 497, 0 : n;
}

n = Y (Y (t + 4)) & 1;
F
U (Y (t + 28) + 1536) |=
62 & -n;
M
U (d + D) =
X (D, Y (t + 12) + 26628, 412162) ? X (D, Y (t + 12) + 27653,
				       410112) ? 31 : 0 : U (d + D);
for (; j < 12800; j += 8)
  P (d + 27653 + Y (t + 12) + ' ' * (j & ~511) + j % 512,
     U (Y (t + 28) + j / 8 + 64 * Y (t + 20)), 0);
}

F if (n)
  {
    D = Y (t + 28);
    if (d - 10)
      U (++Y (t + 24) + D + 1535) = d;
    else
      {
	for (i = D; i < D + 1600; i++)
	  U (i) = U (i + 64);
	Y (t + 24) = 1;
	E (Y (V), i - 127, 3, 0);
      }
  }
else
  Y (t + 20) += ((d >> 4) ^ (d >> 5)) - 3;
}
}

G (_);
G (o);
G (cain)
{
  Z, k = K;
  if (!t)
    {
      Y (V) = V + 208 - (I (_));
      L (209, 223) L (168, 0) L (212, 244) _((int) &s, 3, 0);
      for (; 1;)
	R n = Y (V - 12);
      if (C & ' ')
	{
	  k++;
	  k %= 3;
	  if (k < 2)
	    {
	      Y (j) -= p;
	      Y (j) += p += U (&D) * (1 - k * 1025);
	      if (k)
		goto y;
	    }
	  else
	    {
	      for (C = V - 20;
		   !i && D & 1 && n
		   && (X (p, Y (n + 12), Y (n + 16)) ? j = n + 12, Y (C + 8) =
		       Y (n + 8), Y (n + 8) = Y (V - 12), Y (V - 12) =
		       n, 0 : n); C = n, n = Y (n + 8));
	      i = D & 1;
	      j &= -i;
	    }
	}
      else if (128 & ~D)
	{
	  E (Y (n), n, 3, U (V + D % 64 + 131) ^ 32);
	  n = Y (V - 12);
	y:C = 1 << 24;
	  M U (C + D) = 125;
	  o (n, 0, C);
	  P (C + p - 8196, 88, 0);
	  M U (Y (0x11028) + D) = U (C + D);
	}
    }
}

for (D = 720; D > -3888; D--)
  putchar (D >
	   0 ?
	   "  )!\320\234\360\256\370\256 0\230F           .,mnbvcxz    ;lkjhgfdsa \n][poiuytrewq  =-0987654321   \357\262   \337\337 \357\272   \337\337         ( )\"\343\312F\320!/ !\230 26!/\16 K>!/\16\332 \4\16\251\0160\355&\2271\20\2300\355`x{0\355\347\2560 \237qpa%\231o!\230 \337\337\337     ,               )\"K\240   \343\316qrpxzy\0 sRDh\16\313\212u\343\314qrzy    !0( "
	   [D] ^ 32 : Y (I (D)));
return 0;
}

G (o)
{
  Z;
  if (t)
    {
      C = Y (t + 12);
      j = Y (t + 16);
      o (Y (t + 8), 0, d);
      M U (d + D) =
	X (D, C, j) ? X (D, C + 1025, j - 2050) ? X (D, C + 2050,
						     j - 3075) ? X (D,
								    C + 2050,
								    j -
								    4100) ?
	X (D, C + 4100,
	   ((j & 1023) + 18424)) ? 176 : 24 : 20 : 28 : 0 : U (d + D);
      for (n = Y (t + 4); U (i + n); i++)
	P (d + Y (t + 12) + 5126 + i * 8, U (n + i), 31);
      E (Y (t), t, 2, d);
    }
}

G (_)
{
  Z = Y (V + 24);
  F Y (V - 16) += t;
  D = Y (V - 16) - t;
}

F for (i = 124; i < 135; i++)
  D = D << 3 | Y (t + i) & 7;
}

if (q > 0)
  {
    for (; n = U (D + i); i++)
      if (n - U (t + i))
	{
	  D += _(D, 2, 0) + 1023 & ~511;
	  i = ~0;
	}
    F if (Y (D))
      {
	n = _(164, 1, 0);
	Y (n + 8) = Y (V - 12);
	Y (V - 12) = n;
	Y (n + 4) = i = n + 64;
	for (; j < 96; j++)
	  Y (i + j) = Y (t + j);
	i = D + 512;
	j = i + Y (i + 32);
	for (; Y (j + 12) != Y (i + 24); j += 40);
	E (Y (n) = Y (j + 16) + i, n, 1, 0);
      }
  }
}

return D;
}

Авиасимулятор


Победитель IOCCC 1998 года — настоящий авиасимулятор, в котором можно полетать по ландшафту на основе реальных карт местности. Код программы из 58 строк представляет ASCII-изображение самолёта:

#include                                     <math.h>
#include                                   <sys/time.h>
#include                                   <X11/Xlib.h>
#include                                  <X11/keysym.h>
                                          double L ,o ,P
                                         ,_=dt,T,Z,D=1,d,
                                         s[999],E,h= 8,I,
                                         J,K,w[999],M,m,O
                                        ,n[999],j=33e-3,i=
                                        1E3,r,t, u,v ,W,S=
                                        74.5,l=221,X=7.26,
                                        a,B,A=32.2,c, F,H;
                                        int N,q, C, y,p,U;
                                       Window z; char f[52]
                                    ; GC k; main(){ Display*e=
 XOpenDisplay( 0); z=RootWindow(e,0); for (XSetForeground(e,k=XCreateGC (e,z,0,0),BlackPixel(e,0))
; scanf("%lf%lf%lf",y +n,w+y, y+s)+1; y ++); XSelectInput(e,z= XCreateSimpleWindow(e,z,0,0,400,400,
0,0,WhitePixel(e,0) ),KeyPressMask); for(XMapWindow(e,z); ; T=sin(O)){ struct timeval G={ 0,dt*1e6}
; K= cos(j); N=1e4; M+= H*_; Z=D*K; F+=_*P; r=E*K; W=cos( O); m=K*W; H=K*T; O+=D*_*F/ K+d/K*E*_; B=
sin(j); a=B*T*D-E*W; XClearWindow(e,z); t=T*E+ D*B*W; j+=d*_*D-_*F*E; P=W*E*B-T*D; for (o+=(I=D*W+E
*T*B,E*d/K *B+v+B/K*F*D)*_; p<y; ){ T=p[s]+i; E=c-p[w]; D=n[p]-L; K=D*m-B*T-H*E; if(p [n]+w[ p]+p[s
]== 0|K <fabs(W=T*r-I*E +D*P) |fabs(D=t *D+Z *T-a *E)> K)N=1e4; else{ q=W/K *4E2+2e2; C= 2E2+4e2/ K
 *D; N-1E4&& XDrawLine(e ,z,k,N ,U,q,C); N=q; U=C; } ++p; } L+=_* (X*t +P*M+m*l); T=X*X+ l*l+M *M;
  XDrawString(e,z,k ,20,380,f,17); D=v/l*15; i+=(B *l-M*r -X*Z)*_; for(; XPending(e); u *=CS!=N){
                                   XEvent z; XNextEvent(e ,&z);
                                       ++*((N=XLookupKeysym
                                         (&z.xkey,0))-IT?
                                         N-LT? UP-N?& E:&
                                         J:& u: &h); --*(
                                         DN -N? N-DT ?N==
                                         RT?&u: & W:&h:&J
                                          ); } m=15*F/l;
                                          c+=(I=M/ l,l*H
                                          +I*M+a*X)*_; H
                                          =A*r+v*X-F*l+(
                                          E=.1+X*4.9/l,t
                                          =T*m/32-I*T/24
                                           )/S; K=F*M+(
                                           h* 1e4/l-(T+
                                           E*5*T*E)/3e2
                                           )/S-X*d-B*A;
                                           a=2.63 /l*d;
                                           X+=( d*l-T/S
                                            *(.19*E +a
                                            *.64+J/1e3
                                            )-M* v +A*
                                            Z)*_; l +=
                                            K *_; W=d;
                                            sprintf(f,
                                            "%5d  %3d"
                                            "%7d",p =l
                                           /1.7,(C=9E3+
                              O*57.3)%0550,(int)i); d+=T*(.45-14/l*
                             X-a*130-J* .14)*_/125e2+F*_*v; P=(T*(47
                             *I-m* 52+E*94 *D-t*.38+u*.21*E) /1e2+W*
                             179*v)/2312; select(p=0,0,0,0,&G); v-=(
                              W*F-T*(.63*m-I*.086+m*E*19-D*25-.11*u
                               )/107e2)*_; D=cos(o); E=sin(o); } }




Наношахматы и эмулятор Intel 8080


Nanochess (1255 символов) — самые маленькие в мире шахматы на C. Это первая из программ Оскара Толедо, пятикратного победителя IOCCC.

Исходный код на С
B,i,y,u,b,I[411],*G=I,x=10,z=15,M=1e4;X(w,c,h,e,S,s){int t,o,L,E,d,O=e,N=-M*M,K
=78-h<<x,p,*g,n,*m,A,q,r,C,J,a=y?-x:x;y^=8;G++;d=w||s&&s>=h&&v 0,0)>M;do{_ o=I[
p=O]){q=o&z^y _ q<7){A=q--&2?8:4;C=o-9&z?q["& .$  "]:42;do{r=I[p+=C[l]-64]_!w|p
==w){g=q|p+a-S?0:I+S _!r&(q|A<3||g)||(r+1&z^y)>9&&q|A>2){_ m=!(r-2&7))P G[1]=O,
K;J=n=o&z;E=I[p-a]&z;t=q|E-7?n:(n+=2,6^y);Z n<=t){L=r?l[r&7]*9-189-h-q:0 _ s)L
+=(1-q?l[p/x+5]-l[O/x+5]+l[p%x+6]*-~!q-l[O%x+6]+o/16*8:!!m*9)+(q?0:!(I[p-1]^n)+
!(I[p+1]^n)+l[n&7]*9-386+!!g*99+(A<2))+!(E^y^9)_ s>h||1<s&s==h&&L>z|d){p[I]=n,O
[I]=m?*g=*m,*m=0:g?*g=0:0;L-=X(s>h|d?0:p,L-N,h+1,G[1],J=q|A>1?0:p,s)_!(h||s-1|B
-O|i-n|p-b|L<-M))P y^=8,u=J;J=q-1|A<7||m||!s|d|r|o<z||v 0,0)>M;O[I]=o;p[I]=r;m?
*m=*g,*g=0:g?*g=9^y:0;}_ L>N){*G=O _ s>1){_ h&&c-L<0)P L _!h)i=n,B=O,b=p;}N=L;}
n+=J||(g=I+p,m=p<O?g-3:g+2,*m<z|m[O-p]||I[p+=p-O]);}}}}Z!r&q>2||(p=O,q|A>2|o>z&
!r&&++C*--A));}}}Z++O>98?O=20:e-O);P N+M*M&&N>-K+1924|d?N:0;}main(){Z++B<121)*G
++=B/x%x<2|B%x<2?7:B/x&4?0:*l++&31;Z B=19){Z B++<99)putchar(B%x?l[B[I]|16]:x)_
x-(B=F)){i=I[B+=(x-F)*x]&z;b=F;b+=(x-F)*x;Z x-(*G=F))i=*G^8^y;}else v u,5);v u,
1);}}

Наношахматы — полноценный шахматный движок, с которым можно поиграть. Программа взяла номинацию «Лучшая игра» на IOCCC 2005 года. Потом Толедо ещё участвовал в конкурсах 2006 и 2011 гг., причём в 2006 году с эмулятором 8080 стал абсолютным победителем.

Эмулятор размером 59 строк (плюс несколько вспомогательных файлов с образами памяти и др.) полностью эмулирует процессор Intel 8080, телетайп и дисковый контроллер, как в начале революции ПК, это примерно 1975-й год.

                               #include <stdio.h>
                               #include <stdlib.h>
                               #include <unistd.h>
           #define n(o,p,e)=y=(z=a(e)%16 p x%16 p o,a(e)p x p o),h(
                                #define s 6[o]
             #define p z=l[d(9)]|l[d(9)+1]<<8,1<(9[o]+=2)||++8[o]
                                #define Q a(7)
           #define w 254>(9[o]-=2)||--8[o],l[d(9)]=z,l[1+d(9)]=z>>8
                               #define O )):((
                  #define b (y&1?~s:s)>>"\6\0\2\7"[y/2]&1?0:(
                               #define S )?(z-=
                    #define a(f)*((7&f)-6?&o[f&7]:&l[d(5)])
                               #define C S 5 S 3
                       #define D(E)x/8!=16+E&198+E*8!=x?
                             #define B(C)fclose((C))
                       #define q (c+=2,0[c-2]|1[c-2]<<8)
                          #define m x=64&x?*c++:a(x),
                         #define A(F)=fopen((F),"rb+")
                    unsigned char o[10],l[78114],*c=l,*k=l
                          #define d(e)o[e]+256*o[e-1]
#define h(l)s=l>>8&1|128&y|!(y&255)*64|16&z|2,y^=y>>4,y^=y<<2,y^=~y>>1,s|=y&4
+64506; FILE *u, *v, *e, *V; int x,y,z,Z; main(r,U)char**U;{

     { { { } } }       { { { } } }       { { { } } }       { { { } } }
    { { {   } } }     { { {   } } }     { { {   } } }     { { {   } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
    { { {   } } }    { { {     } } }    { { {   } } }    { { {     } } }
      { { ; } }      { { {     } } }      { { ; } }      { { {     } } }
    { { {   } } }    { { {     } } }    { { {   } } }    { { {     } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
   { { {     } } }   { { {     } } }   { { {     } } }   { { {     } } }
    { { {   } } }     { { {   } } }     { { {   } } }     { { {   } } }
     { { { } } }       { { { } } }       { { { } } }       { { { } } }

                                   for(v A((u A((e A((r-2?0:(V A(1[U])),"C")
),system("stty raw -echo min 0"),fread(l,78114,1,e),B(e),"B")),"A")); 118-(x
=*c++); (y=x/8%8,z=(x&199)-4 S 1 S 1 S 186 S 2 S 2 S 3 S 0,r=(y>5)*2+y,z=(x&
207)-1 S 2 S 6 S 2 S 182 S 4)?D(0)D(1)D(2)D(3)D(4)D(5)D(6)D(7)(z=x-2 C C C C
C C C C+129 S 6 S 4 S 6 S 8 S 8 S 6 S 2 S 2 S 12)?x/64-1?((0 O a(y)=a(x) O 9
[o]=a(5),8[o]=a(4) O 237==*c++?((int (*)())(2-*c++?fwrite:fread))(l+*k+1[k]*
256,128,1,(fseek(e=5[k]-1?u:v,((3[k]|4[k]<<8)<<7|2[k])<<7,Q=0),e)):0 O y=a(5
),z=a(4),a(5)=a(3),a(4)=a(2),a(3)=y,a(2)=z O c=l+d(5) O y=l[x=d(9)],z=l[++x]
,x[l]=a(4),l[--x]=a(5),a(5)=y,a(4)=z O 2-*c?Z||read(0,&Z,1),1&*c++?Q=Z,Z=0:(
Q=!!Z):(c++,Q=r=V?fgetc(V):-1,s=s&~1|r<0) O++c,write(1,&7[o],1) O z=c+2-l,w,
c=l+q O p,c=l+z O c=l+q O s^=1 O Q=q[l] O s|=1 O q[l]=Q O Q=~Q O a(5)=l[x=q]
,a(4)=l[++x] O s|=s&16|9<Q%16?Q+=6,16:0,z=s|=1&s|Q>159?Q+=96,1:0,y=Q,h(s<<8)
O l[x=q]=a(5),l[++x]=a(4) O x=Q%2,Q=Q/2+s%2*128,s=s&~1|x O Q=l[d(3)]O x=Q  /
128,Q=Q*2+s%2,s=s&~1|x O l[d(3)]=Q O s=s&~1|1&Q,Q=Q/2|Q<<7 O Q=l[d(1)]O s=~1
&s|Q>>7,Q=Q*2|Q>>7 O l[d(1)]=Q O m y n(0,-,7)y) O m z=0,y=Q|=x,h(y) O m z=0,
y=Q^=x,h(y) O m z=Q*2|2*x,y=Q&=x,h(y) O m Q n(s%2,-,7)y) O m Q n(0,-,7)y)  O
m Q n(s%2,+,7)y) O m Q n(0,+,7)y) O z=r-8?d(r+1):s|Q<<8,w O p,r-8?o[r+1]=z,r
[o]=z>>8:(s=~40&z|2,Q=z>>8) O r[o]--||--o[r-1]O a(5)=z=a(5)+r[o],a(4)=z=a(4)
+o[r-1]+z/256,s=~1&s|z>>8 O ++o[r+1]||r[o]++O o[r+1]=*c++,r[o]=*c++O z=c-l,w
,c=y*8+l O x=q,b z=c-l,w,c=l+x) O x=q,b c=l+x) O b p,c=l+z) O a(y)=*c++O r=y
,x=0,a(r)n(1,-,y)s<<8) O r=y,x=0,a(r)n(1,+,y)s<<8))));
system("stty cooked echo"); B((B((V?B(V):0,u)),v)); }

Можно почувствовать себя в 1975 году и программировать на общедоступном языке Palo Alto Tiny BASIC, который был опубликован в самом первом томе компьютерного журнала Dr. Dobb's Journal. Тот начал выходить в 1976 году и сыграл важную роль в образовании будущих программистов. Вот примеры программ, которую можно набрать в эмуляторе и запустить:

    10 FOR A=1 TO 10
    20 PRINT A
    30 NEXT A
    LIST
    RUN

    10 INPUT A
    20 INPUT B
    30 PRINT A+B
    LIST
    RUN

Последний конкурс IOCCC прошёл в 2020 году. На нём выиграла игра в крестики-нолики от Николаса Карлини с примечанием «абьюз libc». Вся программа состоит из одного итерированного вызова printf(3):

    int main() {
        while(*d) printf(fmt, arg);
    }

Список всех победителей IOCCC за 1094−2020 гг..

Почему конкурс закрылся


К сожалению, в наше время задачи минимизации кода уже неактуальны. Мощности современного железа хватает, чтобы запускать любой софт, даже не оптимизированный. Вместо рефакторинга проще увеличить системные требования — а пользователи купят новое железо и больше памяти. Такой потребительский подход работает уже несколько десятилетий, от него выигрывают все: из-за необходимости постоянного апгрейда потребители вливают в отрасль миллиарды долларов инвестиций — деньги идут на непрерывный R&D, уменьшается техпроцесс производства микросхем, выпускаются новые модели процессоров, ноутбуков, смартфонов и т. д.

Никому не выгодно, чтобы потребитель всю жизнь сидел на одном ПК: бурный рост отрасли затихнет, новых заводов станет меньше, а многих программистов уволят за ненадобностью, потому что старый софт работает десятилетиями.

Вот и конкурс IOCCC стал не очень актуальным, как и вся демосцена. Современные пользователи просто не понимают, в чём гениальность уместить полноценную программу в два килобайта. В чём вообще смысл, если в реальной жизни ограничения на память не существует.

В общем, оптимизация более не актуальна. Как выразился Джон Кармак, «многие смогли бы работать на устаревшем железе, если бы оптимизация ПО была приоритетом». Но в эпоху потребления это не так.

Есть вероятность, что IOCCC ещё возродится. В его истории уже был пропуск с 2006 по 2011 гг., то есть четыре года без конкурса. И организатор Курт Нолл недавно вышел на пенсию, занимается любительской астрономией, фотографирует коктейли в инстаграме* и артефакты из путешествий (на КДПВ и ниже: снимки из экспедиции в Антарктиду).



То есть у него вполне есть время возродить мероприятие, если программирование ещё не надоело.

*Instagram принадлежит Meta, запрещена в России.

© 2025 ООО «МТ ФИНАНС»

Telegram-канал со скидками, розыгрышами призов и новостями IT 💻