はじめに
CodeIQの「第11回デスマコロシアム」の結果が発表されたので回答したコードを公開します。
前準備
シェル芸を使用して、問題の出力結果から'*'の挿入位置を取得する。
1.問題の出力結果
bash
$ cat text
br*infuckbra*nfuckbrain*uckbrainfu*kb*ainfuckb*ainfuckb*ainfuckbra*nfuckb*ainfuckbrainfu*kb*ainfuckbrainfuck*br*infuckbra*nfuckbr*infuckbrainfuck*bra*nfuckb*ainfuckbra*nfuckbrainfu*kbrai*fuckb*ainfuckbrai*fuckbra*nfuckbrai*fuckbrainfu*kbrain*uckbra*nfuckbrain*uckbrainfuck*brainf*ckb*ainfuckbrainf*ckbrainfu*kbrainfu*kb*ainfuckbrainfu*kbra*nfuckbrainfu*kbrainfuck*brainfuc*bra*nfuckbrainfuc*brainfuck*brainfuck*brainfu*kb*ainfuck*rainfuckb*ainfuckb*ainfuck*rainfuckbra*nfuckb*ainfuck*rainfuckbrainfu*kb*ainfuck*rainfuckbrainfuck*b*ainfuckb*ainfuckbra*nfuck
2.単語を一行毎に分割
文字に対応しない'*'は単語の直後に置くのが味噌。
bash
$ !!|gsed -E 's/(ck|\*k|c\*|ck\*)(br|\*r|b\*)/\1\n\2/g'
(中略)
b*ainfuck
brainfu*k
b*ainfuck
brainfuck*
br*infuck
(以下省略)
3.'*'の挿入位置を取得
単語の先頭の文字が0、単語の直後が9となる。
bash
$ !!|awk '{print index($1,"*")-1}'
(中略)
1
7
1
9
2
(以下省略)
4.挿入位置を1行にまとめる
ここで出来上がった数列が素数を先頭から30個繋げたものだと判明する。
bash
$ !!|tr -d '\n'
2357111317192329313741434753596167717379838997101103107109113
コードの説明
同じ言語を選択した回答者が多いとペナルティが増えるため、前回の回答者が0だったHaskellを選択。しかし、今回は自分も含めて2人だった。(-10)
また、指定のideoneでは、素数ライブラリが使用できなかったため、数列はコードに直接記述した。
1. 前準備で求めた数列を順番に数値に変換し、
2. 単語"brainfuck"の数値が示す位置に'*'を挿入し、
3. 結果を一行に結合する。
提出したコード
"main="より後の部分が評価対象(148文字)
Haskell
main=putStr$concat$map((\s i->take i s++"*"++drop(i+1)s)"brainfuck")$map(\x->read[x]::Int)"2357111317192329313741434753596167717379838997101103107109113"
改良版
関数合成と型推論を使うともう少し短く出来た。自分はHeskell初心者なのでこれが限界の模様。
Haskell
main=putStr$concat$map(((\s i->take i s++"*"++drop(i+1)s)"brainfuck").(\x->read[x]+0))"2357111317192329313741434753596167717379838997101103107109113"
2015/7/17追記。
エラトステネスの篩を実装して、もう一寸頑張ってみる。
Haskell
import Data.Char
main=putStr$concat$map(((\s i->take i s++"*"++drop(i+1)s)"brainfuck").digitToInt)$let f[]=[];f(x:s)=show x++f[y|y<-s,mod y x/=0]in f[2..113]
2015/7/18追記。
さらに3文字減った模様。
Haskell
import Data.Char
main=print$concatMap(((\s i->take i s++'*':drop(i+1)s)"brainfuck").digitToInt)$let f[]=[];f(x:s)=show x++f[y|y<-s,mod y x/=0]in f[2..113]
最後に
トーナメント結果はベスト16で、豪傑バッジをいただきました。