Advertisement

実用Brainf*ckプログラミング

Sep. 9, 2013
Advertisement

More Related Content

Slideshows for you(20)

Advertisement

More from 京大 マイコンクラブ(20)

Advertisement

実用Brainf*ckプログラミング

  1. 実用 Brainf*ck プログラミング KMC ID:prime
  2. 目次 ● 自己紹介 ● Brainf*ck とは ● 開発環境の入手 ● 実践編 :Brainf*ck でのコーディング ● 番外編 :?????
  3. 自己紹介 ● KMC ID:prime ● Twitter ID:@_primenumber ( そすう ) ● 最近始めたはてなブログ : – http://primenumber.hatenadiary.jp/ ● 京都大学理学部一回生 数学系志望 ● 普段使う言語 :C++,Brainf*ck, たまに Ruby,Coq ● 競技プログラミング :Codeforces,AOJ,ICPC... ● 数学ぽいプログラミングもやってます – 素数判定・素数表作成・素因数分解 , フィボナッチ数 , コ ラッツ予想の検証 , 多項式ライブラリ , ・・・
  4. ところで
  5. おわび ● タイムテーブルでは「実用 Brainf*ck プログラミング入門編」 となっていましたが , これは入門編ではありません – 任意のプログラムが ( 頑張れば )Brainf*ck で書けるよう なレベルまで解説します ● 時間いっぱい参加者の皆さんを Brainf*ck でガンガン殴り続 ける予定です ● 入門編 , 初級編 , 中級編と進みます – 上級編もやりたいですが時間の都合上省略します
  6. Brainf*ck とは
  7. Brainf*ck とは ● コンパイラがなるべく簡潔になるように設計された言語 , わず か 8 種類の記号のみでプログラミングする ≠ 人間が読み書きしづらいように設計された言語 ● 実際 ,Brainf*ck の 8 個の命令記号は可読性が上がるよう に選ばれている ● 構造化プログラミングのエッセンスを抽出しているのが特徴 → 忌まわしき goto 文は存在しないため , スパゲッティー コード化が起こりにくい !!!!!
  8. Brainf*ck とは ● 最初に 0 で初期化された十分な長さの配列が与えられる . ● 最初に 0 番地を指しているポインタがあり , このポインタを通 してデータを読み書きする . ● 制御構文 [ と ] によって条件分岐やループができる 番地 0 1 2 3 4 … データ 0 0 0 0 0 …
  9. Brainf*ck とは ● 命令記号は以下の八種類 – + ポインタの指す値をインクリメントする – - ポインタの指す値をデクリメントする – > ポインタをインクリメントする – < ポインタをデクリメントする – , 入力を 1byte 読んでポインタの指す場所に代入する – . ポインタの指す値を文字として出力する – [ ポインタの指す値が 0 なら対応する ] に飛ぶ – ] ポインタの指す値が 0 以外なら対応する [ に飛ぶ
  10. Brainf*ck とは ● それぞれの命令は C 言語で概ね対応する構文がある – + C 言語の (*pt)++; に対応 – - C 言語の (*pt)--; に対応 – > C 言語の pt++; に対応 – < C 言語の pt--; に対応 – , C 言語の *pt = getchar(); に対応 – . C 言語の putchar(*pt); に対応 – [ C 言語の while(*pt){ に対応 – ] C 言語の } に対応
  11. Brainf*ck とは ● 処理系依存の仕様がいくつかある – 配列の長さ ● 使用量に合わせるものと固定長のものがある ● ここでは使用量に合わせる ( 実質無限長 ) とする – 数値がオーバーフロー・アンダーフローするときの扱い ● それ以上値が変化しないものと最大値 <-> 最小値と変 化するものがある ● ここでは 255<->0 となるものとします – 0 番地より左にポインタが移動したとき ● 実行時エラーを吐くもの , 負番地にもアクセスできるも の , 配列の反対側に回るものがある ● ここでは実行時エラーを吐くものとする
  12. Brainf*ck とは ● 処理系依存の仕様 – 入力が EOF に達したときの処理 ● 落ちる ● それ以降ずっと 0 を返す ● 直前に読んだ文字と同じ文字を返し続ける ● そもそも入出力を標準入出力に繋げないのもあり – シェルに繋げばマシンが操作できる – オーディオ入出力に繋いでもよし , ディスプレイ出力に繋 いでもよし – とりあえず今回は標準入出力につなぐことにします
  13. Brainf*ck とは 番地 0 1 2 3 4 … データ 0 0 0 0 0 … + > + < -
  14. Brainf*ck とは 番地 0 1 2 3 4 … データ 1 0 0 0 0 … + > + < -
  15. Brainf*ck とは 番地 0 1 2 3 4 … データ 1 0 0 0 0 … + > + < -
  16. Brainf*ck とは 番地 0 1 2 3 4 … データ 1 1 0 0 0 … + > + < -
  17. Brainf*ck とは 番地 0 1 2 3 4 … データ 1 1 0 0 0 … + > + < -
  18. Brainf*ck とは 番地 0 1 2 3 4 … データ 0 1 0 0 0 … + > + < -
  19. Brainf*ck とは 番地 0 1 2 3 4 … データ 64 0 0 0 0 … . [ > , ] 入力 出力 'A' 'B' '0'
  20. Brainf*ck とは 番地 0 1 2 3 4 … データ 64 0 0 0 0 … . [ > , ] 入力 出力 'A' 'B' '0' '@'
  21. Brainf*ck とは 番地 0 1 2 3 4 … データ 64 0 0 0 0 … . [ > , ] 入力 出力 'A' 'B' '0' '@'
  22. Brainf*ck とは 番地 0 1 2 3 4 … データ 64 0 0 0 0 … . [ > , ] 入力 出力 'A' 'B' '0' '@'
  23. Brainf*ck とは 番地 0 1 2 3 4 … データ 64 65 0 0 0 … . [ > , ] 入力 出力 'A' 'B' '0' '@'
  24. Brainf*ck とは 番地 0 1 2 3 4 … データ 64 65 0 0 0 … . [ > , ] 入力 出力 'A' 'B' '0' '@'
  25. Brainf*ck とは 番地 0 1 2 3 4 … データ 64 65 0 0 0 … . [ > , ] 入力 出力 'A' 'B' '0' '@'
  26. Brainf*ck とは 番地 0 1 2 3 4 … データ 64 65 66 0 0 … . [ > , ] 入力 出力 'A' 'B' '0' '@'
  27. Brainf*ck とは 番地 0 1 2 3 4 … データ 64 65 66 0 0 … . [ > , ] 入力 出力 'A' 'B' '0' '@'
  28. Brainf*ck とは 番地 0 1 2 3 4 … データ 64 65 66 0 0 … . [ > , ] 入力 出力 'A' 'B' '0' '@'
  29. Brainf*ck とは 番地 0 1 2 3 4 … データ 64 65 66 0 0 … . [ > , ] 入力 出力 'A' 'B' '0' '@'
  30. Brainf*ck とは 番地 0 1 2 3 4 … データ 64 65 66 0 0 … . [ > , ] 入力 出力 'A' 'B' '0' '@'
  31. Brainf*ck とは ● これだけの命令記号で ( 無限長の配列なら ) チューリング完全 – 他のプログラミング言語でできることなら ( 理論上 ) なんで もできる ● 「でも実際に実装するのはほぼ無理でしょ ? 」
  32. Brainf*ck とは ● これだけの命令記号で ( 無限長の配列なら ) チューリング完全 – 他のプログラミング言語でできることなら ( 理論上 ) なんで もできる ● 「でも実際に実装するのはほぼ無理でしょ ? 」 – 実はある程度のパターンを知ればわりと実装できる !!!
  33. Brainf*ck とは ● これだけの命令記号で ( 無限長の配列なら ) チューリング完全 – 他のプログラミング言語でできることなら ( 理論上 ) なんで もできる ● 「でも実際に実装するのはほぼ無理でしょ ? 」 – 実はある程度のパターンを知ればわりと実装できる !!! – 今回は実際に様々なプログラムを Brainf*ck で書いていき ます
  34. 開発環境の入手
  35. 開発環境の入手 ● ブラウザ上で実行できるインタプリタを用意しました – http://moon.kmc.gr.jp/~prime/brainf_ck/env/ – デバッグを ON にすると今どこを処理しているかやメモリの内 容が可視化される ● @ に到達すると一時停止 ( ブレークポイント ) – デバッグ OFF にすると高速に処理 ● マシンにもよるが数百万 step/s くらい ? – デバッグ ON かつ wait を 0ms にすると高速に処理してかつブ レークポイントが有効になる – めちゃくちゃステップ数のかかる処理をデバッグ OFF で実行 すると固まる
  36. 開発環境の入手 ● 最適化のかかるインタプリタを C++ で用意しました – http://moon.kmc.gr.jp/~prime/brainf_ck/bfi.cpp – C++11 でコンパイルしてください ● gcc/clang ならコンパイルオプションに -std=c++11 ● C++ のコードに変換するコンパイラ (?) も用意しました – http://moon.kmc.gr.jp/~prime/brainf_ck/bfc.cpp – 一応無駄な処理をある程度省いたコードが生成される – こちらも C++11 必須
  37. サンプルコードの入手 ● 今日使うサンプルコードをおいておきます – http://moon.kmc.gr.jp/~prime/brainf_ck/bftext/ – このページを常に開いておくことをおすすめします ● ASCII コード表もすぐに参照できるようにしておくのがよいで しょう – 「 ASCII コード表」とかで検索すると出てきます
  38. ● ここからいよいよ実際にどうコーディングするかを解説します ● 今回は「なるべく書きやすいコーディング方法」を紹介します – その分コードが冗長になったり低速になったりします – 入力が正しいかをチェックしません – どうすればより短く , より高速に動作するコードが書けるか 研究してみてください ● 説明のために記号を導入します – {n} で n 番地の値を表す . 例えば {5} なら 5 番地の値 .
  39. 入門編
  40. 入門編 :for ループ ● for ループ – {0} の値の回数だけ *** という処理を行う – コード )[***-] – *** を行うたびに {0} の値を 1 減らす – ! 注意 !*** の中で {0} の値を変更しないこと ,*** が終 わった時点で 0 番地にいること ● 次から出てくるのは for ループのいろいろな使い方
  41. 入門編 : 初期化 , 代入 ● 初期化 – {0} の値を 0 クリアする – コード )[-] – 0 になるまで 1 減らす , という操作を行う . ● 代入 – {0} に自分の好きな定数を代入する – コード )[-]+++++++ – 0 クリアして必要な数だけ + を重ねる
  42. 入門編 : 値の移動 , 足し算 ● 値の移動 – {0} から {1} に値を移動する . – 最初 {1} は 0 だったとする . – コード )[>+<-] – {1} の値を 1 増やし ,{0} の値を 1 減らす , ということを {0} が 0 になるまで繰り返す ● 足し算 – {0} と {1} の和を {1} に入れる – コード )[>+<-] – 値の移動と同じコード
  43. 入門編 : 引き算 , 値のコピー ● 引き算 – {1} から {0} を引いた値を {1} に入れる – コード )[>-<-] – {1} と {0} を 1 減らすことを {0} が 0 になるまで繰り返す ● 値のコピー ● Brainf*ck ではほとんどの操作が破壊的変更を加えるので , 頻繁に値のコピーが必要になる – {0} の値を {1} にコピー ( 一時変数として {2} を使う ) – コード )[>+>+<<-]>>[<<+>>-] – {0} の値を {1} と {2} に同時に移したあと ,{2} の値を {0} に移動する
  44. 入門編 : 掛け算 ● 定数倍 – {0} の値の 5 倍を {1} に入れる – コード )[>+++++<-] ● 掛け算 – {0} と {1} の積を {2} に入れる ({3} を一時変数として使 う ) – コード )[>[>+>+<<-]>>[<<+>>-]<<<-] – 足し算と値のコピーの合わせ技 – {0} が 0 になるまで「 {1} の値を {2} に足すたびに {0} の 値を 1 減らす」を繰り返す
  45. 入門編 : 演習 ● 数字二文字を入力にとってその和を出力する Brainf*ck コー ドを書きましょう ● とりあえず次の条件で作ってみましょう – 数字二文字 (ASCII コードで 48~57 が '0' から '9' に対 応 ) 以外の入力は与えられない – 計算結果は繰り上がりしない
  46. 入門編 : 演習 ● コード例 – ,>,>++++++[<-------->-]<<[>+<-]>. – 幸いにも ASCII コードは小さい順に並んでいるの で '0'=48 を引けば数値になる
  47. 入門編 : スタック ● スタックと Brainf*ck の命令体系は親和性が高い – push が > に ,pop が < に対応している – スタックに 3,2,3 を積み , その積を計算する – コード )+++>++>+++> << >[<[>>+>+<<<-]>>>[<<<+>>>-]<<-]<[-]>>[<<+>>-]<< > << >[<[>>+>+<<<-]>>>[<<<+>>>-]<<-]<[-]>>[<<+>>-]<< >
  48. 入門編 : 再帰 ● 再帰 : 関数からその関数自身を呼ぶこと – 再帰を使うと処理が簡潔に書けるケースがたくさん知られ ている
  49. 入門編 : 再帰 ● 再帰 : 関数からその関数自身を呼ぶこと – 再帰を使うと処理が簡潔に書けるケースがたくさん知られ ている ● 実は再帰はスタックを用いて書ける – 再帰関数の引数をスタックに積むことで実現する
  50. 入門編 : 再帰 ● 再帰 : 関数からその関数自身を呼ぶこと – 再帰を使うと処理が簡潔に書けるケースがたくさん知られ ている ● 実は再帰はスタックを用いて書ける – 再帰関数の引数をスタックに積むことで実現する →Brainf*ck ではスタックが使える !!!
  51. 入門編 : 再帰 ● 再帰 : 関数からその関数自身を呼ぶこと – 再帰を使うと処理が簡潔に書けるケースがたくさん知られ ている ● 実は再帰はスタックを用いて書ける – 再帰関数の引数をスタックに積むことで実現する →Brainf*ck ではスタックが使える !!! →Brainf*ck では再帰が書ける !!!!!
  52. 入門編 : 再帰 ● 再帰 : 関数からその関数自身を呼ぶこと – 再帰を使うと処理が簡潔に書けるケースがたくさん知られ ている ● 実は再帰はスタックを用いて書ける – 再帰関数の引数をスタックに積むことで実現する →Brainf*ck ではスタックが使える !!! →Brainf*ck では再帰が書ける !!!!! ● 再帰を用いた実践的なコードを書いてみます
  53. ハノイの塔 ● リュカという数学者が考案したと言われるパズルゲーム ● 三本の棒と大きさの異なる n 枚の円盤があり , 最初円盤は左 端の棒に大きいものが下になるように置かれている ● 次の規則を満たしつつ , 全ての円盤を右端の棒に移動させる – 一度に動かせるのは棒の一番上の円盤どれか一枚のみ – 小さい円盤の上に 大きい円盤を載せる ことはできない
  54. ハノイの塔 ● リュカという数学者が考案したと言われるパズルゲーム ● 三本の棒と大きさの異なる n 枚の円盤があり , 最初円盤は左 端の棒に大きいものが下になるように置かれている ● 次の規則を満たしつつ , 全ての円盤を右端の棒に移動させる – 一度に動かせるのは棒の一番上の円盤どれか一枚のみ – 小さい円盤の上に 大きい円盤を載せる ことはできない
  55. ハノイの塔 ● リュカという数学者が考案したと言われるパズルゲーム ● 三本の棒と大きさの異なる n 枚の円盤があり , 最初円盤は左 端の棒に大きいものが下になるように置かれている ● 次の規則を満たしつつ , 全ての円盤を右端の棒に移動させる – 一度に動かせるのは棒の一番上の円盤どれか一枚のみ – 小さい円盤の上に 大きい円盤を載せる ことはできない
  56. ハノイの塔 ● リュカという数学者が考案したと言われるパズルゲーム ● 三本の棒と大きさの異なる n 枚の円盤があり , 最初円盤は左 端の棒に大きいものが下になるように置かれている ● 次の規則を満たしつつ , 全ての円盤を右端の棒に移動させる – 一度に動かせるのは棒の一番上の円盤どれか一枚のみ – 小さい円盤の上に 大きい円盤を載せる ことはできない
  57. ハノイの塔 ● リュカという数学者が考案したと言われるパズルゲーム ● 三本の棒と大きさの異なる n 枚の円盤があり , 最初円盤は左 端の棒に大きいものが下になるように置かれている ● 次の規則を満たしつつ , 全ての円盤を右端の棒に移動させる – 一度に動かせるのは棒の一番上の円盤どれか一枚のみ – 小さい円盤の上に 大きい円盤を載せる ことはできない
  58. ハノイの塔 ● リュカという数学者が考案したと言われるパズルゲーム ● 三本の棒と大きさの異なる n 枚の円盤があり , 最初円盤は左 端の棒に大きいものが下になるように置かれている ● 次の規則を満たしつつ , 全ての円盤を右端の棒に移動させる – 一度に動かせるのは棒の一番上の円盤どれか一枚のみ – 小さい円盤の上に 大きい円盤を載せる ことはできない
  59. ハノイの塔 ● リュカという数学者が考案したと言われるパズルゲーム ● 三本の棒と大きさの異なる n 枚の円盤があり , 最初円盤は左 端の棒に大きいものが下になるように置かれている ● 次の規則を満たしつつ , 全ての円盤を右端の棒に移動させる – 一度に動かせるのは棒の一番上の円盤どれか一枚のみ – 小さい円盤の上に 大きい円盤を載せる ことはできない
  60. ハノイの塔 ● リュカという数学者が考案したと言われるパズルゲーム ● 三本の棒と大きさの異なる n 枚の円盤があり , 最初円盤は左 端の棒に大きいものが下になるように置かれている ● 次の規則を満たしつつ , 全ての円盤を右端の棒に移動させる – 一度に動かせるのは棒の一番上の円盤どれか一枚のみ – 小さい円盤の上に 大きい円盤を載せる ことはできない
  61. ハノイの塔 ● ハノイの塔は再帰的な手続きによって最短で解けることが知 られている ● 何らかの方法で左端の上から n-1 枚の円盤を真ん中の棒 に移動させる ● 左端にある一番大きな円盤を右端の棒に移動させる ● 何らかの方法で真ん中の棒の n-1 枚の円盤を右端の棒に 移動させる ● 「何らかの方法」のところにこの手続き自身を使える ( 再帰的 な手続き ) ● 実はこの方法が最短 ● 円盤が n 枚なら最短手数は 2^n-1
  62. Brainf*ck でハノイの塔 ● ハノイの塔を解くプログラムを Brainf*ck で作っていく ● 具体的な動かし方を ' 円盤の名前 ' ' 動かす前の棒の番号 ' ' 動かす先の棒の番号 ' の形で出力する ● 円盤には小さい方から A,B,C,… と名前を付ける ( 最大 26 枚 ) ● 棒には左から 1,2,3 と番号を付ける ● 円盤 2 枚の場合の出力例 A 1 2 B 1 3 A 2 1
  63. Brainf*ck でハノイの塔 ● プログラムの動作を擬似コードで書く Hanoi(n,a,b)//n 枚の円盤を a から b に動かす Hanoi(n-1,a,c) Move(n,a,b) Hanoi(n-1,c,b) end ● Move は n 番目に小さい円盤を a から b に動かすという出力を する .Move(5,1,2) なら E 1 2 と出力する ● c は {1,2,3} のうち a でも b でもない数
  64. Brainf*ck でハノイの塔 ● c は 6-a-b で求められる ( 引き算だから簡単 !) ● Hanoi の中で Move という別の関数を呼ぶ処理は書きにくい – よく見ると Hanoi と Move は引数の形が同じ – 引数を一つ増やした Hanoi'(n,s,a,b) を考えて ,s=1 なら Hanoi,s=0 なら Move の処理をするという条件分岐の形に する ● スタックに積むのは (n,s,a,b) という値の四つ組 ● スタックから 4 個ずつ値を積んだり取り出したりすることで再 帰的手続きを実現する ● s=0 なら , 〜〜という処理は if 文がないので ,s=1 である限 り Hanoi を繰り返し , そのループを抜けたあとに Move をす る , という形で書く
  65. Brainf*ck でハノイの塔 ①最初にスタックに (n,s,a,b)=(n,1,1,3) を積む ②スタックの一番上の値を読み、 s=0 なら 6 に飛ぶ ③スタックから取り出した値が (n,1,a,b) だったとすると それを消してスタックに (n-1,1,a,6-a-b),(n,0,a,b), (n-1,1,6-a-b,b) を積む ④スタックの一番上の値を読み、 (1,*,*,*) でないなら 3 に 戻る ⑤スタックの一番上の値を読み、 s を 1 から 0 にする ⑥スタックから取り出した値を出力する。たとえば (3,0,1,3) だったら C 1 3 を出力する ⑦スタックの一番上の値が (0,*,*,*) でないなら 2 に戻る
  66. Brainf*ck でハノイの塔 ● 実際のコード >>>>++++>+>+>+++<<<[>[<-[[>>>>+>>>>+>>>>+<<<<<<<<<<<<- ]>[>>>>+>>>>+>>>>+<<<<<<<<<<<<-]>[>>>>+>>>>+>>>>+<<<<< <<<<<<<-]>[>>>>+>>>>+>>>>+<<<<<<<<<<<<-]<++++++>>+>->> >>>>>[<<<<<<<<<<<<+>>>>>>>>>>>>-]>[<<<<<<<<<<<<+>>>>>> >>>>>>-]>[<<<<<<<<<<<<->>>>>>>>>>>>-]>[<<<<<<<<<<<<+<- >>>>>>>>>>>>>-]<<<<<[>>+>+<<<-]>[>+<-]++++++>[<->-]>[< <<+>>>-]<<<<<-]+>-]++++++++[>++++++>++++++<<<++++++++> -]>>>>++++[<++++++++>-]<<<<<.[-]>>>>.<<.[-]>>.[-]<.[-] ++++++++++.[-]<<<<<<<] (454bytes)
  67. Brainf*ck でハノイの塔 ● 見やすく整形すると >>>>+>+++++[<+++++>-]+>+>+++<<< [>[ <-[ [>>>>+>>>>+>>>>+<<<<<<<<<<<<-] >[>>>>+>>>>+>>>>+<<<<<<<<<<<<-] >[>>>>+>>>>+>>>>+<<<<<<<<<<<<-] >[>>>>+>>>>+>>>>+<<<<<<<<<<<<-] <++++++>>+>->>>>>>> [<<<<<<<<<<<<+>>>>>>>>>>>>-] >[<<<<<<<<<<<<+>>>>>>>>>>>>-] >[<<<<<<<<<<<<->>>>>>>>>>>>-] >[<<<<<<<<<<<<+<->>>>>>>>>>>>>-] <<<<<[>>+>+<<<-] >[>+<-]++++++>[<->-]>[<<<+>>>-] <<<<<- ]+>- ]++++++++[>++++++>++++++<<<++++++++>-]>>>>++++[<+++++++ +>-]<<<<<.[-]>>>>.<<.[-]>>.[-]<.[-]++++++++++. [-]<<<<<<<] Hanoi(n,a,b) Move(n,a,b)
  68. 初級編
  69. 初級編 :if イディオム ● Brainf*ck には while 文に相当する [,] はあるが ,if 文に 相当する構文はない ● while 文のループを 1 回で終えれば if 文と同じ動作になる – {0} が 0 でなければ *** の内容を実行 – コード )[***[-]] – ! 注意 ! *** の処理は最後に 0 番地に戻ること ● else 文も少しの工夫で実現可能 – {0} が 0 でなければ *1*,0 なら *0* の内容を実行 – コード )>+<[*1*>-<[-]]>[*0*-] – ! 注意 ! *1* は 0 番地に ,*0* は 1 番地に戻ること – {1} をフラグとして用いて else 文を実現している
  70. 初級編 :if イディオム ● 二つの値が等しい・等しくないで分岐する – {0}={1} なら *1* を , そうでないなら *0* を実行する – コード )[>-<-]>>+<[*1*>-<[-]]>[*0*-] – {1}-{0} を計算して 0 かどうかで場合分けしている ● 値をコピーしておけば if を連鎖して switch のようにすること も可能
  71. 初級編 : 大小比較 ● 大小比較 – {0}<{1} なら *0* を , そうでないなら *1* を実行 ( 一時変 数として {2},{3} を使用 ) – コード ) [>>>+<<[-<->[>+<-]>>-<<]>[<+>-]>[-<<<[-]>>>]<<<] +>[*0*<->[-]]<[*1*[-]] – ! 注意 ! *0* は 1 番地に ,*1* は 0 番地に戻ること – 「 {0},{1} が両方正なら 1 ずつ減らし , 減らす前の {1} が 0 だったら {0} も 0 にする」という操作を {0} が正の間行 い ,{1} が 0 かそうでないかで場合分けしている
  72. 初級編 : 除算 ● 除算 – {0}÷{1} の商を {6} に , 余りを {7} に入れる ({2} 〜 {5} を一時変数として使う ) – コード ) [[>>+>+<<<-]>>>[<<<+>>>-]<<[>>+>+<<<-]>>>[<<<+>> >-]<<[>>>+<<[-<->[>+<-]>>-<<]>[<+>-]>[-<<<[-]>>> ]<<<]+>[[-]<<<[>>>>>>>+<<<<<<<-]>>->]<[-<[>+<<-> -]>[<+>-]>>>>+<<<<]<<] – {0}≧{1} である間 , 「 {0} から {1} を引き ,{6} に 1 加え る」ということを繰り返し ,{0}<{1} になったら {0} を {7} に入れる
  73. 初級編 : 配列 ● ランダムアクセス出来る配列を実現したい – 例 ) 配列の {0} 番目の値を参照する ● 次のようにデータを配置することで可能 ● 2 バイトごとに一つの値を格納する (1 セクションと呼ぶことにする ) – 1 バイト目に値 – 2 バイト目は計算領域 ( 最初は 0 で埋めておく ) ● 配列へのアクセス – コード )[[>>+<<-]>>-] – セクションをひとつずつ移動しながら , 値を 2 つ横に移動して 1 減ら す , ということを値が 0 になるまで繰り返すと , 終了した時にはポイ ンタは a[{0}] の直前を指している 番地 0 1 2 3 4 5 6 7 8 … 値 {0} 0 0 0 0 …a0 a1 a2 a3
  74. 初級編 : 配列 ● 配列を走査したい ● 配列の端を求めたい ● 1 セクションを 3 バイト区切りにする – 1 バイト目に値 – 2 バイト目に 1: 直前に値があることを示す – 3 バイト目は計算領域 ● 3n 番地から配列の終端まで飛ぶ – コード )[>>>]<<<< – セクションの 2 バイト目が番兵の役割を果たしている 番地 0 1 2 3 4 5 6 7 … m m+1 m+2 m+3 m+4 値 0 0 1 0 1 0 … 1 0 0 0a0 a1 an−1
  75. 初級編 : 配列 ● 同様にして配列の先頭に飛ぶことも出来る ● セクションをひとつずつ移動し , そのセクションの 2 バイト目 が 1 の間 ~ する , というコードを書くことで配列を走査出来る ● この方法でデータを格納すると (256 バイト以上はランダムア クセスするのは難しいが ) いくらでも長い配列を用意できる 番地 0 1 2 3 4 5 6 7 … m m+1 m+2 m+3 m+4 値 0 0 1 0 1 0 … 1 0 0 0a0 a1 an−1
  76. 初級編 : 配列 ● ポインタを使いたい ( 今居る場所を記憶して後で戻りたい ) – ひとつの配列にひとつのポインタであれば , ポインタの指 している区切りの 2 バイト目を 0 にすることで実現できる – コード )[>>>] – 3 番地から始めるとポインタの指す先 , ポインタの指す先 の次のセクションの 2 バイト目から始めると配列の末尾に 飛べる ● 256 バイト以上あっても使える 番地 0 1 2 3 4 5 6 7 … m m+1 m+2 m+3 m+4 値 0 0 1 0 1 0 … 1 0 0 0a0 a1 an−1
  77. 初級編 : 配列 ● この場合のポインタというのは , 参照している場所を保存する ためのデータ構造といえる – アドレスを格納する変数を用意しようと思うと ,256 要素以 上の配列に対しては多倍長整数が扱える必要がある ● 多倍長整数を扱うのにも配列が必要になるため , 処理 が大変なことになる ● 今後この形式の配列をポインタフラグ付き配列と呼ぶ
  78. 初級編 : 配列 ● 長さ {0} のポインタフラグ付き配列を作る ( 配列の最初の要素 が来るのは 3 番地 ) – コード )[>>>>[>>>]+[<<<]<-] ● ポインタフラグ付き配列のコピー – 最初配列の先頭にポインタがあるものとする – コード ) >[-<[>>+>>[>>>]>>>[>>>]<+<<[<<<]<<<[<<<]<-]>>[<<+ >>-]>>[>>>]>>>[>>>]+[<<<]<<<[<<<]+>>>] – 1 セクションごとに「まず値をコピーし , つぎにポインタフラグ をコピーする」ということをする
  79. Brainf*ck で Brainf*ck インタプリタ ● 初級編で取り上げた条件分岐や配列を使ったプログラムとし て ,Brainf*ck で Brainf*ck のインタプリタを書いてみます ● 仕様 – Brainf*ck のソースコードを標準入力で受け取る ● '!' が現れる前までをソースコード , その後を標準入 力として扱う ● 実装 – ソースコードを格納するポインタフラグ付き配列とデータを 格納するポインタフラグ付き配列を持つ – ソースコードを読み込み , それに対応する操作をデータに 対して施す
  80. Brainf*ck で Brainf*ck インタプリタ ● ソースコードとデータの配列は次のように配置する ● ck: ソースコードの k 文字目 ● dk: 配列の k 番目の値 ● pk,qk: プログラムポインタフラグ , データポインタフラグ ● 今ソースコードのどこを読んでいるかを指すポインタフラグと , データ を指すポインタフラグを持つ – それぞれプログラムポインタフラグ , データポインタフラグと呼ぶ ● プログラムポインタの指すところからデータポインタの指すところまで 飛ぶのは簡単 – コード )>>>[>>>]>>>[>>>] 0 0 0 0 c1 p1 0 c2 p2 0 … … cn pn 0 0 0 0 d0 q0 0 …
  81. Brainf*ck で Brainf*ck インタプリタ ①標準入力から ! が現れるまで読み込み , ソースコードを格納 する配列に格納する . プログラムポインタフラグは p1 を 0, それ 以外を 1 にする ②プログラムポインタの指す文字を読み ,+ なら③ ,, なら ④ ,- なら⑤ ,. なら⑥ ,< なら⑦ ,> なら⑧ ,[ なら⑨〜⑪ ,] な ら⑫〜⑭を実行し , それが終わったらそれぞれ⑮に行く ③(+ の処理 ) データポインタまで飛び , 値を 1 増やし , プログラ ムポインタまで戻る ④(, の処理 ) データポインタまで飛び , 標準入力からひとつ読 んでポインタの指す値に代入し , プログラムポインタまで戻る ⑤(- の処理 ) データポインタまで飛び , 値を 1 減らし , プログラ ムポインタまで戻る ● プログラムの流れ
  82. Brainf*ck で Brainf*ck インタプリタ ⑥(. の処理 ) データポインタまで飛び , 値を標準出力に出力 し , プログラムポインタまで戻る ⑦(< の処理 ) データポインタまで飛び , データポインタをひとつ 戻し , プログラムポインタに戻る ⑧(> の処理 ) データポインタまで飛び , データポインタをひとつ 進め , プログラムポインタに戻る ⑨([ の処理 ) データポインタまで飛び , 値が 0 でなければ⑪に 飛ぶ ⑩プログラムポインタに飛び , ソースコードの配列をプログラム ポインタを前進させながら進んでいき ,[ と ] の数を数え , 同じに なったところでとめ , データポインタまで戻る ⑪プログラムポインタまで戻る
  83. Brainf*ck で Brainf*ck インタプリタ ⑫(] の処理 ) データポインタまで飛び , 値が 0 ならば⑭に飛ぶ ⑬プログラムポインタに飛び , ソースコードの配列をプログラム ポインタを後退させながら戻っていき ,[ と ] の数を数え , 同じに なったところで止め , データポインタまで戻る ⑭プログラムポインタまで戻る ⑮プログラムポインタをひとつ進め , プログラムポインタの指す 文字が 0 でなければ②に戻る あとはこれをコードに落としこんでいく
  84. Brainf*ck で Brainf*ck インタプリタ ● 実際のコード >>>>,--->+++++[<------>-]<[+++>+++++[<++++++>-]+>>,--->+++++[<------>-]<]<<[<<<] >>>-<[[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<------->>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]<+<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<- ------>>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<,<<[<<<]<<<[<<<] >-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>> >-]<<<[>>[>>>]>>>[>>>]<-<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--- ------>>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<.<<[<<<]<<<[<<<]> -]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<---------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]+<<<-<<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++ ++[<<-------->>-]+<<++[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]+>>>[-]<<< [<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]>+<<[[<+>-]>>-<<]<[>+<-]>>>[-<<<<[<<<] <<<[<<<]>+[<+>>>-<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------- ----->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<->>>-]<<<[>>>+<<<-]>>>]>>[>>>] >>>[>>>]>]<<<<[<<<]<<<[<<<]>]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------------> >-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]<[>>+>>>+<<<<<-]>>>>>[< <<<<+>>>>>-]<<<[[-]<<<<[<<<]<<<[<<<]<<<<<-[>>->>>+<<<<[>>+>>>+<<<<<-]>>[<<+>>-]+ ++++++[<<------------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>> +<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]< <<[<<<->>>-]<<<[<<<->>>+]<<<]>>>>>>>>[>>>]>>>[>>>]>]<<<<[<<<]<<<[<<<]>]<+>>>[-]< ] (1681bytes)
  85. Brainf*ck で Brainf*ck インタプリタ ● 分かるかボケ – はい
  86. Brainf*ck で Brainf*ck インタプリタ ● 分かるかボケ – はい – 全体を眺めていても何がなんだかわからないので部分ご とに見て行きます
  87. >>>>,--->+++++[<------>-]<[+++>+++++[<++++++>-]+>>,--->+++++[<------>-]<]<<[<<<] >>>-<[[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<------->>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]<+<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<- ------>>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<,<<[<<<]<<<[<<<] >-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>> >-]<<<[>>[>>>]>>>[>>>]<-<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--- ------>>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<.<<[<<<]<<<[<<<]> -]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<---------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]+<<<-<<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++ ++[<<-------->>-]+<<++[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]+>>>[-]<<< [<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]>+<<[[<+>-]>>-<<]<[>+<-]>>>[-<<<<[<<<] <<<[<<<]>+[<+>>>-<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------- ----->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<->>>-]<<<[>>>+<<<-]>>>]>>[>>>] >>>[>>>]>]<<<<[<<<]<<<[<<<]>]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------------> >-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]<[>>+>>>+<<<<<-]>>>>>[< <<<<+>>>>>-]<<<[[-]<<<<[<<<]<<<[<<<]<<<<<-[>>->>>+<<<<[>>+>>>+<<<<<-]>>[<<+>>-]+ ++++++[<<------------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>> +<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]< <<[<<<->>>-]<<<[<<<->>>+]<<<]>>>>>>>>[>>>]>>>[>>>]>]<<<<[<<<]<<<[<<<]>]<+>>>[-]< ] Brainf*ck で Brainf*ck インタプリタ ● 実際のコード (1681bytes) プログラムの読み込み
  88. >>>>,--->+++++[<------>-]<[+++>+++++[<++++++>-]+>>,--->+++++[<------>-]<]<<[<<<] >>>-<[[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<------->>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]<+<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<- ------>>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<,<<[<<<]<<<[<<<] >-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>> >-]<<<[>>[>>>]>>>[>>>]<-<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--- ------>>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<.<<[<<<]<<<[<<<]> -]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<---------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]+<<<-<<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++ ++[<<-------->>-]+<<++[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]+>>>[-]<<< [<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]>+<<[[<+>-]>>-<<]<[>+<-]>>>[-<<<<[<<<] <<<[<<<]>+[<+>>>-<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------- ----->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<->>>-]<<<[>>>+<<<-]>>>]>>[>>>] >>>[>>>]>]<<<<[<<<]<<<[<<<]>]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------------> >-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]<[>>+>>>+<<<<<-]>>>>>[< <<<<+>>>>>-]<<<[[-]<<<<[<<<]<<<[<<<]<<<<<-[>>->>>+<<<<[>>+>>>+<<<<<-]>>[<<+>>-]+ ++++++[<<------------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>> +<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]< <<[<<<->>>-]<<<[<<<->>>+]<<<]>>>>>>>>[>>>]>>>[>>>]>]<<<<[<<<]<<<[<<<]>]<+>>>[-]< ] Brainf*ck で Brainf*ck インタプリタ ● 実際のコード (1681bytes) もし + ならば〜
  89. >>>>,--->+++++[<------>-]<[+++>+++++[<++++++>-]+>>,--->+++++[<------>-]<]<<[<<<] >>>-<[[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<------->>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]<+<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<- ------>>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<,<<[<<<]<<<[<<<] >-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>> >-]<<<[>>[>>>]>>>[>>>]<-<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--- ------>>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<.<<[<<<]<<<[<<<]> -]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<---------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]+<<<-<<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++ ++[<<-------->>-]+<<++[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]+>>>[-]<<< [<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]>+<<[[<+>-]>>-<<]<[>+<-]>>>[-<<<<[<<<] <<<[<<<]>+[<+>>>-<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------- ----->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<->>>-]<<<[>>>+<<<-]>>>]>>[>>>] >>>[>>>]>]<<<<[<<<]<<<[<<<]>]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------------> >-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]<[>>+>>>+<<<<<-]>>>>>[< <<<<+>>>>>-]<<<[[-]<<<<[<<<]<<<[<<<]<<<<<-[>>->>>+<<<<[>>+>>>+<<<<<-]>>[<<+>>-]+ ++++++[<<------------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>> +<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]< <<[<<<->>>-]<<<[<<<->>>+]<<<]>>>>>>>>[>>>]>>>[>>>]>]<<<<[<<<]<<<[<<<]>]<+>>>[-]< ] Brainf*ck で Brainf*ck インタプリタ ● 実際のコード (1681bytes) もし , ならば〜
  90. >>>>,--->+++++[<------>-]<[+++>+++++[<++++++>-]+>>,--->+++++[<------>-]<]<<[<<<] >>>-<[[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<------->>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]<+<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<- ------>>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<,<<[<<<]<<<[<<<] >-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>> >-]<<<[>>[>>>]>>>[>>>]<-<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--- ------>>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<.<<[<<<]<<<[<<<]> -]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<---------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]+<<<-<<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++ ++[<<-------->>-]+<<++[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]+>>>[-]<<< [<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]>+<<[[<+>-]>>-<<]<[>+<-]>>>[-<<<<[<<<] <<<[<<<]>+[<+>>>-<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------- ----->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<->>>-]<<<[>>>+<<<-]>>>]>>[>>>] >>>[>>>]>]<<<<[<<<]<<<[<<<]>]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------------> >-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]<[>>+>>>+<<<<<-]>>>>>[< <<<<+>>>>>-]<<<[[-]<<<<[<<<]<<<[<<<]<<<<<-[>>->>>+<<<<[>>+>>>+<<<<<-]>>[<<+>>-]+ ++++++[<<------------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>> +<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]< <<[<<<->>>-]<<<[<<<->>>+]<<<]>>>>>>>>[>>>]>>>[>>>]>]<<<<[<<<]<<<[<<<]>]<+>>>[-]< ] Brainf*ck で Brainf*ck インタプリタ ● 実際のコード (1681bytes) もし - ならば〜
  91. >>>>,--->+++++[<------>-]<[+++>+++++[<++++++>-]+>>,--->+++++[<------>-]<]<<[<<<] >>>-<[[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<------->>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]<+<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<- ------>>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<,<<[<<<]<<<[<<<] >-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>> >-]<<<[>>[>>>]>>>[>>>]<-<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--- ------>>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<.<<[<<<]<<<[<<<]> -]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<---------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]+<<<-<<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++ ++[<<-------->>-]+<<++[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]+>>>[-]<<< [<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]>+<<[[<+>-]>>-<<]<[>+<-]>>>[-<<<<[<<<] <<<[<<<]>+[<+>>>-<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------- ----->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<->>>-]<<<[>>>+<<<-]>>>]>>[>>>] >>>[>>>]>]<<<<[<<<]<<<[<<<]>]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------------> >-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]<[>>+>>>+<<<<<-]>>>>>[< <<<<+>>>>>-]<<<[[-]<<<<[<<<]<<<[<<<]<<<<<-[>>->>>+<<<<[>>+>>>+<<<<<-]>>[<<+>>-]+ ++++++[<<------------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>> +<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]< <<[<<<->>>-]<<<[<<<->>>+]<<<]>>>>>>>>[>>>]>>>[>>>]>]<<<<[<<<]<<<[<<<]>]<+>>>[-]< ] Brainf*ck で Brainf*ck インタプリタ ● 実際のコード (1681bytes) もし . ならば〜
  92. >>>>,--->+++++[<------>-]<[+++>+++++[<++++++>-]+>>,--->+++++[<------>-]<]<<[<<<] >>>-<[[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<------->>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]<+<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<- ------>>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<,<<[<<<]<<<[<<<] >-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>> >-]<<<[>>[>>>]>>>[>>>]<-<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--- ------>>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<.<<[<<<]<<<[<<<]> -]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<---------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]+<<<-<<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++ ++[<<-------->>-]+<<++[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]+>>>[-]<<< [<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]>+<<[[<+>-]>>-<<]<[>+<-]>>>[-<<<<[<<<] <<<[<<<]>+[<+>>>-<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------- ----->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<->>>-]<<<[>>>+<<<-]>>>]>>[>>>] >>>[>>>]>]<<<<[<<<]<<<[<<<]>]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------------> >-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]<[>>+>>>+<<<<<-]>>>>>[< <<<<+>>>>>-]<<<[[-]<<<<[<<<]<<<[<<<]<<<<<-[>>->>>+<<<<[>>+>>>+<<<<<-]>>[<<+>>-]+ ++++++[<<------------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>> +<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]< <<[<<<->>>-]<<<[<<<->>>+]<<<]>>>>>>>>[>>>]>>>[>>>]>]<<<<[<<<]<<<[<<<]>]<+>>>[-]< ] Brainf*ck で Brainf*ck インタプリタ ● 実際のコード (1681bytes) もし < ならば〜
  93. >>>>,--->+++++[<------>-]<[+++>+++++[<++++++>-]+>>,--->+++++[<------>-]<]<<[<<<] >>>-<[[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<------->>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]<+<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<- ------>>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<,<<[<<<]<<<[<<<] >-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>> >-]<<<[>>[>>>]>>>[>>>]<-<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--- ------>>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<.<<[<<<]<<<[<<<]> -]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<---------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]+<<<-<<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++ ++[<<-------->>-]+<<++[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]+>>>[-]<<< [<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]>+<<[[<+>-]>>-<<]<[>+<-]>>>[-<<<<[<<<] <<<[<<<]>+[<+>>>-<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------- ----->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<->>>-]<<<[>>>+<<<-]>>>]>>[>>>] >>>[>>>]>]<<<<[<<<]<<<[<<<]>]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------------> >-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]<[>>+>>>+<<<<<-]>>>>>[< <<<<+>>>>>-]<<<[[-]<<<<[<<<]<<<[<<<]<<<<<-[>>->>>+<<<<[>>+>>>+<<<<<-]>>[<<+>>-]+ ++++++[<<------------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>> +<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]< <<[<<<->>>-]<<<[<<<->>>+]<<<]>>>>>>>>[>>>]>>>[>>>]>]<<<<[<<<]<<<[<<<]>]<+>>>[-]< ] Brainf*ck で Brainf*ck インタプリタ ● 実際のコード (1681bytes) もし > ならば〜
  94. >>>>,--->+++++[<------>-]<[+++>+++++[<++++++>-]+>>,--->+++++[<------>-]<]<<[<<<] >>>-<[[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<------->>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]<+<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<- ------>>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<,<<[<<<]<<<[<<<] >-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>> >-]<<<[>>[>>>]>>>[>>>]<-<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--- ------>>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<.<<[<<<]<<<[<<<]> -]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<---------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]+<<<-<<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++ ++[<<-------->>-]+<<++[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]+>>>[-]<<< [<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]>+<<[[<+>-]>>-<<]<[>+<-]>>>[-<<<<[<<<] <<<[<<<]>+[<+>>>-<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------- ----->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<->>>-]<<<[>>>+<<<-]>>>]>>[>>>] >>>[>>>]>]<<<<[<<<]<<<[<<<]>]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------------> >-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]<[>>+>>>+<<<<<-]>>>>>[< <<<<+>>>>>-]<<<[[-]<<<<[<<<]<<<[<<<]<<<<<-[>>->>>+<<<<[>>+>>>+<<<<<-]>>[<<+>>-]+ ++++++[<<------------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>> +<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]< <<[<<<->>>-]<<<[<<<->>>+]<<<]>>>>>>>>[>>>]>>>[>>>]>]<<<<[<<<]<<<[<<<]>]<+>>>[-]< ] Brainf*ck で Brainf*ck インタプリタ ● 実際のコード (1681bytes) もし [ ならば〜
  95. >>>>,--->+++++[<------>-]<[+++>+++++[<++++++>-]+>>,--->+++++[<------>-]<]<<[<<<] >>>-<[[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<------->>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]<+<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<- ------>>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<,<<[<<<]<<<[<<<] >-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>> >-]<<<[>>[>>>]>>>[>>>]<-<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--- ------>>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<.<<[<<<]<<<[<<<]> -]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<---------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]+<<<-<<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++ ++[<<-------->>-]+<<++[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]+>>>[-]<<< [<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]>+<<[[<+>-]>>-<<]<[>+<-]>>>[-<<<<[<<<] <<<[<<<]>+[<+>>>-<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------- ----->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<->>>-]<<<[>>>+<<<-]>>>]>>[>>>] >>>[>>>]>]<<<<[<<<]<<<[<<<]>]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------------> >-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]<[>>+>>>+<<<<<-]>>>>>[< <<<<+>>>>>-]<<<[[-]<<<<[<<<]<<<[<<<]<<<<<-[>>->>>+<<<<[>>+>>>+<<<<<-]>>[<<+>>-]+ ++++++[<<------------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>> +<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]< <<[<<<->>>-]<<<[<<<->>>+]<<<]>>>>>>>>[>>>]>>>[>>>]>]<<<<[<<<]<<<[<<<]>]<+>>>[-]< ] Brainf*ck で Brainf*ck インタプリタ ● 実際のコード (1681bytes) もし ] ならば〜
  96. >>>>,--->+++++[<------>-]<[+++>+++++[<++++++>-]+>>,--->+++++[<------>-]<]<<[<<<] >>>-<[[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<------->>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]<+<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<- ------>>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<,<<[<<<]<<<[<<<] >-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>> >-]<<<[>>[>>>]>>>[>>>]<-<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++[<<--- ------>>-]+<<-[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]<.<<[<<<]<<<[<<<]> -]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++[<<---------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>> >>-]<<<[>>[>>>]>>>[>>>]+<<<-<<<[<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]++++++ ++[<<-------->>-]+<<++[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[>>[>>>]>>>[>>>]+>>>[-]<<< [<<<]<<<[<<<]>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]>+<<[[<+>-]>>-<<]<[>+<-]>>>[-<<<<[<<<] <<<[<<<]>+[<+>>>-<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<[[-]>>- <<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------- ----->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<->>>-]<<<[>>>+<<<-]>>>]>>[>>>] >>>[>>>]>]<<<<[<<<]<<<[<<<]>]<<[>>+>>>+<<<<<-]>>[<<+>>-]+++++++[<<-------------> >-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[->>[>>>]>>>[>>>]<[>>+>>>+<<<<<-]>>>>>[< <<<<+>>>>>-]<<<[[-]<<<<[<<<]<<<[<<<]<<<<<-[>>->>>+<<<<[>>+>>>+<<<<<-]>>[<<+>>-]+ ++++++[<<------------->>-]+<<[[-]>>-<<]>>>>>[<<<<<+>>>>>-]<<<[<<<+>>>-]<<[>>+>>> +<<<<<-]>>[<<+>>-]+++++++[<<------------->>-]+<<--[[-]>>-<<]>>>>>[<<<<<+>>>>>-]< <<[<<<->>>-]<<<[<<<->>>+]<<<]>>>>>>>>[>>>]>>>[>>>]>]<<<<[<<<]<<<[<<<]>]<+>>>[-]< ] Brainf*ck で Brainf*ck インタプリタ ● 実際のコード (1681bytes) プログラムカウンタを進める
  97. Brainf*ck で Brainf*ck インタプリタ ● 部分部分に分解していけばこれまでにやったことの組み合わ せでできる ● このインタプリタはめちゃくちゃ遅い – 比較するのに何回もコピーをとっている – データとソースコードを行ったり来たりするのにも時間がか かる – 実際に計測してみるとこのインタプリタを噛まさない場合に 比べて数万倍は遅い – 最悪で ( 数百くらいの定数 )×( ソースコードの長さ ) 倍遅 くなる – 色々と高速化出来る点はあるものの , 数百くらいある定数 が小さくなるだけでオーダーレベルでの改善はほぼ不可能
  98. 中級編
  99. 中級編 ● ここから難易度がインフレ !!!!! ● いちいち細かい実装を見ていると終わらない ● おおまかにどうやって実装するか , どのくらいのコード量 , 計 算量 , メモリ消費になるかに絞って見ていく
  100. 中級編 : 多倍長整数 ● さすがに数値が 255 までしか扱えないのは色々と不便 – 大きな整数 ( できればメモリの許す限り大きな数 ) を扱いたい ● 今回は比較的実装の楽な二つの実装を紹介 – 実装量はそこそこでそこそこの計算量 – 実装量はとても少ないが計算量はかなり大きい – 目的に応じて使い分ける ● 元のデータを壊しても良いかどうかによってコード量がかなり変 わってくることがある – その場合は両方載せる ( 何も書いていないほうが破壊版 ) – 破壊版も使う数値の組のコピーを取れば非破壊版に直せる
  101. 中級編 : 多倍長整数 ● 実装量はそこそこでそこそこの計算量になる実装 ● 値を 2 進数のポインタ付き配列で保存し ,3 バイト区切り一つ で 1 ビット格納する , 負の数は最上位 bit が 1 になる – メモリ消費量は桁数に比例 ● 以後のサンプルコードは演算する 2 数の bit 数が等しいもの と仮定 ● 計算量は足し算・引き算 O(log^2(n)), 掛け算 O(log^3(n))
  102. 中級編 : 多倍長整数 ● 足し算 – 2 数の配列は 0,0,0 でつないであり , ポインタは 2 数の直 後を指しているものとする , オーバーフローはないと仮定 – コード ) <<[-<[<<[<<<]<<<[<<<]<+>>>>[>>>]>>>[>>>]<-]<<[< <<]<<<[<<<]<<<[-]>>>+[>>>]>>>[>>>]+<<<]<<<[-<[< +>>+<-]+[>>>>>+<<<<[-<->[>+<-]>>>>-<<<<]>[<+>-] >>>[-<<<<<[-]>>>>>]<<<<<]>[[-]<<--<<+>>>>]<<[>+ <-]>>+<<<] – 各桁ごとに足してから , 繰り上がりの計算をする ● その桁が 2 以上なら 2 を引き次の桁に 1 を足す , とい ことを下位 bit から順に行う – 繰り上がりの計算は事あるごとに出てくる
  103. 中級編 : 多倍長整数 ● 引き算 – コード ) <<[<<+>[<->-]<[>+<-]<]>>>[>>>]<<<[-<[<<[<<<]<<<[ <<<]<+>>>>[>>>]>>>[>>>]<-]<<[<<<]<<<[<<<]<<<[-]> >>+[>>>]>>>[>>>]+<<<]<<<<+>[-<[<+>>+<-]+[>>>>>+< <<<[-<->[>+<-]>>>>-<<<<]>[<+>-]>>>[-<<<<<[-]>>>> >]<<<<<]>[[-]<<--<<+>>>>]<<[>+<-]>>+<<<]<[-] – 引く数の各ビットを反転し ,2 数を桁ごとに足し ,1 足して , 繰り上がりの計算をし , 最後に桁溢れの 1 を削る – ビット反転して 1 を足すと正負が逆転する – A-B を A+(-B) という形で計算している
  104. 中級編 : 多倍長整数 ● 掛け算(非破壊版 ) – コード ) [->>>[>>>]>>>[>>>]>>>[>>>]+>>>+[<<<]<<<[<<<]<<<[<<<]+>>>]<<<[<<<]>>><[>>>>[>>>]> >>[>>>]>>>[>>>]>>>>>+<<<<<<<<[<<<]<<<[<<<]<<<[<<<]>>>[>+<<[>>-<<-]>>[<<+>>-]>>]< <<<+>[-<[<+>>+<-]+[>>>>>+<<<<[-<->[>+<-]>>>>-<<<<]>[<+>-]>>>[-<<<<<[-]>>>>>]<<<< <]>[[-]<<--<<+>>>>]<<[>+<-]>>+<<<]>>]>[>>>]>>><[>>>>[>>>]>>>[>>>]>>>>>>>+<<[>>-< <-]>>[<<+>>-]<<<<<<<<<<[<<<]<<<[<<<]>>>[>+<<[>>-<<-]>>[<<+>>-]>>]<<<<+>[-<[<+>>+ <-]+[>>>>>+<<<<[-<->[>+<-]>>>>-<<<<]>[<+>-]>>>[-<<<<<[-]>>>>>]<<<<<]>[[-]<<--<<+ >>>>]<<[>+<-]>>+<<<]>>]<<<<<[<<<]>>>[->>>[>>>]>>>[>>>]>>>-<<<<<<[<<<]<<<[<<<]<<< [->>>[>>>]>>>[>>>]>>>[>>>]>>>[>>>]+>>>-<<<[<<<]<<<[<<<]<<<[<<<]<<<[<<<]+<<<]>>>[ >>>]>>>[>>>]>>>[->>>[>>>]>>>[>>>]+>>>[-]<<<[<<<]<<<[<<<]+>>>]<<<[<<<]<<<[<<<]<[> >>>[>>>]>>>[>>>]<<<[-<[>>>>[>>>]>>>[>>>]<+<<[<<<]<<<[<<<]<[>>+<<-]]>>[<<+>>-]>>[ >>>]>>>[>>>]+<<<[-]<<<[<<<]<<<[<<<]+<<<]>>>[>>>]>>>[>>>]>>>[>>>]<<<[-<[<+>>+<-]+ [>>>>>+<<<<[-<->[>+<-]>>>>-<<<<]>[<+>-]>>>[-<<<<<[-]>>>>>]<<<<<]>[[-]<<--<<+>>>> ]<<[>+<-]>>+<<<]<<<[<<<]<<<[<<<]<<<[<<<]<[>>+<<-]]>>[<<+>>-]>>[>>>]>>>[>>>]>>>[> >>]+[<<<]<<<[<<<]<<<[<<<]+>>>]>>>[>>>]>>>[>>>]<<<[-<[<+>>+<-]+[>>>>>+<<<<[-<->[> +<-]>>>>-<<<<]>[<+>-]>>>[-<<<<<[-]>>>>>]<<<<<]>[[-]<<--<<+>>>>]<<[>+<-]>>+<<<]>> >[>>>]>>>>>[-<<<<<<<<[>+<<[>>-<<-]>>[<<+>>-]<<<<]>>>[>>>]<<<<+>[-<[<+>>+<-]+[>>> >>+<<<<[-<->[>+<-]>>>>-<<<<]>[<+>-]>>>[-<<<<<[-]>>>>>]<<<<<]>[[-]<<--<<+>>>>]<<[ >+<-]>>+<<<]>>>[>>>]>>>>>]<<<<<<<<-<<<[<<<]<<<[->>>[>>>]>>>[>>>]+<<<-<<<[<<<]<<< [<<<]+<<<]>>>[>>>]>>>[>>>]+>>>-<<<[<<<]>>>>>>[[>>>]<<<-<[-]>>>>>>>[<[<<<+>>>-]>> >>]<<<-<<<[<<<]+<<<<<<[<<<]>>>>>>]>>>[<[<<<+>>>-]>>>>]<<<-<<<[<<<]+<<<<<<[<<<]>> >
  105. 中級編 : 多倍長整数 ● 掛け算 – まず ,2 つの数の符号を調べ , 積が正負どちらになるか保 存して ,2 つの数を正の数に直す – 長さ 2n の配列を用意 – いわゆる筆算をする ● – n 回足し算をしているが ,1 回足し算をするごとに繰り上が りの計算をしている – 符号が負だったら負の数に直し , 符号を除く上位 n 桁を 落とす – コードが長くなるのは複数の配列を行ったり来たりしてい るから A×B= A×b0×20 + A×b1×21 +⋯
  106. 中級編 : 多倍長整数 ● ( 実質的な ) 実装量は少ないが計算量はかなり大きい実装 ● 2 進数でもめんどくさいのは繰り上がりがあるから – 繰り上がりの問題を何とかしたい
  107. 中級編 : 多倍長整数 ● ( 実質的な ) 実装量は少ないが計算量はかなり大きい実装 ● 2 進数でもめんどくさいのは繰り上がりがあるから – 繰り上がりの問題を何とかしたい ● !!!1 進数多倍長 !!! ● 1 進数なら繰り上がりは常に発生するので煩わしい分岐をす る必要がなくなる ! ● 非破壊版の計算量は足し算・引き算が O(n^2), 掛け算が O(n^3)
  108. 中級編 : 多倍長整数 ● まずは自然数 (0 以上の整数 ) を表現する方法を考える – 連続する 1 の個数で表現する – 10 億を表すのに約 1GB のメモリを消費する – それでも無限のメモリがあればどんなに大きな値も表せる ● 足し算 – コード )[>]+[>]<- – ただ単に連結するだけ ● 前にひとつずらす – 1 進数は計算により長さが変化しうるのでそれに合わせて周り の自然数を動かす必要がある – コード )[>]<[[<]+[>]<-] 0 1 1 1 … 1 1 1 0
  109. 中級編 : 多倍長整数 ● コピー – [->[>]>[>]+[<]<[<]+>] – 1 進数多倍長の計算はほとんどコピーの組み合わせ ● 足し算 ( 非破壊版 ) – コード )[->[>]>[>]>[>]+[<]<[<]<[<]+>]>[->[>]>[>]+ [<]<[<]+>] – 2 数を同じ場所にコピー ● 掛け算 ( 非破壊版 ) – コード )[->[>]>[->[>]>[>]+[<]<[<]+>]<[<]<[<]+>] – かけられる数の要素数分だけ「かける数をコピー」という操 作をする
  110. ● 引き算 ( 片方が 0 になるまで ) – コード ) [[>]>[[>]>+<<[<]]<[<]]>[>]>[>]>[-<<-<[<]<[<]>->[ [>]>[[>]>+<<[<]]<[<]]>[>]>[>]>] ● 割り算 ( 非破壊版 ) – コード ) [->[>]>[>]>[>]+[<]<[<]<[<]+>]>[>]>[>]+[<]>[<<[<] >[->[>]>[>]<[->>[>]<[[<]+[>]<-]<[<]<[<]]<[<]+>]> [[>]>[>]+[<]<[<]>[<+>-]]<[>+<-]>] – 割る数で割られる数を引ける回数を求めている
  111. 中級編 : 多倍長整数 ● 負の数も表現したい ● 符号を格納する領域を作っても良いが , 符号によって場合分 けが必要になり , 大変 ● 2 つの自然数を組にして , その差として表現する – (x,y) という組で x-y という整数を表す ● (0,2),(3,5),(100000,100002) はすべて -2 を表す ● (x1,y1)+(x2,y2)=(x1+x2,y1+y2) ● (x1,y1)-(x2,y2)=(x1+y2,x2+y1) ● (x1,y1)*(x2,y2)=(x1*x2+y1*y2,x1*y2+x2*y1) ● 適宜片方が 0 になるまで引き算して数字が爆発的に増えるの を防ぐ
Advertisement