Skip to content

Commit

Permalink
Publish spoilers for IOCCC 2020
Browse files Browse the repository at this point in the history
  • Loading branch information
mame committed Dec 31, 2021
1 parent cca056d commit 7fdbf08
Show file tree
Hide file tree
Showing 55 changed files with 2,224 additions and 0 deletions.
45 changes: 45 additions & 0 deletions 2020/burton.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
id: 2020/burton
year: 2020
order: 1
authors: "Dave_Burton"
orig_url: "https://www.ioccc.org/2020/burton/prog.c"
hint_url: "https://www.ioccc.org/2020/burton/index.html"
title: "IOCCC 2020: Best one-liner"
award_ja: "最高のワンライナー"
---

## 動作

2進数を表示する。

```
$ gcc -DB=6945503773712347754LL -DI=5859838231191962459LL -DT=0 -DS=7 -o prog prog.c
$ ./prog 128
10000000
$ ./prog 170
10101010
```

ビッグエンディアン用にコンパイルすることもできる。

```
$ gcc -DB=7091606191627001958LL -DI=6006468689561538903LL -DT=1 -DS=0 -o prog prog.c
$ ./prog 128
00000001
$ ./prog 170
01010101
```

引数は基本的に0から255。

## 解説

ワンライナーでループ無しで実現されている。
ビット演算によって`long long`型の上でASCIIの`'0'``'1'`を並べ、`printf("%.8s\n",(char*)&n)`で表示する。
デバッグ出力させながら観察すれば仕組みはわかると思う。
コンパイルオプションで定数を定義仕分けることでリトルエンディアン・ビッグエンディアンが切り替えられるあたりがおもしろい。
79 changes: 79 additions & 0 deletions 2020/carlini.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
id: 2020/carlini
year: 2020
order: 15
authors: "Nicholas Carlini"
orig_url: "https://www.ioccc.org/2020/carlini/prog.c"
hint_url: "https://www.ioccc.org/2020/carlini/index.html"
title: "IOCCC 2020: Best of show - abuse of libc"
award_ja: "最優秀賞 - libcの悪用"
---

### 動作

○×ゲーム。

```
$ gcc -o prog prog.c
$ ./prog
...(大量の空白やゴミ文字)...
| |
-----
| |
-----
| |
P1>
```

左上から各マスに1~9まで番号が振られている。
3を指定する例。

```
P1>3
...(大量の空白やゴミ文字)...
| |X
-----
| |
-----
| |
P2>
```

AIは搭載されていないので、同様に手入力していく。
不可能な手を打つか、勝敗が決定するか、全マスが埋まったら終了する。

```
O| |X
-----
|O|X
-----
| |X
P1 WINS
```

### 解説

`main`関数が`printf()`の繰り返しだけになっている。
マクロでごまかしているなどではなく、実際にこのようになっている。

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

ポイントは、`%n`というマイナーな`printf()`フォーマット指定子。
コード形状もそれを表現している。
これはポインタを引数に受け取り、`printf()`がここまでに書いた文字数をそのポインタに書き込む。
`%hhn`とすれば`char`型へのポインタとして扱ってくれるので、実質256の剰余も計算できる。
さらに`%2$hn`のような引数位置の指定もあわせることで、できることが増える。
hint.textには2進演算の考え方がわかりやすく書いてある。
もちろん、効率的に実行するにはそれ以上の工夫が必要となるとのこと。

なお、入力は`scanf()`で行っている。
最初は空文字列で`scanf()`することで何も読み込まず、2度目からは`printf()`によって`scanf()`のフォーマット文を有効にすることで、位置の入力を受け取るようになる。
65 changes: 65 additions & 0 deletions 2020/endoh1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
id: 2020/endoh1
year: 2020
order: 2
authors: "Yusuke_Endoh"
orig_url: "https://www.ioccc.org/2020/endoh1/prog.c"
hint_url: "https://www.ioccc.org/2020/endoh1/index.html"
title: "IOCCC 2020: Most explosive"
award_ja: "もっとも爆発的"
---

## 動作

半自動マインスイーパ。

```
$ gcc -o prog prog.c -lncurses
$ ./prog
```

{% include img.html src="2020-endoh1-1.png" desc="1クリックだけで広がった様子" %}

端末で起動し、マウスクリックすると普通のマインスイーパのようにマスを開いて機雷の有無を調べる。
数字が出たら、その周りの8セルのうちその数だけ機雷があるということを意味する。
`R`を押したら現在のゲームを捨てて新しいゲームを開始する。
`Q`で終了。

特徴は、簡単な推論でわかるところは自動的にやってくれてしまうところ。
上記の画面は、1クリックしただけで勝手に広がりきったところ。

初期配置を指定することもできる。

```
$ ./prog ioccc.txt
```

{% include img.html src="2020-endoh1-2.png" desc="機雷の配置を指定して実行した様子" %}

デモ動画。

{% include youtube.html src="3SLf94gqUy0" desc="作者によるデモ動画" %}

### 解説

マインスイーパをプレイするときは、ふつう、次の2種類のアクションとなる。

1. 機雷がなさそうなマスを第六感で選んでヒントを得る
2. ヒントをもとに機雷がないマスを特定していく

しかし、(2)の方は間違いやすく、時間の無駄。こういう作業は機械にやらせるべき。
ということで、局所的な推論で機雷の有無が決定するマスを自動的に特定していく機能を備えたマインスイーパ。

ふつうのマインスイーパでも0のマスを開いた場合は自動的に周りのマスを開いてくれるものが多い。
その推論をもうちょっと賢くしたとも言える。

次の4つのルールに基づいて自動的に推論する。

* 周囲のマスにすでに数字と同じ数だけフラグが立っていたら、他のマスをすべて開く。
* 周囲のマスにすでに数字と同じ数しか閉じマスがなかったら、それらにすべてフラグを立てる。
* 隣接する2つの数字に注目したとき、大きい方の数字の周囲にどのように機雷があるとしても、小さい方の数字の分をカバーしきってしまう場合、小さい方の数字の周囲マスのうち大きい方の数字と共有していないマスをすべて開く。
* 隣接する2つの数字に注目したとき、小さい方の数字の周囲にどのように機雷があるとしても、大きい方の数字の分の残りが他のマスと同じ数になってしまう場合、大きい方の数字の周囲マスのうち小さい方の数字と共有していないマスにすべてフラグを立てる。

言葉ではわかりにくいと思うが、hint.textに例付きで書かれているので参照されたい。
コード上ではこれらのルールを単一の規則にまとめて表現している。
66 changes: 66 additions & 0 deletions 2020/endoh2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
id: 2020/endoh2
year: 2020
order: 3
authors: "Yusuke_Endoh"
orig_url: "https://www.ioccc.org/2020/endoh2/prog.c"
hint_url: "https://www.ioccc.org/2020/endoh2/index.html"
title: "IOCCC 2020: Best perspective"
award_ja: "最高の展望"
---

### 動作

ROT13の結果を[スターウォーズのオープニング風](https://ja.wikipedia.org/wiki/%E3%80%8E%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%BB%E3%82%A6%E3%82%A9%E3%83%BC%E3%82%BA%E3%80%8F%E3%81%AE%E3%82%AA%E3%83%BC%E3%83%97%E3%83%8B%E3%83%B3%E3%82%B0%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%AB)に表示する。

```
$ cat hello.txt
URYYB
JBEYQ
NAQ
TNYNKL
$ gcc -o prog prog.c
$ ./prog hello.txt
```

```
I^ _^ I^^^^^ I I _I^^^_
_^^^^I^ _^^^^ I ^_ I_ ^I
^ ^ ^^^^^^ ^^^^ ^^^^^^ ^^^^
_^ _ _I _^^^^_ I^^^I_ I ^I^^^___
I^ _I^ _^ _I I I I ^I ^_ ^I
II_^_^_I _I _^ I^^^I^ I I ^_
_II^ II^ I _I I I I_ ^I ^_
_I^ I^ I_ __^ I ^I I ^I __^
^^ ^^^^^^^^ ^^^
```

デモ動画。

{% include youtube.html src="pwFQ6J2EHT0" desc="作者によるデモ動画" %}

### 解説

コード形状は"IOCCC 2020"をスターウォーズのロゴの雰囲気にしたもの。
大文字アルファベットの字形を、2次ベジエ曲線によって表現したものを埋め込んでいる。

`double complex`型によってベクトルを表現している([[[2012/endoh1]]]({{ site.baseurl }}{% link 2012/endoh1.md %})と同じネタ)。
59 changes: 59 additions & 0 deletions 2020/endoh3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
id: 2020/endoh3
year: 2020
order: 4
authors: "Yusuke_Endoh"
orig_url: "https://www.ioccc.org/2020/endoh3/prog.c"
hint_url: "https://www.ioccc.org/2020/endoh3/index.html"
title: "IOCCC 2020: Most head-turning"
award_ja: "もっとも振り向かせる"
---

### 動作

実行すると、散髪屋の時計(左右反転した時計)が表示される。

```
$ gcc -o prog prog.c
$ ./prog
#define/**/Q(x,y)char*/* */q=y#x","#y")",*p,s[x;}
/*IOCCC'20*/#include/* SI */<stdio.h>/*-Qlock-*/
int(y),x,i,k,r;Q(9/* I II */<<9];float(o)[03];
void(P)(){*o=r<0/* */?r:-r;o[1]=39.5;
o[2]=22.5;for(k/* */=0;++k<39;*o*=i
/6875.5/(k%2?k/* */:-k))y=o[1+k%2
]+=*o;k=o[2];/* S ,, ; OI */p=s+y+k/2*80;
}int(main)()/* '',, ; */{for(p=s;+i<
1839;*q>32?k/* ', ; */=i++/80-11,y
=(750>r*r+k/* '',, ; */*k*4)*4+y/2
,*p++=r<41?/* ',,; */y?"0X+0X+!"
[y-1]-1:+*q/* E ' e */++:10:*q++)
r=i%80-38;;/* */;for(x=13,r
=20;i=3600*/* */--x,i;*p++=
"OISEA2dC8e"/* */[x%10],*p+=x
/10*41)P();r/* */=10;;sscanf(
__TIME__,"%d"/* A 8 */":%d:%d",&k,&
x,&i);for(i+=(/* */k*60+x)*60;18+
r;*p=k%2?*p%2?+/* */59:44:*p>39?59:
39,i=!r--?i%3600/* 2 C */*12:i)P();puts(s
),"#define/**/Q(x"/* */",y)char*q=y#x\","
"\"#y\")\",*p,s[x;}"/* d */"/*IOCCC'20*/#inclu"
"de<stdio.h>/*-Qlock-"/* */"*/int(y),x,i,k,r;Q(")
```

この出力はQuineになっていて、保存してコンパイル・実行することでまた同様に時計になる。

デモ動画。

{% include youtube.html src="FmxcnXhvJlo" desc="作者によるデモ動画" %}

### 解説

動作がすべて。

賞名の"head-turning"は「人を振り向かせる」「耳目を集める」という表現だけれど、文字通り「頭を回転させる」という意味で使っている。

[prog.alt.c](https://www.ioccc.org/2020/endoh3/prog.alt.c)はUnicodeの文字を使って、鏡文字をもうちょっとそれっぽい字にする。

{% include img.html src="2020-endoh3.png" desc="prog.alt.cの実行結果" %}
61 changes: 61 additions & 0 deletions 2020/ferguson1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
id: 2020/ferguson1
year: 2020
order: 5
authors: "Cody_Ferguson"
orig_url: "https://www.ioccc.org/2020/ferguson1/prog.c"
hint_url: "https://www.ioccc.org/2020/ferguson1/index.html"
title: "IOCCC 2020: Don't tread on me award"
award_ja: "俺を踏みにじるな賞"
---

### 動作

[snake game](https://ja.wikipedia.org/wiki/%E3%83%98%E3%83%93%E3%82%B2%E3%83%BC%E3%83%A0)

{: .wrap }
```
$ gcc -D_XOPEN_SOURCE -D_POSIX_C_SOURCE -D'f(a,b)'='((a)<(b)?(a):(b))' -DWALL='COLOR_CYAN' -DHEAD='COLOR_RED' -DBODY='COLOR_GREEN' -DWB='COLOR_BLACK' -DHB='COLOR_BLACK' -DBS='COLOR_BLACK' -DBG='COLOR_WHITE' -DBB='COLOR_BLACK' -o prog prog.c -lcurses
$ ./prog
```

{% include img.html src="2020-ferguson1.png" desc="プレイ画面" %}

`<`が蛇の頭(向きによってキャラクタが変わる)。上下左右で移動、スペースでポーズと再開、<kbd>q</kbd>で終了。
`*`が虫で、これを餌として集める。

### 解説

環境変数でいろいろな設定が可能。

* `WALL=0`としたら、壁に当たると死ぬ(デフォルトではトーラスになっている)
* `CANNIBAL=0`としたら、自分自身に当たっても死ななくなる(デフォルトでは当然死ぬ)
* `SHED`だけ動くごとに`SHEDS`だけ胴体が伸びる
* 胴体の長さの初期値は`SIZE``MAXSIZE`まで伸びたら勝利(`SIZE=-1`とすれば即時に勝利)
* `WAIT`を小さくするとすべてが速くなる
* `EVADE`を小さくすると虫の位置が変わるスピードが速くなる

ドキュメントがとんでもなく長い。

```
$ wc *.markdown COMPILING HACKING HISTORY README
293 2657 14817 bugs.markdown
170 1067 6293 chocolate-cake.markdown
773 4555 34107 gameplay.markdown
52 150 1161 judges.markdown
773 4555 34107 remarks.markdown
890 7762 42421 spoilers.markdown
328 1955 11850 terminals.markdown
409 3027 16822 troubleshooting.markdown
595 4570 27663 COMPILING
515 3643 20407 HACKING
132 1543 8186 HISTORY
148 1385 7640 README
5078 36869 225474 total
```

コード形状は、遊んでいたらなんとなくできたパターンらしい。
全体の行数やブロックの行数が素数になっている。

賞名は、アメリカの昔の軍人[クリストファー・ガズデン](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AA%E3%82%B9%E3%83%88%E3%83%95%E3%82%A1%E3%83%BC%E3%83%BB%E3%82%AC%E3%82%BA%E3%83%87%E3%83%B3)がデザインしたアメリカ軍旗([ガズデン旗](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:Naval_jack_of_the_United_States_%281975%E2%80%931976%29.png))に基づく。
Loading

0 comments on commit 7fdbf08

Please sign in to comment.