Not Quine 終了

あなごる Not Quine が終了した。期間の長い問題だった。回答したのは JS のみで、28B で最短だった。満点だ。他のユーザーによる 28B の回答と同じ構造をしていた。

Quine のように、ソースコードと同じ出力をしなければならないというルールではない。そこがミソである。問題名が Not Quine である。Quine という単語が入っている。なので、しばらく、「Quine に一工夫して正解しよう」というふうに意識が引きずられた。そこで、できた回答が、以下の 2 つである。

\nnew function f() print("new", f)

\n は、実際には、改行コードの 0x0A (1B) である。

これ (33B) は、Quine での murky-satyr さんによる美しい回答の改変である。おしりにあった改行をあたまに持っていっただけ。非常に洗練されているため、当初は、これが最短だと思い込んでいた。

\nprint(read("test.js").trim() )

次に投稿したこのコード (31B) は、Quine での teebee さんによる、read 関数を用いた裏技的な回答の改変である。trim を行うことで、あたまの改行を削り、正解できる。

さすがにもう、これ以上は縮まないだろうと思っていた。が、縮んだ。すなわち、以下である。

print(e=/(e,)preint=/,e)//\n 

このコード (28B) の最大のポイントは、正規表現リテラルの開始文字かつ終了文字である 2 つのスラッシュ / と、コメント開始文字の 2 つのスラッシュ // が協力しているところである。

出力は以下となる。

/(e,)preint=/ /(e,)preint=/\n

print(/./) を行うと、/./\n が出力される。リテラル開始&終了文字を含んだ形で、文字列化されているところが、Quine 的行為のために都合が良い。文字列リテラルだと、こういうふうにはいかない。print(".") を行っても .\n となり、"" が失われるから、正規表現ほどの有用さが期待できない。

回答の出力では /(e,)preint=/ が 2 回出現している。1 回目のそれは、ソースコード正規表現リテラルがそのまま表れていると見なすとして。2 回目のそれは、どこかから借りてくる必要がある。どこから借りるか。そう、コメント開始文字のダブルスラッシュである。素晴らふぃーね。

ちなみに、ソースコードのそれは、厳密に /(e,)preint=/ である必要はない。たしか、/print(e=,e)/ という可読性に優れた形でも通った気がする。が、時すでに遅し。試行錯誤のつもりでやっていて、まさか通るとは思ってなかったものが通っちゃった。