プログラミングの備忘録

プログラムをつくる過程を残すもの

プログラミング言語「Piet」を触ってみる

こんにちは。
今回は、プログラミング言語「Piet」を紹介します。


実は最近、こんなツイートをしました。


これを見て"自己紹介"を感じていただけたならそれはそれで芸術の面白さを感じますが、芸術に疎い私にはこの画像に自己を乗せるというような高尚な表現はできないので、別の意味を持たせてあります。

それが今回紹介するプログラミング言語「Piet」に関わってきます。


目次


「Piet」とは

Piet は難解プログラミング言語のひとつです。
難解とよばれる所以は、この言語の特徴である画像ソースコードとする点にあります。


公式サイト
DM's Esoteric Programming Languages - Piet

wiki
Piet - Wikipedia


名前は画家のピエト・モンドリアンに由来し、「Mondrian」という名前にしようと思ったが既にあったので「Piet」にした、といういきさつがあるようです。

ピエト・モンドリアンは『赤・青・黄のコンポジション』『ブロードウェイ・ブギウギ』などの抽象画で有名ですが、これをソースコードにしようという発想が面白い。
実際に書いてみると、はじめに挙げたようにモザイクに近いような見た目になることが多いです。

寄せて作ってみるとこんな感じになります。


仕様

Piet は画像をソースコードとしています。
実行時は基本、左上から時計回りにコーデルをたどっていき、移動の前後での色相 (Hue) と明度 (Lightness) の変化によって実行する命令を指定できます。

コーデルは色を置いてあるマスのことを指し、同じ色が接している部分ではひとまとまりとみなされます。

数値は同じ色のコーデルが何個接しているかによって表されます。


コーデルを移動する"インタプリタ"は、DP (Direction Pointer) とCC (Codel Chooser) を持っています。
DPとCCはそれぞれ、車と乗っている人それぞれの向く方向と考えると分かりやすいです。

基本的には"壁"にぶつかるまでDP方向に直進し、左上から時計回りにぐるぐる回っていくと考えてよいので、詳しい説明は省きます。


また、記憶領域としてスタックを1つ持ち、後入れ後出しで値を取り扱うことができます。


使うことのできる色は、基本色のRYGCBMとその明暗で18色、そして白黒の2色で計20色です。


既に、移動前後の色相と明度の変化により実行される命令が決まる、と書きましたが、それは以下のように決まっています。

命令はそれぞれ、

  • push: スタックに値を1つ入れる

  • pop: スタックから値を1つ出す

  • addsubtractmultiplydivide: スタックから値を2つ出して加減乗除を計算し、結果をスタックに入れる
    (除は「2つ目の値 / 1つ目の値」)

  • mod: スタックから値を2つ出し、2つ目の値を1つ目の値で割った余りをスタックに入れる

  • not: スタックから値を1つ出し、その値が0なら1を、0以外なら0をスタックに入れる

  • greater: スタックから値を2つ出し、2つ目の値が1つ目の値よりも大きければ1を、そうでなければ0をスタックにいれる

  • pointer: スタックから値を1つ出し、その値の回数だけDPを時計回りに回転させる
    (負の数なら反時計回り)

  • switch: スタックから値を1つ出し、その値の回数だけCCを切り替える
    (負の数でも同じ)

  • duplicate: スタックから値を1つ出し、同じ値を2つスタックに入れる

  • roll: スタックから値を2つ出し、1つ目の値の回数だけ、2つ目の値だけの深さへの"roll"操作を行う
    "roll"操作は、一番新しい値を"2つ目の値"番目に入れ、それよりも上にある値を1段ずつ引き上げるという操作
    (回数が負の数なら逆の操作になる)

  • in: 標準入力から値を1つ受け取り、スタックに入れる
    (numberでは数字を、charでは文字を10進数の unicode で受け取る)

  • out: スタックから値を1つ出し、標準出力に出力する
    (numberでは数字を、charでは数字を文字に変換 (10進数の unicode) して出力する)

を意味しています。

また、白では何もせず、黒は"壁"としての役割を持ちます。


基本的な部分は説明できたかと思いますが、不十分な部分もあると思いますので適宜他のサイトを見てください。

[Piet入門編]Piet入門1 - 趣味プログラミングの部屋


コーディング

さて、だらだらと説明を書きましたが、百聞は一見に如かずとも言いますし、やってみた方がわかりやすいかと思います。


実際にコードを"描いて"いくわけですが、ペイントソフトや Excel でやるとなると、1ドット単位での操作や命令の難解さで厳しいです。

エディタが提供されていますので、積極的に利用しましょう。

piet-editor.github.io

github.com


今回は Pietron を使います。

実行画面はこんな感じです。


命令は色相と明度の変化で決まるので、初めの色は何でも大丈夫です。
なので、以下に挙げた12種類のコードは、全て明度変化1 (1 Darker) で、1を push する命令となっています。


自己紹介

それでは、この記事の初めに挙げた「自己紹介」のコードを作ってみます。

自己紹介というタイトルは、その名の通り、名前を出力するコードであるということでつけました。
すなわち、実行することで「taq」と出力されます。


Piet で文字を出力するためには out(c) を使うわけですが、これはスタックにある数字を unicode とみなして文字に変換して出力しています。
なので、「t」「a」「q」それぞれを表す unicode を調べ、それを四則演算等を用いて表現する必要があります。

調べると「t」「a」「q」はそれぞれ 116、97、113 で表されることがわかりました。


続いて、これらをどのように計算するかを考えます。
「t」の 116 を例にしてみます。

$116 = 4 \times (4 \times 7 + 1)$ と表されるので、

4 (push 4)
4 4 (dup)
4 4 4 (dup)
4 4 4 4 (dup)
4 4 4 4 1 (push 1)
4 4 4 3 (sub)
4 4 7 (add)
4 28 (multi)
4 28 1 (push 1)
4 29 (add)
116 (multi)

という風にスタックを操作していって 116 を作りました。
最後に out(c) を実行して「t」を出力します。

10 × 10 のコーデルで「t」を出力するコードは以下のようになります。
念のため"壁"である黒を隅に置きましたが、無くして詰めても問題ないです。

同じ要領で 97 と 113 も作っていくと、

ぴったり収まりました。偶然です。


Pietron にはデバッグモードがあり、F7 を押すことで1つずつ進む様子を見ることができます。

スタックが変化していって、最終的に「taq」が出力される様子が見えて面白いです。


これで完成でもよかったのですが、一本道が明らかに見えていたのでなんとなく周りに関係ない色を置いてカモフラージュしてみました。


書いていませんでしたが、Piet の処理は同じ白道を何回かたどると終了するので、右端はあえて白にしています。


本家に寄せたバージョン

この言語はピエト・モンドリアンに着想を得ているということで、『赤・青・黄のコンポジション』に似せた感じで作ってみました。

経路を矢印で示してみると、

数値に関しては、四角形にぴったり収まらなかったので似た色で調整しています。


まとめ

以上、難解プログラミング言語「Piet」を紹介しました。

私自身 processing を扱っていながら芸術方面にはめっぽう疎いですが、ただの絵だと思っていたら実はソースコードで実行すると隠されたメッセージが読める、みたいなものは現代アートという感じがしてとても好きです。

また、ネタ言語とはいえチューリング完全で、今回は roll やDP・CCの操作を使っていないので、できることはもっとあろうかと思います。

みなさんもぜひ Piet を使って、processing とはまた違った「プログラミング×芸術」を楽しんでみてください。


最後まで読んでいただいてありがとうございました。また次回。