C, –110 자
이 버전의 프로그램은 선형 런타임 알고리즘을 사용하여 시퀀스를 생성합니다. 프로그램에서 402 문자에서 512를 빼면 총 음수가 110이됩니다.
#define C v=calloc(7,8),v->p=p
#define G(F,K)u->F[d[K]]
#define S(F,T)G(f,T)=F,G(t,T)=T,G(n,T)=
struct{int p,f[2],t[2];void*n[2];}r,*u,*v,*w;char*d,c;p,b,h,i,j,k;
main(s){for(;d=++p-s?d:realloc(d,s*=2);){d[i=p]=b;c+=c+b;p%8||putchar(c);
for(u=&r;b=u->p,u->p=p,w=G(n,k=i);S(i,k)v=G(n,k),u=v)for(h=G(f,k),j=G(t,k);j>h;--i,--j)
if(d[i]-d[j]){S(i,k)C;u=v;S(h,j)w;S(0,i)C;b=w->p;goto x;}S(0,i)C;x:b=1-d[b+1];}}
문제에 따라 프로그램은 무한 루프로 실행되므로 많은 메모리 할당이 필요 realloc()
하며 시퀀스를 연속적으로 유지하는 데 사용하면 힙 조각화가 발생할 수 있습니다. calloc(7,8)
첫 줄을 로 바꾸면 프로그램의 메모리 사용량을 향상시킬 수 있습니다 calloc(1,sizeof*v)
. 이것은 특히 32 비트 시스템에서 도움이 될 것입니다. 56 비트는 2 배가 될 수 있습니다.
코드는 읽을 수없고 재미있는 방식이 아닙니다. 그 점에 대해 사과드립니다. 솔직히 말하면, ungolfed 버전조차도 너무 명확하지 않습니다.
#include <stdio.h>
#include <stdlib.h>
typedef struct branch branch;
typedef struct node node;
struct branch {
int from, to;
node *next;
};
struct node {
int pos;
branch br[2];
};
static node root = { 0 };
static unsigned char *data = NULL;
static int endpos = 0;
static int size = 1;
static node *mknode(void)
{
node *n;
n = calloc(1, sizeof *n);
n->pos = endpos;
return n;
}
static branch *getbranch(node *n, int p)
{
return &n->br[data[p]];
}
static void setbranch(node *n, int from, int to, node *next)
{
n->br[data[to]].next = next;
n->br[data[to]].from = from;
n->br[data[to]].to = to;
}
int main(void)
{
node *u, *v, *w;
int follower, from, i, i0, j;
int out, b;
out = b = 0;
for (;;) {
++endpos;
if (endpos == size) {
size *= 2;
data = realloc(data, size);
}
data[endpos] = b;
out = (out << 1) | b;
if (endpos % 8 == 0) {
putchar(out);
out = 0;
}
i = endpos;
u = &root;
for (;;) {
follower = u->pos + 1;
u->pos = endpos;
w = getbranch(u, i)->next;
if (!w)
break;
i0 = i;
from = getbranch(u, i0)->from;
for (j = getbranch(u, i0)->to ; j > from ; --j) {
if (data[i] != data[j]) {
/* divide branch */
v = mknode();
setbranch(u, i, i0, v);
u = v;
setbranch(u, from, j, w);
setbranch(u, 0, i, mknode());
follower = w->pos + 1;
goto bitfound;
}
--i;
}
v = getbranch(u, i0)->next;
setbranch(u, i, i0, v);
u = v;
}
/* extend branch */
setbranch(u, 0, i, mknode());
bitfound:
b = 1 - data[follower];
}
}
(위의 ungolfed 코드는 문제 설명 및 Soltys 홈페이지 에서 참조한 Grzegorz Herman 및 Michael Soltys가 작성한 코드를 기반으로합니다 .)
초기 버전의 버그를보고 해 주신 @schnaader 및 @res에게 감사드립니다.