Anarchy Golf 954. Connect Digits
公開直後に縮まなくなるまでやってそのまま忘れていたら、提出した全ての言語で最下位になっていました。悲しい。
brainfuck
http://golf.shinh.org/reveal.rb?Connect+Digits/kimiyuki_1465065337
私 74byte
#!/usr/bin/env bfi
,.<,+[
*b&1 a
-<+>>
0 1 b *a 0
[>+<-<[-<<]<[+<<]>>>>]
a~b&1 b~a *0 a
+
<[>[-]>+.<<-]
<-[>>[-]>-.<<<-]
>>[>.<-]
,+
*c&1 b
]
$(b, a)$引き算して$((a\dot{-}b)+1, b\dot{-}a, 0, a)$のようにして、$a$を$b$に変化させながら出力。
mitchsさん 56byte
http://golf.shinh.org/reveal.rb?Connect+Digits/mitchs_1464799809
,+[-
a a&1 0 *b
[
>+>++[-<<]<
a a\k 0 *b\k k k
[+.<<]>>[>>]>
]
a a&1\b 0 *0 b b
<<[-[-[<-.>-]]]
>>>.>+>>
b 0 0 0 b b&1 0 *0
,+]
同様に引き算(limited subtraction)をするのだが、引きすぎる場合は引きながら出力している。たしかにどうせ引く対象が$0$かどうかで場合分けが入っているので、出力はそこに吸収させられる。賢い。
sed
私 108byte
http://golf.shinh.org/reveal.rb?Connect+Digits/kimiyuki_1464772487
s/^/I/
:
s/I\(.\)\(.\)/\1<0123456789 9876543210>\2/
s/\(.\)<.*\1\(\w*\)\(.\).*>\3/\1\2I\3/
s/<.*>/I/
t
s/I//
前から指示子Iで1文字ずつ見ていって、x<0123456789 987654321>yを作って、xやyをcaptureして無理矢理該当部分を切り出した。
mitchsさん 69byte
http://golf.shinh.org/reveal.rb?Connect+Digits/mitchs_1464924624
s/./&<0123456789@9876543210&& &/g
s/<\(\S\)*\(\(\w\)*\)\S* \1\3*/\2/g
隣接するabに対し、<0123456789@9876543210aa abという形を作り、a\w*bにmatchする\w*bで置き換え。
先頭も末尾もいい感じになっている。
c
私のそれは97byteとかいう酷さでした。
mitchsさん + tailsさん 54byte
http://golf.shinh.org/reveal.rb?Connect+Digits/mitchs+%28tails%29_1465935599
t;main(c){while(read(-t%c,&c,1))putchar(t-=c/~t|t>c);}
t;
main(c) {
while (read((-t)%c, &c, 1))
putchar(t -= (c/~t) | (t>c));
}
tにはひとつ前の文字が入り、cには現在の文字が入る。
ssize_t read(int fd, void *buf, size_t count);。
(-t)%cは、tがcの倍数なら$0$でSTDIN_FILENO、そうでなければ負値なので全体でnop。
little endianで$1$文字読むので、普通に$48 \dots 58$の整数としてcに入る。
tから引いている式の|は結合順位の問題を除けば+で置き換えてよい。
~tは-(t+1)なので、この場合t<c?-1:0や-(t<c)と同じように動く。
cはtに近付く方向に動いていき、一致したあと-t%cが$0$になり次の文字を読む。
perl
私の提出は69byteでした。
teebeeさん 43byte
http://golf.shinh.org/reveal.rb?Connect+Digits/teebee_1464762573
print$_+=~$_?$&<=>$_:$&until/$&/&&getc!~/./
print($_ += (~ $_ ? ($& <=> $_) : $&)) until (/$&/ && (getc !~ /./))
$_にはひとつ前の文字が入り、$&には現在の文字が入る。
まず最初にgetc !~ /./が走って、読んだ文字を$&にcaptureする。
!~はpattern match演算子の否定形。
初回なので$_が空であり、自分自身とのmatch ~ $_は失敗し、整数$_に$&が代入される。
/$&/が成功してもう一度getcが発生。ここで初期化終了。
/$&/が成功するまで、$_を$&に近付けていく。
宇宙船演算子<=>は引き算の結果を$[-1, 1]$にclampして返す比較用の演算子。
一致すると再度getc。