【趣味プログラミング】Brainfuckはじめました #2 ABC329-A
こんにちは。すっかりBrainfuckのとりこになっているほっぴーです。
今回もBrainfuckでAtCoderの問題を解いていこうと思います。
BrainfuckについてやAtCoderについてはこちらの記事を参照ください。
問題
今回解いていく問題はこちら!
解いていく
方針1 素朴な実装(55byte)
0番地に空白をセットしておいて、
「1番地に値を入力して表示し、0番地の空白を表示」
を改行コードが入力されるまで繰り返す。
という方針でとりあえず解けそうです。
コードはこんな感じ。
//1番地に空白をセット
++++++++[->++++<]
//0番地に入力して、改行じゃなくなるまで繰り返す
,----------[++++++++++.>.<,----------]
一行ver
++++++++[->++++<],----------[++++++++++.>.<,----------]
方針2 入力がNULLだったら-1がセットされることを利用(28byte)
これは今回初めて知った仕様で、例えば入力「abc」として、「,,,,」というコードを実行すると、0番地には-1がセットされます。
コンパイラによって挙動が異なるところですが、AtCoderの環境では-1が入るようです。
この知識を使うと、終わりの判定がかなり短くなります。
//1番地に空白をセット
++++++++[->++++<]
//0番地に入力して、NULLじゃなくなるまで繰り返す
,+[-.>.<,+]
一行ver
++++++++[->++++<],+[-.>.<,+]
方針3 空白を作る部分でオーバーフローを使用(23byte)
前回使ったテクで、2^Nの繰り返しはオーバーフローをうまく使うと短くなるケースがあります。このテク考えた人本当に頭良すぎる。
さっそく今回も使っていきましょう!
具体的には、「空白」の文字コードは32なので、256 / 32 = 8より、0から8ずつ引いていけばいいことがわかります。
//1番地に空白をセット
-------->+<]
//0番地に入力して、NULLじゃなくなるまで繰り返す
,+[-.>.<,+]
一行ver
-------->+<],+[-.>.<,+]
かなり上手くいっていると思いますが、この問題のshortestは20byte。
あと3byteをどうしても縮められそうになかったので、shortestコードを見てみることにしました。
方針4(?) 改行区切りでも良いことを利用する(20byte)shortest
20byteのコードを見てみたところ、この問題は空白区切りではなく、改行区切りで表示してもACするようです(なんじゃそりゃ)
試しにc++で改行区切りするコードで出してみましたが、無事(?)ACしました。
しゃくぜんとはしませんが、コードにするとこんな感じ。
// 入力して、NULLじゃなければ表示して改行を繰り返す
,+[-.>++++++++++.,+]
まとめ
shortestまではいけませんでしたが、空白区切りで表示しているコードの中では一番短かったので、及第点といったところでしょうか。
空白じゃなくて改行でも良かったり、答えの前後に空白や改行が挿入されていてもいいという柔軟さは、短いコードを書く上で利用できることがあるようです。
それにしても、やはりBrainfuckでのAtCoderは他では接種できない楽しさを提供してくれます。
この記事が、みなさんの良きBrainfuckライフの手助けになっていれば幸いです。
この記事が気に入ったらサポートをしてみませんか?