Esolangを可視化する
これはTSG Advent Calendar 2016 - Adventarの19日目の記事として書かれました。
僕が入っているTSGというサークルでesolang陣取り大会とやらが行われました(というか、行われている?)。Esolang陣取り大会のルールとかesolangの説明とかはsatosさんの記事esolangを書く - 忖度にあったのでそちらを見てください(丸投げ)。ちなみにこの記事を書いている時点で100言語のうち55言語が埋まっていますが、その55言語のうち21言語は僕が埋めました(現状1位)。やったぜ。
で、この記事では僕が埋めたHexagonyという言語の話をします。*1
コード
? { 1 0 \ > / 1 " ' < | . . > ' 2 } { / / . . . . . . . . . . . . . . . . . . : % ' * ' + { = & { } / . > ' ' ! @ . . . . < . . . . . . . . > " " * { = & \ . . / & ' ' < . . > } = .
です。*2
これで2進数を10進数に変換できます。
解説
この言語の特徴として、見て分かる通りコードが六角形をなしていて、コマンドがハニカム構造での六角形のように並んでいるわけですが、それだけでなく記憶領域もハニカム構造で埋め尽くされた平面上に存在していて、六角形の一つの辺に一つの値が保持されるという、六角形大好き仕様になっています。
コードの実行を開始すると、左上の頂点から、右に向かって実行が進んでいきます。ただし途中でミラー (/
, \
, |
, _
) に特定の方向から当たって反射したりとか分岐点 (<
, >
) に差し掛かったりとかで途中で向きが変わります。
メモリについては前述の通り六角形の辺に値が保持されるわけですが、メモリポインタというものが ある1つの辺と向きを指しています。このメモリポインタを、左前や右前の辺に前進させたり、左後ろや右後ろの辺に後退させたり、向きを反転させたりするコマンドがあります。
その他もろもろのコマンドがあったりしますが、今回使ったコマンドだけおおざっぱに紹介しておきます。
コマンド | 意味 |
---|---|
. |
何もしない (no-op) |
/ \ | _ |
ミラー(コード実行の向きを反射する) |
< > |
分岐点(< に、左から入ったときは現在の辺の値が0以下ならば右上、正ならば右下に進む。右上か右下から入った場合は左に進む。> はその180°回転) |
{ } |
メモリポインタを左前・右前に前進させる |
" ' |
メモリポインタを左後ろ・右後ろに後退させる |
= |
メモリポインタの向きを反転させる |
+ - * : % |
左前の辺の値と右前の辺の値の和・差・積・商・剰余を現在の辺にセットする |
& |
現在の辺の値が正なら右前の辺の値を、0以下なら左前の辺の値を現在の辺の値にセットする |
数字 | 現在の辺の値を10倍してその数字を足した値を現在の辺にセットする |
? |
標準入力からの数値を10進数で解釈した値を現在の辺にセットする |
! |
現在の辺の値を10進数の数値として標準出力に出力する |
@ |
実行終了 |
可視化
お題は「100桁の2進数を10進数に変換せよ」だったのですが可視化するには100桁は長すぎるので、代わりに2進数の「10110」を10進数の「22」に変換して出力する様子を可視化しました。*3
左半分ではコード上でコマンドが実行されていく様子を、右半分ではメモリの状況を示しています。10回くらいループで見たら何をやっているのかがだいたい分かりそう?(?)
このアニメーションは、デバッグオプションをつけてHexagonyインタプリタを実行すると、そのとき実行している位置とメモリの状況を逐次出力してくれるので、それを利用して作りました。画像化にはTSGの2D&3D分科会で存在を知ったProcessingというソフト(というか開発環境?)を使っています。*4
まとめ
Esolangはアート(適当)
*1:ほかの言語に関してはEsolang Writeupsの方に書いているのでそちらを見てください。
*2:実際にsubmitしたコードには要らないコマンドがあったのですがここではno-opの . に置き換えてあります。
*3:100桁のときとコードは同じです。
*4:このアニメーションは即興で作ったので完成度とかがアレなんですが、Processingは使いようによってはすごいアニメーションも作れるやばいソフトらしいです?