BrainFuck(というプログラミング言語)

cf. どーんとやってみよう – BrainFuck で棒グラフ

なんというか,こんなプログラミング言語があったとは。

見た目にはこれがプログラムだとは思えないんだけど,Wkikipediaにはこうある。

処理系には十分なサイズのbyte型配列とその要素のひとつを指すポインタがある。ポインタを「>」「<」命令で移動させながら、そのポインタが指す値を増減させて処理を進めていく(Hello world参照)。

実用性はほとんど無いように思われるが、これだけでチューリングマシンで実行可能なあらゆるプログラムが記述できる(チューリング完全である)とされている。

つまり,えーと,立派なプログラミング言語だってことか。

見てるだけじゃわからないので,試してみることにする。使ったのはこれ(Windows版)。

http://esoteric.sange.fi/brainfuck/compiled/win/BFI.exe

ちゃんと動いてビックリ(向井さんのとはちょっと違うけど)。

再度Wikipediaによると

実行可能な命令は「8つ」のみである。

1. > ポインタをインクリメントする。ポインタをptrとすると、C言語の「ptr++;」に相当する。

2. < ポインタをデクリメントする。C言語の「ptr–;」に相当。

3. + ポインタが指す値をインクリメントする。C言語の「(*ptr)++;」に相当。

4. – ポインタが指す値をデクリメントする。C言語の「(*ptr)–;」に相当。

5. . ポインタが指す値を出力する。C言語の「putchar(*ptr);」に相当。

6. , 1バイトを入力してポインタが指す値に代入する。C言語の「*ptr=getchar();」に相当。

7. [ ポインタが指す値が0なら、対応する ] までジャンプする。C言語の「while(*ptr){」に相当。

8. ] ポインタが指す値が0でないなら、対応する [ にジャンプする。C言語の「}」に相当。

ということらしい。ついでにいわゆる Hello world プログラムもあった。

++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<
+++++++++++++++.>.+++.------.--------.>+.>.

いろいろいじってると何となくわかってきた。けど,プログラムを読んで動作を理解するのは至難の業だ。動かしてみたほうが速い。

というか,デバッグはどうやってやるんだろう。

キミならどう書く 2.0 – ROUND 3 –

cf. キミならどう書く 2.0 – ROUND 3 –

前のエントリでは話がBrainf*ck(一応伏せ字にする)にいっちゃったけど,こっちが本題。
まったくもって乗り遅れたけど書いてみた。

import System

showStar :: Int -> IO ()
showStar n = do putStrLn $ (show n) ++ " : " ++ (repeatStar n)

repeatStar :: Int -> String
repeatStar n = take n $ repeat '*'

main = do args <- getArgs
          mapM_ showStar $ map read args

実行。

>runghc starbar.hs 3 8 5
3 : ***
8 : ********
5 : *****

OK。いけてるぞ。
でも桁数の違う数が混じると汚いな。

>runghc starbar.hs 3 12 7
3 : ***
12 : ************
7 : *******

まぁいいか。

追記:
(コメントから)
そうか。replicate を使えばいいのか。よし,ついでにポイントフリーにして,

Prelude> let repeatStar = flip replicate '*'
Prelude> :t repeatStar
repeatStar :: Int -> [Char]
Prelude> repeatStar 7
"*******"