aboutsummaryrefslogtreecommitdiffhomepage
path: root/services/nuldoc/content/posts/2022-09-29
diff options
context:
space:
mode:
Diffstat (limited to 'services/nuldoc/content/posts/2022-09-29')
-rw-r--r--services/nuldoc/content/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line.md (renamed from services/nuldoc/content/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line.dj)40
1 files changed, 12 insertions, 28 deletions
diff --git a/services/nuldoc/content/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line.dj b/services/nuldoc/content/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line.md
index c23341d..3665b7f 100644
--- a/services/nuldoc/content/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line.dj
+++ b/services/nuldoc/content/posts/2022-09-29/write-fizzbuzz-in-php-2-letters-per-line.md
@@ -15,28 +15,22 @@ remark = "公開"
date = "2022-09-29"
remark = "小さな文言の修正・変更"
---
-{#intro}
-# 記事の構成について
+# 記事の構成について {#intro}
この記事は、普通の fizzbuzz を徐々に変形して最終形にしていく、という構成で書かれている。
最終形を見てどのような仕組みで動いているのか解読してから解説を読みたい、というかたがいれば、
[このページ](https://gist.github.com/nsfisis/04c227d5a419867472a0b23a83ad2919#file-fizzbuzz-php-2-letters-per-line-and-supports-php-8-x-without-warnings)
にソースコードがあるので、そちらを先に見てほしい。
-{#regulations}
-# レギュレーション
+# レギュレーション {#regulations}
PHP で、次のような制約の下に fizzbuzz を書いた。
* 1行あたりの文字数は2文字までに収めること (ただし `<?php` タグは除く)
-
* 厳密な定義: `<?php` タグ以降のソースコードが、2 byte ごとにラインフィード (LF) で区切られること
-
* スペースやタブを使用しないこと
* ループのアンロールをしないこと
-
* 100 回ループの代わりに 100 回コードをコピペ、というのは禁止
-
* PHP 7.4〜8.1 で動作すること
* 実行時に Notice や Warning が出ないこと
* 標準的なインストール構成の PHP で実現できること (デフォルトで有効になっていない拡張等を使わないこと)
@@ -46,8 +40,7 @@ PHP で、次のような制約の下に fizzbuzz を書いた。
を使うことができ、文字どおり1行2文字で書ける。
ただ、このオプションはデフォルト off になっている環境が多いようなので、今回は使わないことにした。
-{#problems}
-# 主な障害
+# 主な障害 {#problems}
1行あたりの文字数など、適当に改行を挟めばいいだけではないのか?
@@ -166,11 +159,9 @@ a'
これらの障害をどのように乗り越えるのか、次節から見ていく。
-{#commentary}
-# 解説
+# 解説 {#commentary}
-{#normal-fizzbuzz}
-## 普通の (?) fizzbuzz
+## 普通の (?) fizzbuzz {#normal-fizzbuzz}
まずは普通に書くとしよう。
@@ -184,8 +175,7 @@ for ($i = 1; $i < 100; $i++) {
素直に書いた fizzbuzz とは言い難いが、このくらいは普通だということにしておかないと、この先がやっていられないので許してほしい。
-{#remove-keywords}
-## `for` の排除
+## `for` の排除 {#remove-keywords}
`for` は、3文字もある長いキーワードである。
こんなものは使えない。`array_` 系の関数を使って、適当に置き換えるとしよう。
@@ -205,8 +195,7 @@ printf((($i % 3 ? '' : 'Fizz') . ($i % 5 ? '' : 'Buzz') ?: $i) . "\n"),
`for` よりも長いトークンが現れてしまったが、これは次節で直すことにする。
なお、`echo` は文 (statement) であり式 (expression) ではないので、式である `printf` に置き換えた。
-{#shorten-function-invocation}
-## 関数呼び出しの短縮
+## 関数呼び出しの短縮 {#shorten-function-invocation}
`range`、`array_walk`、`printf` は長すぎるのでどうにかせねばならない。
ここで、PHP の可変関数を使う。可変関数とは、関数名が文字列として入った変数を経由して、関数を呼び出す機能である。
@@ -231,8 +220,7 @@ $p((($i % 3 ? '' : 'Fizz') . ($i % 5 ? '' : 'Buzz') ?: $i) . "\n"),
また `'Fizz'` や `'Buzz'` はどうやって 1 行 2 文字に収めるのか。
次のテクニックへ移ろう。
-{#incompatible-solution}
-## 余談: PHP 8.x で動作しなくてもいいなら
+## 余談: PHP 8.x で動作しなくてもいいなら {#incompatible-solution}
今回使ったテクニックを説明する前に、余談として、文字列リテラルの短縮法として今回採用しなかったものを紹介する。
@@ -267,8 +255,7 @@ F.
むしろ、このことがわかっていたからこそ PHP 8.x での動作を要件に課したところがある。
-{#shorten-string-literals}
-## 文字列リテラルの短縮
+## 文字列リテラルの短縮 {#shorten-string-literals}
実際に使った手法の説明に移る。
@@ -347,8 +334,7 @@ echo "$r\n";
備考: `Buzz` 中にある小文字の `u` は、このロジックだと non-printable な文字になってしまう。
ここまでのテクニックを駆使すれば回避するのはそう難しくないので、考えてみてほしい。
-{#stretched-fizzbuzz}
-# 完成系
+# 完成系 {#stretched-fizzbuzz}
完成したものがこちら。
@@ -504,16 +490,14 @@ $i
);
```
-{#outro}
-# 感想など
+# 感想など {#outro}
PHP は、スクリプト言語の中だとシンタックスシュガーが少ない (体感)。
この挑戦は不可能に思われたが、PHP マニュアルとにらめっこしていたらなんとかなった。
みんなもプログラムを細長くしよう。
-{#alternative-solution}
-# 余談2: 別解
+# 余談2: 別解 {#alternative-solution}
PHP では、バッククォートを使ってシェルを呼び出せる。
これは `shell_exec` 関数と等価である。