summaryrefslogtreecommitdiffhomepage
path: root/services/blog/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'services/blog/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html')
-rw-r--r--services/blog/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html572
1 files changed, 572 insertions, 0 deletions
diff --git a/services/blog/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html b/services/blog/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html
new file mode 100644
index 00000000..ee215a60
--- /dev/null
+++ b/services/blog/public/posts/2022-04-09/phperkaigi-2022-tokens/index.html
@@ -0,0 +1,572 @@
+<!DOCTYPE html>
+<html lang="ja-JP">
+ <head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="author" content="nsfisis">
+ <meta name="copyright" content="&copy; 2022 nsfisis">
+ <meta name="description" content="PHPerKaigi 2022 で私が作成した PHPer チャレンジ問題を解説する。">
+ <meta name="keywords" content="カンファレンス,PHP,PHPerKaigi">
+ <meta property="og:type" content="article">
+ <meta property="og:title" content="PHPerKaigi 2022 トークン問題の解説|REPL: Rest-Eat-Program Loop">
+ <meta property="og:description" content="PHPerKaigi 2022 で私が作成した PHPer チャレンジ問題を解説する。">
+ <meta property="og:site_name" content="REPL: Rest-Eat-Program Loop">
+ <meta property="og:locale" content="ja_JP">
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg">
+ <title>PHPerKaigi 2022 トークン問題の解説|REPL: Rest-Eat-Program Loop</title>
+ <link rel="stylesheet" href="/style.css?h=9513229b52eb2041b99ba1b959305633">
+ </head>
+ <body class="single">
+ <header class="header">
+ <div class="site-logo">
+ <a href="/">REPL: Rest-Eat-Program Loop</a>
+ </div>
+ <nav class="nav">
+ <ul>
+ <li>
+ <a href="/about/">About</a>
+ </li>
+ <li>
+ <a href="/posts/">Posts</a>
+ </li>
+ <li>
+ <a href="/slides/">Slides</a>
+ </li>
+ <li>
+ <a href="/tags/">Tags</a>
+ </li>
+ </ul>
+ </nav>
+ </header>
+ <main class="main">
+ <article class="post-single">
+ <header class="post-header">
+ <h1 class="post-title">PHPerKaigi 2022 トークン問題の解説</h1>
+ <ul class="post-tags">
+ <li class="tag">
+ <a href="/tags/conference/">カンファレンス</a>
+ </li>
+ <li class="tag">
+ <a href="/tags/php/">PHP</a>
+ </li>
+ <li class="tag">
+ <a href="/tags/phperkaigi/">PHPerKaigi</a>
+ </li>
+ </ul>
+ </header>
+ <div class="post-content">
+ <section id="changelog">
+ <h2><a href="#changelog">更新履歴</a></h2>
+ <ol>
+ <li class="revision">
+ <time datetime="2022-04-09">2022-04-09</time>: 公開
+ </li>
+ <li class="revision">
+ <time datetime="2022-04-16">2022-04-16</time>: 2問目、3問目の解説を追加、1問目に加筆
+ </li>
+ </ol>
+ </section>
+ <section id="section--intro">
+ <h2><a href="#section--intro">はじめに</a></h2>
+ <p>
+ 本日開始された <a href="https://phperkaigi.jp/2022/" rel="noreferrer" target="_blank">PHPerKaigi 2022</a> の PHPer チャレンジにおいて、弊社 <a href="https://www.dgcircus.com/" rel="noreferrer" target="_blank">デジタルサーカス株式会社</a> の問題を 3問作成した。この記事では、これらの問題の解説をおこなう。
+ </p>
+ <p>
+ リポジトリはこちら: <a href="https://github.com/nsfisis/PHPerKaigi2022-tokens" rel="noreferrer" target="_blank">https://github.com/nsfisis/PHPerKaigi2022-tokens</a>
+ </p>
+ </section>
+ <section id="section--q1-brainfuck">
+ <h2><a href="#section--q1-brainfuck">第1問 brainf_ck.php</a></h2>
+ <p>
+ ソースコードはこちら。実行には PHP 8.1 以上が必要なので注意。
+ </p>
+ <div class="codeblock">
+ <div class="filename">
+ brainf_ck.php
+ </div>
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#D73A49">declare</span><span style="color:#24292E">(</span><span style="color:#005CC5">strict_types</span><span style="color:#D73A49">=</span><span style="color:#005CC5">0O1</span><span style="color:#24292E">);</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#D73A49">namespace</span><span style="color:#6F42C1"> Dgcircus\PHPerKaigi\Y2022</span><span style="color:#24292E">;</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#6A737D">/**</span></span>
+<span class="line"><span style="color:#6A737D"> * </span><span style="color:#D73A49">@todo</span></span>
+<span class="line"><span style="color:#6A737D"> * Run this program to acquire a PHPer token.</span></span>
+<span class="line"><span style="color:#6A737D"> */</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#005CC5">https</span><span style="color:#D73A49">:</span><span style="color:#6A737D">//creativecommons.org/publicdomain/zero/1.0/</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#005CC5">\error_reporting</span><span style="color:#24292E">(</span><span style="color:#D73A49">~+!</span><span style="color:#032F62">'We are hiring!'</span><span style="color:#24292E">);</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#24292E">$z </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($f) => (</span><span style="color:#D73A49">fn</span><span style="color:#24292E">($x) => $f(</span><span style="color:#D73A49">fn</span><span style="color:#24292E">(</span><span style="color:#D73A49">...</span><span style="color:#24292E">$xs) => $x($x)(</span><span style="color:#D73A49">...</span><span style="color:#24292E">$xs)))(</span><span style="color:#D73A49">fn</span><span style="color:#24292E">($x) => $f(</span><span style="color:#D73A49">fn</span><span style="color:#24292E">(</span><span style="color:#D73A49">...</span><span style="color:#24292E">$xs) => $x($x)(</span><span style="color:#D73A49">...</span><span style="color:#24292E">$xs)));</span></span>
+<span class="line"><span style="color:#24292E">$id </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> \</span><span style="color:#6F42C1">spl_object_id</span><span style="color:#24292E">(</span><span style="color:#D73A49">...</span><span style="color:#24292E">);</span></span>
+<span class="line"><span style="color:#24292E">$put </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($c) => </span><span style="color:#005CC5">\</span><span style="color:#005CC5">printf</span><span style="color:#24292E">(</span><span style="color:#032F62">'%c'</span><span style="color:#24292E">, $c);</span></span>
+<span class="line"><span style="color:#24292E">$mm </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($p, $n) => </span><span style="color:#D73A49">new</span><span style="color:#005CC5"> \ArrayObject</span><span style="color:#24292E">(</span><span style="color:#005CC5">\array_fill</span><span style="color:#24292E">(</span><span style="color:#D73A49">+!!</span><span style="color:#24292E">[], $n, $p));</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#24292E">$👉 </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($m, $p, $b, $e, $mp, $pc) => [</span><span style="color:#D73A49">++</span><span style="color:#24292E">$mp, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc];</span></span>
+<span class="line"><span style="color:#24292E">$👈 </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($m, $p, $b, $e, $mp, $pc) => [</span><span style="color:#D73A49">--</span><span style="color:#24292E">$mp, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc];</span></span>
+<span class="line"><span style="color:#24292E">$👍 </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($m, $p, $b, $e, $mp, $pc) => [$mp, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$m[$mp]];</span></span>
+<span class="line"><span style="color:#24292E">$👎 </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($m, $p, $b, $e, $mp, $pc) => [$mp, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc, </span><span style="color:#D73A49">--</span><span style="color:#24292E">$m[$mp]];</span></span>
+<span class="line"><span style="color:#24292E">$📝 </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($m, $p, $b, $e, $mp, $pc) => [$mp, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc, $put($m[$mp])];</span></span>
+<span class="line"><span style="color:#24292E">$🤡 </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($m, $p, $b, $e, $mp, $pc) => </span><span style="color:#D73A49">match</span><span style="color:#24292E"> ($m[$mp]) {</span></span>
+<span class="line"><span style="color:#D73A49"> +!!</span><span style="color:#24292E">[] </span><span style="color:#D73A49">=></span><span style="color:#24292E"> [$mp, $z(</span><span style="color:#D73A49">fn</span><span style="color:#24292E">($loop) => </span><span style="color:#D73A49">fn</span><span style="color:#24292E">($pc, $n) => </span><span style="color:#D73A49">match</span><span style="color:#24292E"> ($id($p[$pc])) {</span></span>
+<span class="line"><span style="color:#24292E"> $b </span><span style="color:#D73A49">=></span><span style="color:#24292E"> $loop(</span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$n),</span></span>
+<span class="line"><span style="color:#24292E"> $e </span><span style="color:#D73A49">=></span><span style="color:#24292E"> $n </span><span style="color:#D73A49">===</span><span style="color:#D73A49"> +!!</span><span style="color:#24292E">[] </span><span style="color:#D73A49">?</span><span style="color:#D73A49"> ++</span><span style="color:#24292E">$pc </span><span style="color:#D73A49">:</span><span style="color:#24292E"> $loop(</span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc, </span><span style="color:#D73A49">--</span><span style="color:#24292E">$n),</span></span>
+<span class="line"><span style="color:#D73A49"> default</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> $loop(</span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc, $n),</span></span>
+<span class="line"><span style="color:#24292E"> })($pc, </span><span style="color:#D73A49">-!</span><span style="color:#24292E">[])],</span></span>
+<span class="line"><span style="color:#D73A49"> default</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> [$mp, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc],</span></span>
+<span class="line"><span style="color:#24292E">};</span></span>
+<span class="line"><span style="color:#24292E">$🎪 </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($m, $p, $b, $e, $mp, $pc) => </span><span style="color:#D73A49">match</span><span style="color:#24292E"> ($m[$mp]) {</span></span>
+<span class="line"><span style="color:#D73A49"> +!!</span><span style="color:#24292E">[] </span><span style="color:#D73A49">=></span><span style="color:#24292E"> [$mp, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$pc],</span></span>
+<span class="line"><span style="color:#D73A49"> default</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> [$mp, $z(</span><span style="color:#D73A49">fn</span><span style="color:#24292E">($loop) => </span><span style="color:#D73A49">fn</span><span style="color:#24292E">($pc, $n) => </span><span style="color:#D73A49">match</span><span style="color:#24292E"> ($id($p[$pc])) {</span></span>
+<span class="line"><span style="color:#24292E"> $e </span><span style="color:#D73A49">=></span><span style="color:#24292E"> $loop(</span><span style="color:#D73A49">--</span><span style="color:#24292E">$pc, </span><span style="color:#D73A49">++</span><span style="color:#24292E">$n),</span></span>
+<span class="line"><span style="color:#24292E"> $b </span><span style="color:#D73A49">=></span><span style="color:#24292E"> $n </span><span style="color:#D73A49">===</span><span style="color:#D73A49"> +!!</span><span style="color:#24292E">[] </span><span style="color:#D73A49">?</span><span style="color:#24292E"> $pc</span><span style="color:#D73A49">+!</span><span style="color:#24292E">[] </span><span style="color:#D73A49">:</span><span style="color:#24292E"> $loop(</span><span style="color:#D73A49">--</span><span style="color:#24292E">$pc, </span><span style="color:#D73A49">--</span><span style="color:#24292E">$n),</span></span>
+<span class="line"><span style="color:#D73A49"> default</span><span style="color:#D73A49"> =></span><span style="color:#24292E"> $loop(</span><span style="color:#D73A49">--</span><span style="color:#24292E">$pc, $n),</span></span>
+<span class="line"><span style="color:#24292E"> })($pc, </span><span style="color:#D73A49">-!</span><span style="color:#24292E">[])],</span></span>
+<span class="line"><span style="color:#24292E">};</span></span>
+<span class="line"><span style="color:#24292E">$🐘 </span><span style="color:#D73A49">=</span><span style="color:#D73A49"> fn</span><span style="color:#24292E">($p) => $z(</span><span style="color:#D73A49">fn</span><span style="color:#24292E">($loop) => </span><span style="color:#D73A49">fn</span><span style="color:#24292E">($m, $p, $b, $e, $mp, $pc) =></span></span>
+<span class="line"><span style="color:#005CC5"> isset</span><span style="color:#24292E">($p[$pc]) </span><span style="color:#D73A49">&#x26;&#x26;</span><span style="color:#24292E"> $loop($m, $p, $b, $e, </span><span style="color:#D73A49">...</span><span style="color:#24292E">($p[$pc]($m, $p, $b, $e, $mp, $pc)))</span></span>
+<span class="line"><span style="color:#24292E">)($mm(</span><span style="color:#D73A49">+!!</span><span style="color:#24292E">[], </span><span style="color:#D73A49">+</span><span style="color:#24292E">(</span><span style="color:#D73A49">!</span><span style="color:#24292E">[]</span><span style="color:#D73A49">.</span><span style="color:#D73A49">!</span><span style="color:#24292E">[])), $p, $id($🤡), $id($🎪), </span><span style="color:#D73A49">+!!</span><span style="color:#24292E">[], </span><span style="color:#D73A49">+!!</span><span style="color:#24292E">[]);</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#24292E">$🐘([</span></span>
+<span class="line"><span style="color:#24292E"> $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍,</span></span>
+<span class="line"><span style="color:#24292E"> $🤡,</span></span>
+<span class="line"><span style="color:#24292E"> $👉, $👍, $👍, $👍,</span></span>
+<span class="line"><span style="color:#24292E"> $👉, $👍, $👍, $👍, $👍, $👍,</span></span>
+<span class="line"><span style="color:#24292E"> $👉, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍,</span></span>
+<span class="line"><span style="color:#24292E"> $👉, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍, $👍,</span></span>
+<span class="line"><span style="color:#24292E"> $👈, $👈, $👈, $👈, $👎,</span></span>
+<span class="line"><span style="color:#24292E"> $🎪,</span></span>
+<span class="line"><span style="color:#24292E"> $👉, $👍, $👍, $👍, $👍, $👍, $📝,</span></span>
+<span class="line"><span style="color:#24292E"> $👎, $👎, $📝,</span></span>
+<span class="line"><span style="color:#24292E"> $👉, $👎, $👎, $👎, $📝,</span></span>
+<span class="line"><span style="color:#24292E"> $👉, $👎, $👎, $👎, $📝,</span></span>
+<span class="line"><span style="color:#24292E"> $👎, $👎, $📝,</span></span>
+<span class="line"><span style="color:#24292E"> $👎, $📝,</span></span>
+<span class="line"><span style="color:#24292E"> $👈, $📝,</span></span>
+<span class="line"><span style="color:#24292E"> $👉, $👉, $👎, $👎, $📝,</span></span>
+<span class="line"><span style="color:#24292E"> $👍, $👍, $👍, $👍, $👍, $👍, $👍, $📝,</span></span>
+<span class="line"><span style="color:#24292E"> $👈, $👎, $👎, $👎, $👎, $📝,</span></span>
+<span class="line"><span style="color:#24292E"> $👈, $📝,</span></span>
+<span class="line"><span style="color:#24292E"> $👉, $👍, $👍, $📝,</span></span>
+<span class="line"><span style="color:#24292E"> $👉, $👎, $📝,</span></span>
+<span class="line"><span style="color:#24292E"> $👈, $📝,</span></span>
+<span class="line"><span style="color:#24292E">]);</span></span></code></pre>
+ </div>
+ <p>
+ この問題は、単に適切なバージョンの PHP で動かせばトークンが得られる。
+ </p>
+ <section id="section--q1-brainfuck--commentary">
+ <h3><a href="#section--q1-brainfuck--commentary">解説</a></h3>
+ <section id="section--q1-brainfuck--commentary--emoji">
+ <h4><a href="#section--q1-brainfuck--commentary--emoji">絵文字</a></h4>
+ <p>
+ まず目につくのは大量の絵文字だろう。 PHP は識別子に使用できる文字の範囲が広く、絵文字も使うことができる。
+ </p>
+ </section>
+ <section id="section--q1-brainfuck--commentary--brainfuck">
+ <h4><a href="#section--q1-brainfuck--commentary--brainfuck">プログラム全体</a></h4>
+ <p>
+ Brainf*ck のインタプリタとプログラムになっている。 Brainf*ck とは、難解プログラミング言語のひとつであり、ここで説明するよりも Wikipedia の該当ページを読んだ方がよい。
+ </p>
+ <p>
+ <a href="https://ja.wikipedia.org/wiki/Brainfuck" rel="noreferrer" target="_blank">https://ja.wikipedia.org/wiki/Brainfuck</a>
+ </p>
+ <p>
+ なお、brainf*ck プログラムを普通の書き方で書くと、次のようになる。
+ </p>
+ <div class="codeblock">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>+ + + + + + + + + +</span></span>
+<span class="line"><span>[</span></span>
+<span class="line"><span> > + + +</span></span>
+<span class="line"><span> > + + + + +</span></span>
+<span class="line"><span> > + + + + + + + + + + + +</span></span>
+<span class="line"><span> > + + + + + + + + + +</span></span>
+<span class="line"><span> &#x3C; &#x3C; &#x3C; &#x3C; -</span></span>
+<span class="line"><span>]</span></span>
+<span class="line"><span>> + + + + + .</span></span>
+<span class="line"><span>- - .</span></span>
+<span class="line"><span>> - - - .</span></span>
+<span class="line"><span>> - - - .</span></span>
+<span class="line"><span>- - .</span></span>
+<span class="line"><span>- .</span></span>
+<span class="line"><span>&#x3C; .</span></span>
+<span class="line"><span>> > - - .</span></span>
+<span class="line"><span>+ + + + + + + .</span></span>
+<span class="line"><span>&#x3C; - - - - .</span></span>
+<span class="line"><span>&#x3C; .</span></span>
+<span class="line"><span>> + + .</span></span>
+<span class="line"><span>> - .</span></span>
+<span class="line"><span>&#x3C; .</span></span></code></pre>
+ </div>
+ <p>
+ 実行結果はこちら: <a href="https://ideone.com/22VWmb" rel="noreferrer" target="_blank">https://ideone.com/22VWmb</a>
+ </p>
+ <p>
+ それぞれの絵文字で表された関数が、各命令に対応している。
+ </p>
+ <ul>
+ <li>
+ <code>$👉</code>: <code>&gt;</code>
+ </li>
+ <li>
+ <code>$👈</code>: <code>&lt;</code>
+ </li>
+ <li>
+ <code>$👍</code>: <code>+</code>
+ </li>
+ <li>
+ <code>$👎</code>: <code>-</code>
+ </li>
+ <li>
+ <code>$📝</code>: <code>.</code>
+ </li>
+ <li>
+ <code>$🤡</code>: <code>[</code>
+ </li>
+ <li>
+ <code>$🎪</code>: <code>]</code>
+ </li>
+ </ul>
+ <p>
+ <code>,</code> (入力) に対応する関数はない (このプログラムでは使わないので用意していない)。
+ </p>
+ <p>
+ なお、<code>$🐘</code> はいわゆる main 関数であり、プログラムの実行部分である。
+ </p>
+ </section>
+ <section id="section--q1-brainfuck--commentary--emoji-selection">
+ <h4><a href="#section--q1-brainfuck--commentary--emoji-selection">絵文字の選択</a></h4>
+ <p>
+ おおよそ意味に合致するよう選んでいるが、<code>$🤡</code> と <code>$🎪</code> は弊社デジタルサーカスにちなんでいる。 また、<code>$🐘</code> は PHP のマスコットの象に由来する。
+ </p>
+ </section>
+ <section id="section--q1-brainfuck--commentary--strict-types">
+ <h4><a href="#section--q1-brainfuck--commentary--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> から始まる八進数リテラルを使った。
+ </p>
+ </section>
+ <section id="section--q1-brainfuck--commentary--url">
+ <h4><a href="#section--q1-brainfuck--commentary--url">URL</a></h4>
+ <p>
+ ソースコードのライセンスを示したこの部分だが、
+ </p>
+ <div class="codeblock">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#6F42C1">https</span><span style="color:#24292E">:</span><span style="color:#6A737D">//creativecommons.org/publicdomain/zero/1.0/</span></span></code></pre>
+ </div>
+ <p>
+ 完全に合法な PHP のコードである。 <code>https:</code> 部分はラベル、<code>//</code> 以降は行コメントになっている。
+ </p>
+ </section>
+ <section id="section--q1-brainfuck--commentary--numbers">
+ <h4><a href="#section--q1-brainfuck--commentary--numbers">リテラルなしで数値を生成する</a></h4>
+ <p>
+ ソースコード中に、ほとんど数値リテラルが書かれていないことにお気づきだろうか。PHP では、型変換を利用することで任意の整数を作り出すことができる。
+ </p>
+ <div class="codeblock">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#005CC5">assert</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#D73A49"> ===</span><span style="color:#D73A49"> +!!</span><span style="color:#24292E">[]);</span></span>
+<span class="line"><span style="color:#005CC5">assert</span><span style="color:#24292E">(</span><span style="color:#005CC5">1</span><span style="color:#D73A49"> ===</span><span style="color:#D73A49"> +!</span><span style="color:#24292E">[]);</span></span>
+<span class="line"><span style="color:#005CC5">assert</span><span style="color:#24292E">(</span><span style="color:#005CC5">2</span><span style="color:#D73A49"> ===</span><span style="color:#D73A49"> !</span><span style="color:#24292E">[]</span><span style="color:#D73A49">+!</span><span style="color:#24292E">[]);</span></span>
+<span class="line"><span style="color:#005CC5">assert</span><span style="color:#24292E">(</span><span style="color:#005CC5">3</span><span style="color:#D73A49"> ===</span><span style="color:#D73A49"> !</span><span style="color:#24292E">[]</span><span style="color:#D73A49">+!</span><span style="color:#24292E">[]</span><span style="color:#D73A49">+!</span><span style="color:#24292E">[]);</span></span>
+<span class="line"><span style="color:#005CC5">assert</span><span style="color:#24292E">(</span><span style="color:#005CC5">10</span><span style="color:#D73A49"> ===</span><span style="color:#D73A49"> +</span><span style="color:#24292E">(</span><span style="color:#D73A49">!</span><span style="color:#24292E">[]</span><span style="color:#D73A49">.</span><span style="color:#D73A49">+!!</span><span style="color:#24292E">[]));</span></span></code></pre>
+ </div>
+ <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>&apos;10&apos;</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> にしている。
+ </p>
+ </section>
+ <section id="section--q1-brainfuck--commentary--conditionals">
+ <h4><a href="#section--q1-brainfuck--commentary--conditionals"><code>if</code> 文なしで条件分岐</a></h4>
+ <p>
+ 三項演算子ないし <code>match</code> 式を使うことで、<code>if</code> を一切書かずに条件分岐ができる。 また、<code>&amp;&amp;</code> / <code>||</code> も使えることがある。遅延評価が不要なケースでは、<code>[$t, $f][$cond]</code> のような形で分岐することもできる。
+ </p>
+ </section>
+ <section id="section--q1-brainfuck--commentary--loops">
+ <h4><a href="#section--q1-brainfuck--commentary--loops"><code>while</code>、<code>for</code> 文なしでループ</a></h4>
+ <p>
+ 不動点コンビネータを使って無名再帰する (詳しい説明は省略する。これらの単語で検索してほしい)。 ここでは、一般に Z コンビネータとして知られるものを使った (<code>$z</code>)。
+ </p>
+ <p>
+ 実際のところ、<code>$🤡</code> や <code>$🎪</code>、<code>$🐘</code> は、一度 Scheme (Lisp の一種) で書いてから PHP に翻訳する形で記述した。
+ </p>
+ <p>
+ なお、PHP は末尾再帰の最適化をおこなわない (少なくとも今のところは) ので、 あまりに長い brainf*ck プログラムを書くとスタックオーバーフローする。
+ </p>
+ </section>
+ </section>
+ </section>
+ <section id="section--q2-riddle">
+ <h2><a href="#section--q2-riddle">第2問 riddle.php</a></h2>
+ <p>
+ ソースコードはこちら。実行には PHP 8.0 以上が必要なので注意。
+ </p>
+ <div class="codeblock">
+ <div class="filename">
+ riddle.php
+ </div>
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#6A737D">/*********************************************************</span></span>
+<span class="line"><span style="color:#6A737D"> * This program displays a PHPer token. *</span></span>
+<span class="line"><span style="color:#6A737D"> * Guess 'N'. *</span></span>
+<span class="line"><span style="color:#6A737D"> * *</span></span>
+<span class="line"><span style="color:#6A737D"> * Hints: *</span></span>
+<span class="line"><span style="color:#6A737D"> * - N itself has no special meaning, e.g., 42, 8128, *</span></span>
+<span class="line"><span style="color:#6A737D"> * it is selected at random. *</span></span>
+<span class="line"><span style="color:#6A737D"> * - Each element of $token represents a single letter. *</span></span>
+<span class="line"><span style="color:#6A737D"> * - One letter consists of 5x5 cells. *</span></span>
+<span class="line"><span style="color:#6A737D"> * - Remember, the output is a complete PHPer token. *</span></span>
+<span class="line"><span style="color:#6A737D"> * *</span></span>
+<span class="line"><span style="color:#6A737D"> * License: *</span></span>
+<span class="line"><span style="color:#6A737D"> * https://creativecommons.org/publicdomain/zero/1.0/ *</span></span>
+<span class="line"><span style="color:#6A737D"> *********************************************************/</span></span>
+<span class="line"><span style="color:#D73A49">const</span><span style="color:#005CC5"> N</span><span style="color:#D73A49"> =</span><span style="color:#005CC5"> 0</span><span style="color:#6A737D"> /* Change it to your answer. */</span><span style="color:#24292E">;</span></span>
+<span class="line"><span style="color:#005CC5">assert</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#D73A49"> &#x3C;=</span><span style="color:#005CC5"> N</span><span style="color:#D73A49"> &#x26;&#x26;</span><span style="color:#005CC5"> N</span><span style="color:#D73A49"> &#x3C;=</span><span style="color:#005CC5"> 0b11111_11111_11111_11111_11111</span><span style="color:#24292E">);</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#24292E">$token </span><span style="color:#D73A49">=</span><span style="color:#24292E"> [</span></span>
+<span class="line"><span style="color:#005CC5"> 0x14B499C</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#005CC5"> 0x0BE34CC</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x01C9C69</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#005CC5"> 0x0ECA069</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x01C2449</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x0FDB166</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x01C9C69</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#005CC5"> 0x01C1C66</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x0FC1C47</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x01C1C66</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#005CC5"> 0x10C5858</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1E4E3B8</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1A2F2F8</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#24292E">];</span></span>
+<span class="line"><span style="color:#D73A49">foreach</span><span style="color:#24292E"> ($token </span><span style="color:#D73A49">as</span><span style="color:#24292E"> $x) {</span></span>
+<span class="line"><span style="color:#24292E"> $x </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $x </span><span style="color:#D73A49">^</span><span style="color:#005CC5"> N</span><span style="color:#24292E">;</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#24292E"> $x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> sprintf</span><span style="color:#24292E">(</span><span style="color:#032F62">'%025b'</span><span style="color:#24292E">, $x);</span></span>
+<span class="line"><span style="color:#24292E"> $x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> str_replace</span><span style="color:#24292E">(</span><span style="color:#6F42C1">search</span><span style="color:#24292E">: [</span><span style="color:#032F62">'0'</span><span style="color:#24292E">, </span><span style="color:#032F62">'1'</span><span style="color:#24292E">], </span><span style="color:#6F42C1">replace</span><span style="color:#24292E">: [</span><span style="color:#032F62">' '</span><span style="color:#24292E">, </span><span style="color:#032F62">'#'</span><span style="color:#24292E">], </span><span style="color:#6F42C1">subject</span><span style="color:#24292E">: $x);</span></span>
+<span class="line"><span style="color:#24292E"> $x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> implode</span><span style="color:#24292E">(</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">, </span><span style="color:#005CC5">str_split</span><span style="color:#24292E">($x, </span><span style="color:#6F42C1">length</span><span style="color:#24292E">: </span><span style="color:#005CC5">5</span><span style="color:#24292E">));</span></span>
+<span class="line"><span style="color:#005CC5"> echo</span><span style="color:#032F62"> "{</span><span style="color:#24292E">$x</span><span style="color:#032F62">}</span><span style="color:#005CC5">\n\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span>
+<span class="line"><span style="color:#24292E">}</span></span></code></pre>
+ </div>
+ <p>
+ さて、この問題はさきほどのように単純に実行しただけでは、謎のブロックが表示されるだけでトークンは得られない。トークンを得るためには、ソースコードを読み、定数 <code>N</code> を特定する必要がある。
+ </p>
+ <p>
+ ここでは、私の想定解を解説する。
+ </p>
+ <section id="section--q2-riddle--code-reading">
+ <h3><a href="#section--q2-riddle--code-reading">読解</a></h3>
+ <p>
+ まずはソースコードを読んでいく。
+ </p>
+ <div class="codeblock">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$token </span><span style="color:#D73A49">=</span><span style="color:#24292E"> [</span></span>
+<span class="line"><span style="color:#6A737D"> // 略</span></span>
+<span class="line"><span style="color:#24292E">];</span></span></code></pre>
+ </div>
+ <p>
+ 数値からなる <code>$token</code> があり、各要素をループしている。
+ </p>
+ <div class="codeblock">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $x </span><span style="color:#D73A49">^</span><span style="color:#005CC5"> N</span><span style="color:#24292E">;</span></span></code></pre>
+ </div>
+ <p>
+ まずは排他的論理和 (xor) を取り、
+ </p>
+ <div class="codeblock">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> sprintf</span><span style="color:#24292E">(</span><span style="color:#032F62">'%025b'</span><span style="color:#24292E">, $x);</span></span></code></pre>
+ </div>
+ <p>
+ 二進数に変換して、
+ </p>
+ <div class="codeblock">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> str_replace</span><span style="color:#24292E">(</span><span style="color:#6F42C1">search</span><span style="color:#24292E">: [</span><span style="color:#032F62">'0'</span><span style="color:#24292E">, </span><span style="color:#032F62">'1'</span><span style="color:#24292E">], </span><span style="color:#6F42C1">replace</span><span style="color:#24292E">: [</span><span style="color:#032F62">' '</span><span style="color:#24292E">, </span><span style="color:#032F62">'#'</span><span style="color:#24292E">], </span><span style="color:#6F42C1">subject</span><span style="color:#24292E">: $x);</span></span></code></pre>
+ </div>
+ <p>
+ 0 を空白に、1 を <code>#</code> にし、
+ </p>
+ <div class="codeblock">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> implode</span><span style="color:#24292E">(</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">, </span><span style="color:#005CC5">str_split</span><span style="color:#24292E">($x, </span><span style="color:#6F42C1">length</span><span style="color:#24292E">: </span><span style="color:#005CC5">5</span><span style="color:#24292E">));</span></span></code></pre>
+ </div>
+ <p>
+ 5文字ごとに区切ったあと、改行で結合している。
+ </p>
+ </section>
+ <section id="section--q2-riddle--hint">
+ <h3><a href="#section--q2-riddle--hint">ヒント</a></h3>
+ <p>
+ 次に、ソースコードに書いてあるヒントを読んでいく。
+ </p>
+ <ul>
+ <li>
+ <code>N</code> それ自体は、42 や 8128 といったような特別な意味を持たず、ランダムに決められている
+ </li>
+ <li>
+ <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 ファイルに追加ヒントとして書かれている)。
+ </p>
+ </section>
+ <section id="section--q2-riddle--solve">
+ <h3><a href="#section--q2-riddle--solve">解く</a></h3>
+ <p>
+ ここまでわかれば、あと一歩で解ける。すなわち、<code>0x14B499C</code> が <code>#</code> に変換されるような <code>N</code> を見つければよい。
+ </p>
+ <p>
+ <code>N</code> は高々
+ </p>
+ <div class="codeblock">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#005CC5">assert</span><span style="color:#24292E">(</span><span style="color:#005CC5">0</span><span style="color:#D73A49"> &#x3C;=</span><span style="color:#005CC5"> N</span><span style="color:#D73A49"> &#x26;&#x26;</span><span style="color:#005CC5"> N</span><span style="color:#D73A49"> &#x3C;=</span><span style="color:#005CC5"> 0b11111_11111_11111_11111_11111</span><span style="color:#24292E">);</span></span></code></pre>
+ </div>
+ <p>
+ なのでブルートフォースしてもよいが、ここではブルートフォースしない方法を紹介する。
+ </p>
+ <div class="codeblock">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 0x14B499C</span><span style="color:#24292E">;</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $x </span><span style="color:#D73A49">^</span><span style="color:#005CC5"> N</span><span style="color:#24292E">;</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> sprintf</span><span style="color:#24292E">(</span><span style="color:#032F62">'%025b'</span><span style="color:#24292E">, $x);</span></span>
+<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> str_replace</span><span style="color:#24292E">(</span><span style="color:#6F42C1">search</span><span style="color:#24292E">: [</span><span style="color:#032F62">'0'</span><span style="color:#24292E">, </span><span style="color:#032F62">'1'</span><span style="color:#24292E">], </span><span style="color:#6F42C1">replace</span><span style="color:#24292E">: [</span><span style="color:#032F62">' '</span><span style="color:#24292E">, </span><span style="color:#032F62">'#'</span><span style="color:#24292E">], </span><span style="color:#6F42C1">subject</span><span style="color:#24292E">: $x);</span></span>
+<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> implode</span><span style="color:#24292E">(</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">, </span><span style="color:#005CC5">str_split</span><span style="color:#24292E">($x, </span><span style="color:#6F42C1">length</span><span style="color:#24292E">: </span><span style="color:#005CC5">5</span><span style="color:#24292E">));</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#005CC5">assert</span><span style="color:#24292E">($x </span><span style="color:#D73A49">===</span></span>
+<span class="line"><span style="color:#032F62">" # # </span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> .</span></span>
+<span class="line"><span style="color:#032F62">"#####</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> .</span></span>
+<span class="line"><span style="color:#032F62">" # # </span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> .</span></span>
+<span class="line"><span style="color:#032F62">"#####</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> .</span></span>
+<span class="line"><span style="color:#032F62">" # # "</span><span style="color:#24292E">);</span></span></code></pre>
+ </div>
+ <p>
+ この一連の変換に対する逆変換を考えると、次のようになる。
+ </p>
+ <div class="codeblock">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span></span>
+<span class="line"><span style="color:#032F62">" # # </span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> .</span></span>
+<span class="line"><span style="color:#032F62">"#####</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> .</span></span>
+<span class="line"><span style="color:#032F62">" # # </span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> .</span></span>
+<span class="line"><span style="color:#032F62">"#####</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#D73A49"> .</span></span>
+<span class="line"><span style="color:#032F62">" # # "</span><span style="color:#24292E">;</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> implode</span><span style="color:#24292E">(</span><span style="color:#032F62">''</span><span style="color:#24292E">, </span><span style="color:#005CC5">explode</span><span style="color:#24292E">(</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">, $x));</span></span>
+<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> str_replace</span><span style="color:#24292E">(</span><span style="color:#6F42C1">search</span><span style="color:#24292E">: [</span><span style="color:#032F62">' '</span><span style="color:#24292E">, </span><span style="color:#032F62">'#'</span><span style="color:#24292E">], </span><span style="color:#6F42C1">replace</span><span style="color:#24292E">: [</span><span style="color:#032F62">'0'</span><span style="color:#24292E">, </span><span style="color:#032F62">'1'</span><span style="color:#24292E">], </span><span style="color:#6F42C1">subject</span><span style="color:#24292E">: $x);</span></span>
+<span class="line"><span style="color:#24292E">$x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> bindec</span><span style="color:#24292E">($x);</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#24292E">$n </span><span style="color:#D73A49">=</span><span style="color:#24292E"> $x </span><span style="color:#D73A49">^</span><span style="color:#005CC5"> 0x14B499C</span><span style="color:#24292E">;</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#005CC5">echo</span><span style="color:#032F62"> "N = </span><span style="color:#24292E">$n</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span></code></pre>
+ </div>
+ <p>
+ これを実行すると、<code>N</code> が得られる。
+ </p>
+ </section>
+ </section>
+ <section id="section--q3-toquine">
+ <h2><a href="#section--q3-toquine">第3問 toquine.php</a></h2>
+ <p>
+ ソースコードはこちら。
+ </p>
+ <div class="codeblock">
+ <div class="filename">
+ toquine.php
+ </div>
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span style="color:#D73A49">&#x3C;?</span><span style="color:#005CC5">php</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#6A737D">// License: https://creativecommons.org/publicdomain/zero/1.0/</span></span>
+<span class="line"><span style="color:#6A737D">// This is a quine-like program to generate a PHPer token.</span></span>
+<span class="line"><span style="color:#6A737D">// Execute it like this: php toquine.php | php | php | php | ...</span></span>
+<span class="line"></span>
+<span class="line"><span style="color:#24292E">$s </span><span style="color:#D73A49">=</span><span style="color:#032F62"> &#x3C;&#x3C;&#x3C;'</span><span style="color:#D73A49">Q</span><span style="color:#032F62">'</span></span>
+<span class="line"><span style="color:#032F62">&#x3C;?cuc</span></span>
+<span class="line"><span style="color:#032F62">// Yvprafr: uggcf://perngvirpbzzbaf.bet/choyvpqbznva/mreb/1.0/</span></span>
+<span class="line"><span style="color:#032F62">// Guvf vf n dhvar-yvxr cebtenz gb trarengr n CUCre gbxra.</span></span>
+<span class="line"><span style="color:#032F62">// Rkrphgr vg yvxr guvf: cuc gbdhvar.cuc | cuc | cuc | cuc | ...</span></span>
+<span class="line"><span style="color:#032F62">%f$f = %f;</span></span>
+<span class="line"><span style="color:#032F62">$f = fge_ebg13($f); $kf = [</span></span>
+<span class="line"><span style="color:#032F62">%f,</span></span>
+<span class="line"><span style="color:#032F62">];</span></span>
+<span class="line"><span style="color:#032F62">$g = ahyy.snyfr; sbe ($v = 0; $v &#x3C;= vagqvi(__YVAR__-035,6); ++$v) vs (!vffrg($kf[$v])) oernx; ryfr</span></span>
+<span class="line"><span style="color:#032F62">$g .= vzcybqr("\a", fge_fcyvg(fge_ercynpr(['0','1'], [' ','##'], fcevags(pue(37) . '025o', $kf[$v])), 012)) . "\a\a";</span></span>
+<span class="line"><span style="color:#032F62">$jf = neenl_znc(sa($j) => vzcybqr(', ', $j), neenl_puhax(neenl_znc(sa($k) => fcevags('0k' . pue(37) . '07K', $k), $kf), 10));</span></span>
+<span class="line"><span style="color:#032F62">cevags($f, $g, fge_ebg13("&#x3C;&#x3C;&#x3C;'Q'\a{$f}\aQ"), vzcybqr(",\a", $jf));</span></span>
+<span class="line"><span style="color:#D73A49">Q</span><span style="color:#24292E">;</span></span>
+<span class="line"><span style="color:#24292E">$s </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> str_rot13</span><span style="color:#24292E">($s); $xs </span><span style="color:#D73A49">=</span><span style="color:#24292E"> [</span></span>
+<span class="line"><span style="color:#005CC5">0x0AFABEA</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F294A7</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F2109F</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F294A7</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x0002800</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F2109F</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x0117041</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F294A7</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1FAD6B5</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F295B7</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#005CC5">0x010FC21</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1FAD6B5</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1151151</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x010FC21</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F294A7</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F295B7</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1FAD6B5</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F294A7</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F295B7</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F8C63F</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#005CC5">0x1F8C631</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1FAD6B5</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x17AD6BD</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x17AD6BD</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F8C63F</span><span style="color:#24292E">, </span><span style="color:#005CC5">0x1F295B7</span><span style="color:#24292E">,</span></span>
+<span class="line"><span style="color:#24292E">];</span></span>
+<span class="line"><span style="color:#24292E">$t </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> null</span><span style="color:#D73A49">.</span><span style="color:#005CC5">false</span><span style="color:#24292E">; </span><span style="color:#D73A49">for</span><span style="color:#24292E"> ($i </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 0</span><span style="color:#24292E">; $i </span><span style="color:#D73A49">&#x3C;=</span><span style="color:#6F42C1"> intdiv</span><span style="color:#24292E">(</span><span style="color:#005CC5">__LINE__</span><span style="color:#D73A49">-</span><span style="color:#005CC5">035</span><span style="color:#24292E">,</span><span style="color:#005CC5">6</span><span style="color:#24292E">); </span><span style="color:#D73A49">++</span><span style="color:#24292E">$i) </span><span style="color:#D73A49">if</span><span style="color:#24292E"> (</span><span style="color:#D73A49">!</span><span style="color:#005CC5">isset</span><span style="color:#24292E">($xs[$i])) </span><span style="color:#D73A49">break</span><span style="color:#24292E">; </span><span style="color:#D73A49">else</span></span>
+<span class="line"><span style="color:#24292E">$t </span><span style="color:#D73A49">.=</span><span style="color:#005CC5"> implode</span><span style="color:#24292E">(</span><span style="color:#032F62">"</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">, </span><span style="color:#005CC5">str_split</span><span style="color:#24292E">(</span><span style="color:#005CC5">str_replace</span><span style="color:#24292E">([</span><span style="color:#032F62">'0'</span><span style="color:#24292E">,</span><span style="color:#032F62">'1'</span><span style="color:#24292E">], [</span><span style="color:#032F62">' '</span><span style="color:#24292E">,</span><span style="color:#032F62">'##'</span><span style="color:#24292E">], </span><span style="color:#005CC5">sprintf</span><span style="color:#24292E">(</span><span style="color:#005CC5">chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">37</span><span style="color:#24292E">) </span><span style="color:#D73A49">.</span><span style="color:#032F62"> '025b'</span><span style="color:#24292E">, $xs[$i])), </span><span style="color:#005CC5">012</span><span style="color:#24292E">)) </span><span style="color:#D73A49">.</span><span style="color:#032F62"> "</span><span style="color:#005CC5">\n\n</span><span style="color:#032F62">"</span><span style="color:#24292E">;</span></span>
+<span class="line"><span style="color:#24292E">$ws </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> array_map</span><span style="color:#24292E">(</span><span style="color:#D73A49">fn</span><span style="color:#24292E">($w) => </span><span style="color:#005CC5">implode</span><span style="color:#24292E">(</span><span style="color:#032F62">', '</span><span style="color:#24292E">, $w), </span><span style="color:#005CC5">array_chunk</span><span style="color:#24292E">(</span><span style="color:#005CC5">array_map</span><span style="color:#24292E">(</span><span style="color:#D73A49">fn</span><span style="color:#24292E">($x) => </span><span style="color:#005CC5">sprintf</span><span style="color:#24292E">(</span><span style="color:#032F62">'0x'</span><span style="color:#D73A49"> .</span><span style="color:#005CC5"> chr</span><span style="color:#24292E">(</span><span style="color:#005CC5">37</span><span style="color:#24292E">) </span><span style="color:#D73A49">.</span><span style="color:#032F62"> '07X'</span><span style="color:#24292E">, $x), $xs), </span><span style="color:#005CC5">10</span><span style="color:#24292E">));</span></span>
+<span class="line"><span style="color:#005CC5">printf</span><span style="color:#24292E">($s, $t, </span><span style="color:#005CC5">str_rot13</span><span style="color:#24292E">(</span><span style="color:#032F62">"&#x3C;&#x3C;&#x3C;'D'</span><span style="color:#005CC5">\n</span><span style="color:#032F62">{</span><span style="color:#24292E">$s</span><span style="color:#032F62">}</span><span style="color:#005CC5">\n</span><span style="color:#032F62">D"</span><span style="color:#24292E">), </span><span style="color:#005CC5">implode</span><span style="color:#24292E">(</span><span style="color:#032F62">",</span><span style="color:#005CC5">\n</span><span style="color:#032F62">"</span><span style="color:#24292E">, $ws));</span></span></code></pre>
+ </div>
+ <p>
+ コメントにもあるとおり、次のようにして実行すれば答えがでてくる。
+ </p>
+ <div class="codeblock">
+ <pre class="shiki github-light" style="background-color:#f5f5f5;color:#24292e" tabindex="0"><code><span class="line"><span>$ php toquine.php | php | php | php | ...</span></span></code></pre>
+ </div>
+ <p>
+ 実際にはもう少しパイプで繋げなければならない。
+ </p>
+ <section id="section--q3-toquine--commentary">
+ <h3><a href="#section--q3-toquine--commentary">解説</a></h3>
+ <section id="section--q3-toquine--commentary--quine">
+ <h4><a href="#section--q3-toquine--commentary--quine">プログラム全体</a></h4>
+ <p>
+ コメントにもあるとおり、これは quine (風) のプログラムになっている。Quine とは、自分のソースコードをそっくりそのまま出力するようなプログラムのことである。
+ </p>
+ <p>
+ このプログラムは、実行すると自身とほとんど同じプログラムを出力する。異なるのはトークンになっている部分のみである。
+ </p>
+ </section>
+ <section id="section--q3-toquine--commentary--tokens">
+ <h4><a href="#section--q3-toquine--commentary--tokens">トークン</a></h4>
+ <p>
+ <code>$xs</code> がトークンに対応している。変換のロジックは <code>riddle.php</code> とほぼ同じなので省略する。
+ </p>
+ </section>
+ <section id="section--q3-toquine--commentary--states">
+ <h4><a href="#section--q3-toquine--commentary--states">状態保持</a></h4>
+ <p>
+ トークンの何文字目まで出力したかを、ソースコードを変えずに (quine なので) 覚えておく必要がある。このプログラムでは、トークンが出力されるとソースコードがだんだんと長くなっていくのを利用して、<code>__LINE__</code> から情報を取得している。
+ </p>
+ </section>
+ <section id="section--q3-toquine--commentary--rot-13">
+ <h4><a href="#section--q3-toquine--commentary--rot-13">ROT 13</a></h4>
+ <p>
+ Quine は、素朴に書くとプログラムの一部が 2回記述されてしまう。これがあまり美しくないので、<code>toquine.php</code> では、ROT 13 変換を使って難読化した。
+ </p>
+ <p>
+ それにしてもなぜこんなものが標準ライブラリに……。
+ </p>
+ </section>
+ </section>
+ </section>
+ <section id="section--outro">
+ <h2><a href="#section--outro">おわりに</a></h2>
+ <p>
+ 解いていただいたみなさん、また、難易度調整につきあっていただいた社内のみなさん、ありがとうございました。
+ </p>
+ <p>
+ 今回は直前に作りはじめたのもあり、3問だけかつ使い古されたネタばかりになってしまいましたが、来年は 5問、より面白い問題を持っていきます。
+ </p>
+ <p>
+ 実はもう作りはじめているので、どうか来年もありますように……。
+ </p>
+ </section>
+ </div>
+ </article>
+ </main>
+ <footer class="footer">
+ &copy; 2021 nsfisis
+ </footer>
+ </body>
+</html>