diff options
| author | nsfisis <nsfisis@gmail.com> | 2023-03-18 19:51:06 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2023-03-18 19:51:06 +0900 |
| commit | 7f15e0b8277ac8b101b4f71ce57c1c5442927141 (patch) | |
| tree | 31d54a18ede023adeb23a984c907860d667288bd /public/posts/2022-04-09/phperkaigi-2022-tokens/index.html | |
| parent | 032dc3c5e6d0ef84a9f4ea6be10e19b7f43c53b8 (diff) | |
| download | blog.nsfisis.dev-7f15e0b8277ac8b101b4f71ce57c1c5442927141.tar.gz blog.nsfisis.dev-7f15e0b8277ac8b101b4f71ce57c1c5442927141.tar.zst blog.nsfisis.dev-7f15e0b8277ac8b101b4f71ce57c1c5442927141.zip | |
fix(nuldoc): fix whitespaces being trimmed
Diffstat (limited to 'public/posts/2022-04-09/phperkaigi-2022-tokens/index.html')
| -rw-r--r-- | public/posts/2022-04-09/phperkaigi-2022-tokens/index.html | 258 |
1 files changed, 129 insertions, 129 deletions
diff --git a/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html b/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html index 29e5f78..86679f3 100644 --- a/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html +++ b/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html @@ -63,22 +63,22 @@ </ol> </section> <section id="section--_はじめに"> - <h2><a href="#section--_はじめに">はじめに</a></h2> + <h2><a href="#section--_はじめに">はじめに</a></h2> <p> - 本日開始された<a href="https://phperkaigi.jp/2022/">PHPerKaigi 2022</a>の PHPer チャレンジにおいて、弊社<a href="https://www.dgcircus.com/">デジタルサーカス株式会社</a>の問題を 3問作成した。この記事では、これらの問題の解説をおこなう。 + 本日開始された <a href="https://phperkaigi.jp/2022/">PHPerKaigi 2022</a> の PHPer チャレンジにおいて、弊社 <a href="https://www.dgcircus.com/">デジタルサーカス株式会社</a> の問題を 3問作成した。この記事では、これらの問題の解説をおこなう。 </p> - + <p> - リポジトリはこちら:<a href="https://github.com/nsfisis/PHPerKaigi2022-tokens">https://github.com/nsfisis/PHPerKaigi2022-tokens</a> + リポジトリはこちら: <a href="https://github.com/nsfisis/PHPerKaigi2022-tokens">https://github.com/nsfisis/PHPerKaigi2022-tokens</a> </p> </section> - + <section id="section--_第1問_brainf_ck_php"> - <h2><a href="#section--_第1問_brainf_ck_php">第1問 brainf_ck.php</a></h2> + <h2><a href="#section--_第1問_brainf_ck_php">第1問 brainf_ck.php</a></h2> <p> ソースコードはこちら。実行には PHP 8.1 以上が必要なので注意。 </p> - + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"><span class="hljs-meta"><?php</span> <span class="hljs-keyword">declare</span>(strict_types=<span class="hljs-number">0O1</span>); @@ -148,34 +148,34 @@ $👉, $👎, $📝, $👈, $📝, ]);</code></pre> - + <p> この問題は、単に適切なバージョンの PHP で動かせばトークンが得られる。 </p> - + <section id="section--_解説"> - <h3><a href="#section--_解説">解説</a></h3> + <h3><a href="#section--_解説">解説</a></h3> <section id="section--_絵文字"> - <h4><a href="#section--_絵文字">絵文字</a></h4> + <h4><a href="#section--_絵文字">絵文字</a></h4> <p> まず目につくのは大量の絵文字だろう。 PHP は識別子に使用できる文字の範囲が広く、絵文字も使うことができる。 </p> </section> - + <section id="section--_プログラム全体"> - <h4><a href="#section--_プログラム全体">プログラム全体</a></h4> + <h4><a href="#section--_プログラム全体">プログラム全体</a></h4> <p> Brainf*ck のインタプリタとプログラムになっている。 Brainf*ck とは、難解プログラミング言語のひとつであり、ここで説明するよりも Wikipedia の該当ページを読んだ方がよい。 </p> - + <p> <a href="https://ja.wikipedia.org/wiki/Brainfuck">https://ja.wikipedia.org/wiki/Brainfuck</a> </p> - + <p> なお、brainf*ck プログラムを普通の書き方で書くと、次のようになる。 </p> - + <pre class="highlight monospaced"><code>+ + + + + + + + + + [ > + + + @@ -198,132 +198,132 @@ > + + . > - . < .</code></pre> - + <p> - 実行結果はこちら:<a href="https://ideone.com/22VWmb">https://ideone.com/22VWmb</a> + 実行結果はこちら: <a href="https://ideone.com/22VWmb">https://ideone.com/22VWmb</a> </p> - + <p> それぞれの絵文字で表された関数が、各命令に対応している。 </p> - + <ul> <li> - <code>$👉</code>:<code>></code> + <code>$👉</code>: <code>></code> </li> - + <li> - <code>$👈</code>:<code><</code> + <code>$👈</code>: <code><</code> </li> - + <li> - <code>$👍</code>:<code>+</code> + <code>$👍</code>: <code>+</code> </li> - + <li> - <code>$👎</code>:<code>-</code> + <code>$👎</code>: <code>-</code> </li> - + <li> - <code>$📝</code>:<code>.</code> + <code>$📝</code>: <code>.</code> </li> - + <li> - <code>$🤡</code>:<code>[</code> + <code>$🤡</code>: <code>[</code> </li> - + <li> - <code>$🎪</code>:<code>]</code> + <code>$🎪</code>: <code>]</code> </li> </ul> - + <p> - <code>,</code>(入力) に対応する関数はない (このプログラムでは使わないので用意していない)。 + <code>,</code> (入力) に対応する関数はない (このプログラムでは使わないので用意していない)。 </p> - + <p> - なお、<code>$🐘</code>はいわゆる main 関数であり、プログラムの実行部分である。 + なお、<code>$🐘</code> はいわゆる main 関数であり、プログラムの実行部分である。 </p> </section> - + <section id="section--_絵文字の選択"> - <h4><a href="#section--_絵文字の選択">絵文字の選択</a></h4> + <h4><a href="#section--_絵文字の選択">絵文字の選択</a></h4> <p> - おおよそ意味に合致するよう選んでいるが、<code>$🤡</code>と<code>$🎪</code>は弊社デジタルサーカスにちなんでいる。 また、<code>$🐘</code>は PHP のマスコットの象に由来する。 + おおよそ意味に合致するよう選んでいるが、<code>$🤡</code> と <code>$🎪</code> は弊社デジタルサーカスにちなんでいる。 また、<code>$🐘</code> は PHP のマスコットの象に由来する。 </p> </section> - + <section id="section--_strict_types"> - <h4><a href="#section--_strict_types">strict_types</a></h4> + <h4><a href="#section--_strict_types">strict_types</a></h4> <p> - <code>declare</code>文の<code>strict_types</code>に指定できるのは、<code>0</code>か<code>1</code>の数値リテラルだが、<code>0x0</code>や<code>0b1</code>のような値も受け付ける。 今回は、PHP 8.1 から追加された、<code>0O</code>または<code>0o</code>から始まる八進数リテラルを使った。 + <code>declare</code> 文の <code>strict_types</code> に指定できるのは、<code>0</code> か <code>1</code> の数値リテラルだが、 <code>0x0</code> や <code>0b1</code> のような値も受け付ける。 今回は、PHP 8.1 から追加された、<code>0O</code> または <code>0o</code> から始まる八進数リテラルを使った。 </p> </section> - + <section id="section--_url"> - <h4><a href="#section--_url">URL</a></h4> + <h4><a href="#section--_url">URL</a></h4> <p> ソースコードのライセンスを示したこの部分だが、 </p> - + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight">https:<span class="hljs-comment">//creativecommons.org/publicdomain/zero/1.0/</span></code></pre> - + <p> - 完全に合法な PHP のコードである。<code>https:</code>部分はラベル、<code>//</code>以降は行コメントになっている。 + 完全に合法な PHP のコードである。 <code>https:</code> 部分はラベル、<code>//</code> 以降は行コメントになっている。 </p> </section> - + <section id="section--_リテラルなしで数値を生成する"> - <h4><a href="#section--_リテラルなしで数値を生成する">リテラルなしで数値を生成する</a></h4> + <h4><a href="#section--_リテラルなしで数値を生成する">リテラルなしで数値を生成する</a></h4> <p> ソースコード中に、ほとんど数値リテラルが書かれていないことにお気づきだろうか。 PHP では、型変換を利用することで任意の整数を作り出すことができる。 </p> - + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"><span class="hljs-title function_ invoke__">assert</span>(<span class="hljs-number">0</span> === +!![]); <span class="hljs-title function_ invoke__">assert</span>(<span class="hljs-number">1</span> === +![]); <span class="hljs-title function_ invoke__">assert</span>(<span class="hljs-number">2</span> === ![]+![]); <span class="hljs-title function_ invoke__">assert</span>(<span class="hljs-number">3</span> === ![]+![]+![]); <span class="hljs-title function_ invoke__">assert</span>(<span class="hljs-number">10</span> === +(![].+!![]));</code></pre> - + <p> - <code>[]</code>に<code>!</code>を適用すると<code>true</code>が返ってくる。それに<code>+</code>を適用すると、<code>bool</code>から<code>int</code>ヘの型変換が走り、<code>1</code>が生成される。<code>10</code>はさらにトリッキーだ。まず<code>1</code>と<code>0</code>を作り、<code>.</code>で文字列として結合する (<code>'10'</code>)。これに<code>+</code>を適用すると、<code>string</code>から<code>int</code>への型変換が走り、<code>10</code>が生まれる (コード量に頓着しないなら、<code>1</code>を 10 個足し合わせてももちろん 10 が作れる)。 + <code>[]</code> に <code>!</code> を適用すると <code>true</code> が返ってくる。それに <code>+</code> を適用すると、<code>bool</code> から <code>int</code> ヘの型変換が走り、<code>1</code> が生成される。<code>10</code> はさらにトリッキーだ。まず <code>1</code> と <code>0</code> を作り、<code>.</code> で文字列として結合する (<code>'10'</code>)。これに <code>+</code> を適用すると、<code>string</code> から <code>int</code> への型変換が走り、<code>10</code> が生まれる (コード量に頓着しないなら、<code>1</code> を 10 個足し合わせてももちろん 10 が作れる)。 </p> - + <p> - また、<code>error_reporting</code>に指定しているのは<code>-1</code>である。 これは、<code>!</code>によって文字列を<code>false</code>にし、<code>+</code>によって<code>false</code>を<code>0</code>にし、さらにビット反転して<code>-1</code>にしている。 + また、<code>error_reporting</code> に指定しているのは <code>-1</code> である。 これは、<code>!</code> によって文字列を <code>false</code> にし、<code>+</code> によって <code>false</code> を <code>0</code> にし、さらにビット反転して <code>-1</code> にしている。 </p> </section> - + <section id="section--_if_文なしで条件分岐"> - <h4><a href="#section--_if_文なしで条件分岐"><code>if</code>文なしで条件分岐</a></h4> + <h4><a href="#section--_if_文なしで条件分岐"><code>if</code> 文なしで条件分岐</a></h4> <p> - 三項演算子ないし<code>match</code>式を使うことで、<code>if</code>を一切書かずに条件分岐ができる。 また、<code>&&</code>/<code>||</code>も使えることがある。 遅延評価が不要なケースでは、<code>[$t, $f][$cond]</code>のような形で分岐することもできる。 + 三項演算子ないし <code>match</code> 式を使うことで、<code>if</code> を一切書かずに条件分岐ができる。 また、<code>&&</code> / <code>||</code> も使えることがある。 遅延評価が不要なケースでは、<code>[$t, $f][$cond]</code> のような形で分岐することもできる。 </p> </section> - + <section id="section--_whilefor_文なしでループ"> - <h4><a href="#section--_whilefor_文なしでループ"><code>while</code>、<code>for</code>文なしでループ</a></h4> + <h4><a href="#section--_whilefor_文なしでループ"><code>while</code>、<code>for</code> 文なしでループ</a></h4> <p> 不動点コンビネータを使って無名再帰する (詳しい説明は省略する。これらの単語で検索してほしい)。 ここでは、一般に Z コンビネータとして知られるものを使った (<code>$z</code>)。 </p> - + <p> - 実際のところ、<code>$🤡</code>や<code>$🎪</code>、<code>$🐘</code>は、一度 Scheme (Lisp の一種) で書いてから PHP に翻訳する形で記述した。 + 実際のところ、<code>$🤡</code> や <code>$🎪</code>、<code>$🐘</code> は、一度 Scheme (Lisp の一種) で書いてから PHP に翻訳する形で記述した。 </p> - + <p> なお、PHP は末尾再帰の最適化をおこなわない (少なくとも今のところは) ので、 あまりに長い brainf*ck プログラムを書くとスタックオーバーフローする。 </p> </section> </section> </section> - + <section id="section--_第2問_riddle_php"> - <h2><a href="#section--_第2問_riddle_php">第2問 riddle.php</a></h2> + <h2><a href="#section--_第2問_riddle_php">第2問 riddle.php</a></h2> <p> ソースコードはこちら。実行には PHP 8.0 以上が必要なので注意。 </p> - + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"><span class="hljs-meta"><?php</span> <span class="hljs-comment">/********************************************************* @@ -358,99 +358,99 @@ <span class="hljs-variable">$x</span> = <span class="hljs-title function_ invoke__">implode</span>(<span class="hljs-string">"\n"</span>, <span class="hljs-title function_ invoke__">str_split</span>(<span class="hljs-variable">$x</span>, <span class="hljs-attr">length</span>: <span class="hljs-number">5</span>)); <span class="hljs-keyword">echo</span> <span class="hljs-string">"<span class="hljs-subst">{$x}</span>\n\n"</span>; }</code></pre> - + <p> - さて、この問題はさきほどのように単純に実行しただけでは、謎のブロックが表示されるだけでトークンは得られない。 トークンを得るためには、ソースコードを読み、定数<code>N</code>を特定する必要がある。 + さて、この問題はさきほどのように単純に実行しただけでは、謎のブロックが表示されるだけでトークンは得られない。 トークンを得るためには、ソースコードを読み、定数 <code>N</code> を特定する必要がある。 </p> - + <p> ここでは、私の想定解を解説する。 </p> - + <section id="section--_読解"> - <h3><a href="#section--_読解">読解</a></h3> + <h3><a href="#section--_読解">読解</a></h3> <p> まずはソースコードを読んでいく。 </p> - + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"><span class="hljs-variable">$token</span> = [ <span class="hljs-comment">// 略</span> ];</code></pre> - + <p> - 数値からなる<code>$token</code>があり、各要素をループしている。 + 数値からなる <code>$token</code> があり、各要素をループしている。 </p> - + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"> <span class="hljs-variable">$x</span> = <span class="hljs-variable">$x</span> ^ N;</code></pre> - + <p> まずは排他的論理和 (xor) を取り、 </p> - + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"> <span class="hljs-variable">$x</span> = <span class="hljs-title function_ invoke__">sprintf</span>(<span class="hljs-string">'%025b'</span>, <span class="hljs-variable">$x</span>);</code></pre> - + <p> 二進数に変換して、 </p> - + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"> <span class="hljs-variable">$x</span> = <span class="hljs-title function_ invoke__">str_replace</span>(<span class="hljs-attr">search</span>: [<span class="hljs-string">'0'</span>, <span class="hljs-string">'1'</span>], <span class="hljs-attr">replace</span>: [<span class="hljs-string">' '</span>, <span class="hljs-string">'#'</span>], <span class="hljs-attr">subject</span>: <span class="hljs-variable">$x</span>);</code></pre> - + <p> - 0 を空白に、1 を<code>#</code>にし、 + 0 を空白に、1 を <code>#</code> にし、 </p> - + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"> <span class="hljs-variable">$x</span> = <span class="hljs-title function_ invoke__">implode</span>(<span class="hljs-string">"\n"</span>, <span class="hljs-title function_ invoke__">str_split</span>(<span class="hljs-variable">$x</span>, <span class="hljs-attr">length</span>: <span class="hljs-number">5</span>));</code></pre> - + <p> 5文字ごとに区切ったあと、改行で結合している。 </p> </section> - + <section id="section--_ヒント"> - <h3><a href="#section--_ヒント">ヒント</a></h3> + <h3><a href="#section--_ヒント">ヒント</a></h3> <p> 次に、ソースコードに書いてあるヒントを読んでいく。 </p> - + <ul> <li> - <code>N</code>それ自体は、42 や 8128 といったような特別な意味を持たず、ランダムに決められている + <code>N</code> それ自体は、42 や 8128 といったような特別な意味を持たず、ランダムに決められている </li> - + <li> - <code>$token</code>の各要素は、1文字を表す + <code>$token</code> の各要素は、1文字を表す </li> - + <li> 1文字は 5x5 のセルからなる </li> - + <li> 出力されるのは、完全な PHPer トークンである </li> </ul> - + <p> - ここで、PHPer トークンは必ず<code>#</code>記号から始まることを思いだすと、<code>$token</code>の最初の数字<code>0x14B499C</code>は、変換の結果<code>#</code>になるのではないかと予想される (なお、このことは、リポジトリの README ファイルに追加ヒントとして書かれている)。 + ここで、PHPer トークンは必ず <code>#</code> 記号から始まることを思いだすと、 <code>$token</code> の最初の数字 <code>0x14B499C</code> は、変換の結果 <code>#</code> になるのではないかと予想される (なお、このことは、リポジトリの README ファイルに追加ヒントとして書かれている)。 </p> </section> - + <section id="section--_解く"> - <h3><a href="#section--_解く">解く</a></h3> + <h3><a href="#section--_解く">解く</a></h3> <p> - ここまでわかれば、あと一歩で解ける。すなわち、<code>0x14B499C</code>が<code>#</code>に変換されるような<code>N</code>を見つければよい。 + ここまでわかれば、あと一歩で解ける。すなわち、<code>0x14B499C</code> が <code>#</code> に変換されるような <code>N</code> を見つければよい。 </p> - + <p> - <code>N</code>は高々 + <code>N</code> は高々 </p> - + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"><span class="hljs-title function_ invoke__">assert</span>(<span class="hljs-number">0</span> <= N && N <= <span class="hljs-number">0b11111_11111_11111_11111_11111</span>);</code></pre> - + <p> なのでブルートフォースしてもよいが、ここではブルートフォースしない方法を紹介する。 </p> - + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"><span class="hljs-meta"><?php</span> <span class="hljs-variable">$x</span> = <span class="hljs-number">0x14B499C</span>; @@ -467,11 +467,11 @@ <span class="hljs-string">" # # \n"</span> . <span class="hljs-string">"#####\n"</span> . <span class="hljs-string">" # # "</span>);</code></pre> - + <p> この一連の変換に対する逆変換を考えると、次のようになる。 </p> - + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"><span class="hljs-meta"><?php</span> <span class="hljs-variable">$x</span> = @@ -488,19 +488,19 @@ <span class="hljs-variable">$n</span> = <span class="hljs-variable">$x</span> ^ <span class="hljs-number">0x14B499C</span>; <span class="hljs-keyword">echo</span> <span class="hljs-string">"N = <span class="hljs-subst">$n</span>\n"</span>;</code></pre> - + <p> - これを実行すると、<code>N</code>が得られる。 + これを実行すると、<code>N</code> が得られる。 </p> </section> </section> - + <section id="section--_第3問_toquine_php"> - <h2><a href="#section--_第3問_toquine_php">第3問 toquine.php</a></h2> + <h2><a href="#section--_第3問_toquine_php">第3問 toquine.php</a></h2> <p> ソースコードはこちら。 </p> - + <pre class="highlight" language="php" linenumbering="unnumbered"><code class="highlight"><span class="hljs-meta"><?php</span> <span class="hljs-comment">// License: https://creativecommons.org/publicdomain/zero/1.0/</span> @@ -530,67 +530,67 @@ <span class="hljs-variable">$t</span> .= <span class="hljs-title function_ invoke__">implode</span>(<span class="hljs-string">"\n"</span>, <span class="hljs-title function_ invoke__">str_split</span>(<span class="hljs-title function_ invoke__">str_replace</span>([<span class="hljs-string">'0'</span>,<span class="hljs-string">'1'</span>], [<span class="hljs-string">' '</span>,<span class="hljs-string">'##'</span>], <span class="hljs-title function_ invoke__">sprintf</span>(<span class="hljs-title function_ invoke__">chr</span>(<span class="hljs-number">37</span>) . <span class="hljs-string">'025b'</span>, <span class="hljs-variable">$xs</span>[<span class="hljs-variable">$i</span>])), <span class="hljs-number">012</span>)) . <span class="hljs-string">"\n\n"</span>; <span class="hljs-variable">$ws</span> = <span class="hljs-title function_ invoke__">array_map</span>(fn(<span class="hljs-variable">$w</span>) => <span class="hljs-title function_ invoke__">implode</span>(<span class="hljs-string">', '</span>, <span class="hljs-variable">$w</span>), <span class="hljs-title function_ invoke__">array_chunk</span>(<span class="hljs-title function_ invoke__">array_map</span>(fn(<span class="hljs-variable">$x</span>) => <span class="hljs-title function_ invoke__">sprintf</span>(<span class="hljs-string">'0x'</span> . <span class="hljs-title function_ invoke__">chr</span>(<span class="hljs-number">37</span>) . <span class="hljs-string">'07X'</span>, <span class="hljs-variable">$x</span>), <span class="hljs-variable">$xs</span>), <span class="hljs-number">10</span>)); <span class="hljs-title function_ invoke__">printf</span>(<span class="hljs-variable">$s</span>, <span class="hljs-variable">$t</span>, <span class="hljs-title function_ invoke__">str_rot13</span>(<span class="hljs-string">"<<<'D'\n<span class="hljs-subst">{$s}</span>\nD"</span>), <span class="hljs-title function_ invoke__">implode</span>(<span class="hljs-string">",\n"</span>, <span class="hljs-variable">$ws</span>));</code></pre> - + <p> コメントにもあるとおり、次のようにして実行すれば答えがでてくる。 </p> - + <pre class="highlight" language="shell-session" linenumbering="unnumbered"><code>$ php toquine.php | php | php | php | ...</code></pre> - + <p> 実際にはもう少しパイプで繋げなければならない。 </p> - + <section id="section--_解説_2"> - <h3><a href="#section--_解説_2">解説</a></h3> + <h3><a href="#section--_解説_2">解説</a></h3> <section id="section--_プログラム全体_2"> - <h4><a href="#section--_プログラム全体_2">プログラム全体</a></h4> + <h4><a href="#section--_プログラム全体_2">プログラム全体</a></h4> <p> コメントにもあるとおり、これは quine (風) のプログラムになっている。 Quine とは、自分のソースコードをそっくりそのまま出力するようなプログラムのことである。 </p> - + <p> このプログラムは、実行すると自身とほとんど同じプログラムを出力する。 異なるのはトークンになっている部分のみである。 </p> </section> - + <section id="section--_トークン"> - <h4><a href="#section--_トークン">トークン</a></h4> + <h4><a href="#section--_トークン">トークン</a></h4> <p> - <code>$xs</code>がトークンに対応している。変換のロジックは<code>riddle.php</code>とほぼ同じなので省略する。 + <code>$xs</code> がトークンに対応している。変換のロジックは <code>riddle.php</code> とほぼ同じなので省略する。 </p> </section> - + <section id="section--_状態保持"> - <h4><a href="#section--_状態保持">状態保持</a></h4> + <h4><a href="#section--_状態保持">状態保持</a></h4> <p> - トークンの何文字目まで出力したかを、ソースコードを変えずに (quine なので) 覚えておく必要がある。 このプログラムでは、トークンが出力されるとソースコードがだんだんと長くなっていくのを利用して、<code><em>LINE</em></code>から情報を取得している。 + トークンの何文字目まで出力したかを、ソースコードを変えずに (quine なので) 覚えておく必要がある。 このプログラムでは、トークンが出力されるとソースコードがだんだんと長くなっていくのを利用して、<code><em>LINE</em></code> から情報を取得している。 </p> </section> - + <section id="section--_rot_13"> - <h4><a href="#section--_rot_13">ROT 13</a></h4> + <h4><a href="#section--_rot_13">ROT 13</a></h4> <p> - Quine は、素朴に書くとプログラムの一部が 2回記述されてしまう。 これがあまり美しくないので、<code>toquine.php</code>では、ROT 13 変換を使って難読化した。 + Quine は、素朴に書くとプログラムの一部が 2回記述されてしまう。 これがあまり美しくないので、<code>toquine.php</code> では、ROT 13 変換を使って難読化した。 </p> - + <p> それにしてもなぜこんなものが標準ライブラリに……。 </p> </section> </section> </section> - + <section id="section--_おわりに"> - <h2><a href="#section--_おわりに">おわりに</a></h2> + <h2><a href="#section--_おわりに">おわりに</a></h2> <p> 解いていただいたみなさん、また、難易度調整につきあっていただいた社内のみなさん、ありがとうございました。 </p> - + <p> 今回は直前に作りはじめたのもあり、3問だけかつ使い古されたネタばかりになってしまいましたが、 来年は 5問、より面白い問題を持っていきます。 </p> - + <p> 実はもう作りはじめているので、どうか来年もありますように……。 </p> |
