diff options
Diffstat (limited to 'services/nuldoc/content/posts/2022-04-09')
| -rw-r--r-- | services/nuldoc/content/posts/2022-04-09/phperkaigi-2022-tokens.md (renamed from services/nuldoc/content/posts/2022-04-09/phperkaigi-2022-tokens.dj) | 75 |
1 files changed, 25 insertions, 50 deletions
diff --git a/services/nuldoc/content/posts/2022-04-09/phperkaigi-2022-tokens.dj b/services/nuldoc/content/posts/2022-04-09/phperkaigi-2022-tokens.md index 3956583..e5f5541 100644 --- a/services/nuldoc/content/posts/2022-04-09/phperkaigi-2022-tokens.dj +++ b/services/nuldoc/content/posts/2022-04-09/phperkaigi-2022-tokens.md @@ -17,8 +17,7 @@ remark = "公開" date = "2022-04-16" remark = "2問目、3問目の解説を追加、1問目に加筆" --- -{#intro} -# はじめに +# はじめに {#intro} 本日開始された [PHPerKaigi 2022](https://phperkaigi.jp/2022/) の PHPer チャレンジにおいて、弊社 @@ -27,13 +26,11 @@ remark = "2問目、3問目の解説を追加、1問目に加筆" リポジトリはこちら: https://github.com/nsfisis/PHPerKaigi2022-tokens -{#q1-brainfuck} -# 第1問 brainf_ck.php +# 第1問 brainf_ck.php {#q1-brainfuck} ソースコードはこちら。実行には PHP 8.1 以上が必要なので注意。 -{filename="brainf_ck.php"} -```php +```php filename="brainf_ck.php" <?php declare(strict_types=0O1); @@ -107,17 +104,14 @@ $🐘([ この問題は、単に適切なバージョンの PHP で動かせばトークンが得られる。 -{#commentary} -## 解説 +## 解説 {#commentary} -{#emoji} -### 絵文字 +### 絵文字 {#emoji} まず目につくのは大量の絵文字だろう。 PHP は識別子に使用できる文字の範囲が広く、絵文字も使うことができる。 -{#brainfuck} -### プログラム全体 +### プログラム全体 {#brainfuck} Brainf\*ck のインタプリタとプログラムになっている。 Brainf\*ck とは、難解プログラミング言語のひとつであり、ここで説明するよりも @@ -169,22 +163,19 @@ https://ja.wikipedia.org/wiki/Brainfuck なお、`$🐘` はいわゆる main 関数であり、プログラムの実行部分である。 -{#emoji-selection} -### 絵文字の選択 +### 絵文字の選択 {#emoji-selection} おおよそ意味に合致するよう選んでいるが、`$🤡` と `$🎪` は弊社デジタルサーカスにちなんでいる。 また、`$🐘` は PHP のマスコットの象に由来する。 -{#strict-types} -### strict_types +### strict_types {#strict-types} `declare` 文の `strict_types` に指定できるのは、`0` か `1` の数値リテラルだが、 `0x0` や `0b1` のような値も受け付ける。 今回は、PHP 8.1 から追加された、`0O` または `0o` から始まる八進数リテラルを使った。 -{#url} -### URL +### URL {#url} ソースコードのライセンスを示したこの部分だが、 @@ -195,8 +186,7 @@ https://creativecommons.org/publicdomain/zero/1.0/ 完全に合法な PHP のコードである。 `https:` 部分はラベル、`//` 以降は行コメントになっている。 -{#numbers} -### リテラルなしで数値を生成する +### リテラルなしで数値を生成する {#numbers} ソースコード中に、ほとんど数値リテラルが書かれていないことにお気づきだろうか。 PHP では、型変換を利用することで任意の整数を作り出すことができる。 @@ -220,16 +210,14 @@ assert(10 === +(![].+!![])); によって文字列を `false` にし、`+` によって `false` を `0` にし、さらにビット反転して `-1` にしている。 -{#conditionals} -### `if` 文なしで条件分岐 +### `if` 文なしで条件分岐 {#conditionals} 三項演算子ないし `match` 式を使うことで、`if` を一切書かずに条件分岐ができる。 また、`&&` / `||` も使えることがある。 遅延評価が不要なケースでは、`[$t, $f][$cond]` のような形で分岐することもできる。 -{#loops} -### `while`、`for` 文なしでループ +### `while`、`for` 文なしでループ {#loops} 不動点コンビネータを使って無名再帰する (詳しい説明は省略する。これらの単語で検索してほしい)。 ここでは、一般に @@ -242,13 +230,11 @@ Z コンビネータとして知られるものを使った (`$z`)。 ので、 あまりに長い brainf*ck プログラムを書くとスタックオーバーフローする。 -{#q2-riddle} -# 第2問 riddle.php +# 第2問 riddle.php {#q2-riddle} ソースコードはこちら。実行には PHP 8.0 以上が必要なので注意。 -{filename="riddle.php"} -```php +```php filename="riddle.php" <?php /********************************************************* @@ -291,8 +277,7 @@ foreach ($token as $x) { ここでは、私の想定解を解説する。 -{#code-reading} -## 読解 +## 読解 {#code-reading} まずはソースコードを読んでいく。 @@ -328,8 +313,7 @@ $x = implode("\n", str_split($x, length: 5)); 5文字ごとに区切ったあと、改行で結合している。 -{#hint} -## ヒント +## ヒント {#hint} 次に、ソースコードに書いてあるヒントを読んでいく。 @@ -343,8 +327,7 @@ $x = implode("\n", str_split($x, length: 5)); になるのではないかと予想される (なお、このことは、リポジトリの README ファイルに追加ヒントとして書かれている)。 -{#solve} -## 解く +## 解く {#solve} ここまでわかれば、あと一歩で解ける。すなわち、`0x14B499C` が `#` に変換されるような `N` を見つければよい。 @@ -399,13 +382,11 @@ echo "N = $n\n"; これを実行すると、`N` が得られる。 -{#q3-toquine} -# 第3問 toquine.php +# 第3問 toquine.php {#q3-toquine} ソースコードはこちら。 -{filename="toquine.php"} -```php +```php filename="toquine.php" <?php // License: https://creativecommons.org/publicdomain/zero/1.0/ @@ -445,11 +426,9 @@ $ php toquine.php | php | php | php | ... 実際にはもう少しパイプで繋げなければならない。 -{#commentary} -## 解説 +## 解説 {#commentary} -{#quine} -### プログラム全体 +### プログラム全体 {#quine} コメントにもあるとおり、これは quine (風) のプログラムになっている。 Quine @@ -458,22 +437,19 @@ Quine このプログラムは、実行すると自身とほとんど同じプログラムを出力する。 異なるのはトークンになっている部分のみである。 -{#tokens} -### トークン +### トークン {#tokens} `$xs` がトークンに対応している。変換のロジックは `riddle.php` とほぼ同じなので省略する。 -{#states} -### 状態保持 +### 状態保持 {#states} トークンの何文字目まで出力したかを、ソースコードを変えずに (quine なので) 覚えておく必要がある。 このプログラムでは、トークンが出力されるとソースコードがだんだんと長くなっていくのを利用して、`__LINE__` から情報を取得している。 -{#rot-13} -### ROT 13 +### ROT 13 {#rot-13} Quine は、素朴に書くとプログラムの一部が 2回記述されてしまう。 これがあまり美しくないので、`toquine.php` では、ROT 13 @@ -481,8 +457,7 @@ Quine は、素朴に書くとプログラムの一部が 2回記述されてし それにしてもなぜこんなものが標準ライブラリに……。 -{#outro} -# おわりに +# おわりに {#outro} 解いていただいたみなさん、また、難易度調整につきあっていただいた社内のみなさん、ありがとうございました。 |
