放射線硬化クイン


39

(願わくば)知っておくべきことですが、耐放射線強化されたクインは、任意の1文字を削除して、元の修正済みソースを印刷できるクインです。重要なのは、これらのほとんどでは、1文字しか削除できないということです。そうしないと、すべてが故障します。これは、これが来るところです。あなたの目標は、できるだけ多くのキャラクターの除去を行うことができる耐放射線性のクインを構築することです。ルールに準拠する言語であれば問題ありません。

ルール

  • プログラムは少なくとも1文字の長さが必要です
  • 使用する言語は完全にチューリングする必要があります(したがって、HQ9 +などの言語は対象外です)
  • 通常のクインに適用される他のすべてのルールもここに適用されます。
  • 少なくとも有する溶液program_length^(2/n)れる任意正確セットn依然として元のソースコードWINSを印刷中の文字を除去することができます。

1
で解決策を考え出そうとしていSubleqます。この種の挑戦には理想的だと思います!


名前が変わったのかもしれませんが、これは放射線で強化されたクインと同じではありませんか?おそらく「放射線耐性の馬」でしょうか?
チョイス

@Cyoce私が知ることができる唯一の違いは、このチャレンジは任意の数の除去に対するものであり、他の放射線硬化カインのほとんど(すべてではないにしても)が1つしか許可しないことです。
タクラ

有名な「mame」のRubyソリューション。github.com/mame/radiation-hardened-quine
mbomb007 16

回答:


57

Perl、1116 1124バイト、n = 3、score = 1124 ^(2/3)または約108.1

更新:これは、ブルートフォースによってn = 3で機能することを確認しました(これには数日かかりました)。この複雑なプログラムでは、放射線耐性を手動で確認するのは困難です(以前のバージョンで1つのミスを犯したため、バイトカウントが増加しました)。更新を終了

見えない場所にstderrをリダイレクトすることをお勧めします。このプログラムは、文字を削除していない場合でも、疑わしい構文に関する大量の警告を生成します。

プログラムを短縮できる可能性があります。これに取り組むことはかなり苦痛であり、可能な最適化を逃しやすくします。私は主に削除可能なキャラクターの数をできるだけ多くすることを目指していました(それはプログラムの本当に難しい部分だからです)、そしてタイブレークを狙うのに良いものとして扱いましたが、私は入れません最適化へのばかげた努力(放射能抵抗を偶然に破壊することは非常に簡単であることに基づいて)。

プログラム

注:_の4つの出現のそれぞれの直前に、リテラルのControl- 文字(ASCII 31)があり-+ます。StackOverflowに正しくコピーして貼り付けるとは思わないので、プログラムを実行する前に再度追加する必要があります。

eval+<eval+<eval+<eval+(q(FoPqOlengthFoBBPP181XXVVVVJJJKKKNdoWchopJFtPDevalMODx4KNFrPIPA-MN-TUV-ZPINFsPIFoPqOI.Fo.IQNevalFoINevalIFsPZyI.Fr.IT-UPINsayDFtJqJFsKPZyPT-UFWrYrKD.DEEEEQDx6NsayDNDforB1..4YforB1..4NexitQNevalFo)=~y=A-Z=-+;-AZz-~=r)####>####>####>####>####>####>
;
;
;
;
eval+<eval+<eval+<eval+(q(FoPqOlengthFoBBPP181XXVVVVJJJKKKNdoWchopJFtPDevalMODx4KNFrPIPA-MN-TUV-ZPINFsPIFoPqOI.Fo.IQNevalFoINevalIFsPZyI.Fr.IT-UPINsayDFtJqJFsKPZyPT-UFWrYrKD.DEEEEQDx6NsayDNDforB1..4YforB1..4NexitQNevalFo)=~y=A-Z=-+;-AZz-~=r)####>####>####>####>####>####>
;
;
;
;
eval+<eval+<eval+<eval+(q(FoPqOlengthFoBBPP181XXVVVVJJJKKKNdoWchopJFtPDevalMODx4KNFrPIPA-MN-TUV-ZPINFsPIFoPqOI.Fo.IQNevalFoINevalIFsPZyI.Fr.IT-UPINsayDFtJqJFsKPZyPT-UFWrYrKD.DEEEEQDx6NsayDNDforB1..4YforB1..4NexitQNevalFo)=~y=A-Z=-+;-AZz-~=r)####>####>####>####>####>####>
;
;
;
;
eval+<eval+<eval+<eval+(q(FoPqOlengthFoBBPP181XXVVVVJJJKKKNdoWchopJFtPDevalMODx4KNFrPIPA-MN-TUV-ZPINFsPIFoPqOI.Fo.IQNevalFoINevalIFsPZyI.Fr.IT-UPINsayDFtJqJFsKPZyPT-UFWrYrKD.DEEEEQDx6NsayDNDforB1..4YforB1..4NexitQNevalFo)=~y=A-Z=-+;-AZz-~=r)####>####>####>####>####>####>
;
;
;
;

説明

このプログラムは、まったく同じように、4つの同じ小さなプログラムを連結して構成されています。基本的な考え方は、プログラムの各コピーが、実行するには損傷がひどすぎるかどうかを検証することです。実行されていた場合、警告を発すること以外は何もせず、次のコピーを実行します。削除されていない場合(つまり、削除されていない、または削除された文字がプログラムの動作に影響を及ぼさない文字である場合)、適切な処理を行います(完全なプログラムのソースコードを出力します。これは適切なクインです。各部分にソースコード全体のエンコードが含まれる)、終了します(他の破損していないコピーがソースコードを再度印刷するのを防ぎ、テキストを大量に印刷してクインを台無しにします)。

各パーツは、機能的に独立した2つのパーツで構成されています。外部ラッパーと内部コード。そのため、それらを個別に検討できます。

外部ラッパー

外側のラッパーは、基本的にeval<+eval<+eval< ... >####>####...>###(プラスの目的がかなり明確であるセミコロンと改行の束です;セミコロンの一部、またはそれらの前の改行が削除されたかどうかにかかわらず、プログラムの部分が分離されたままになるようにするためです。 )。これはかなり単純に見えるかもしれませんが、いくつかの点で微妙であり、この挑戦​​のためにPerlを選んだ理由です。

最初に、破損していないプログラムのコピーでラッパーがどのように機能するかを見てみましょう。eval1つの引数を取る組み込み関数として解析します。議論が予想されるため、+ここに単項式+があります(これは、今ではPerlゴルファーによく知られています。驚くほど頻繁に役に立つでしょう)。私たちはまだ引数を期待しています(単項演算子を見たばかりです)ので、<次に来るのは<>演算子の開始として解釈されます(プレフィックスまたはポストフィックス引数を取らないため、オペランドの位置で使用できます)。

<>かなり奇妙な演算子です。通常の目的はファイルハンドルを読み取ることであり、ファイルハンドル名山括弧に配置します。あるいは、式がファイルハンドル名として有効でない場合、グロビングを行います(基本的に、UNIXシェルがユーザーが入力したテキストをコマンドライン引数のシーケンスに変換するために使用するプロセスと同じです;実際に使用されるPerlのはるかに古いバージョンこのためのシェルですが、最近ではPerlは内部的にグロビングを処理します)。したがって、使用目的はの行に沿っており、<*.c>通常はのようなリストを返し("foo.c", "bar.c")ます。スカラーコンテキスト(引数への引数など)eval)、最初に実行されたときに最初に検出された最初のエントリ(最初の引数に相当)を返すだけで、将来発生しない仮想実行で他のエントリを返します。

現在、シェルはしばしばコマンドライン引数を処理します。-r引数なしのようなものを指定した場合、その名前のファイルがあるかどうかに関係なく、そのままそのままプログラムに渡されます。Perlは同じように動作します。そのため、<との間にシェルまたはPerlに特別な文字がないことを確認する限り、これ>を文字列リテラルの本当に厄介な形式のように効果的に使用できます。さらに良いことに、Perlのクォートのような演算子用のパーサーは、このようなコンテキストが意味をなさない場合でもブラケットを一致させる傾向があるため、<>安全にネストすることができます(このプログラムを可能にするために必要な発見です)これらのすべてのネストの主な欠点は<>、コンテンツのエスケープです<>ほとんど不可能です。それぞれに2層のエスケープ解除があるように見えるため<>、3つすべての内側から何かをエスケープするには、63個のバックスラッシュを前に付ける必要があります。コードサイズはこの問題の副次的な考慮事項にすぎませんが、スコアにこの種のペナルティを払う価値はほとんどないので、問題のある文字を使用せずにプログラムの残りを書くことにしました。

では、ラッパーの一部が削除されるとどうなりますか?

  • 単語を削除すると、意味のない文字列でevalあるbarewordに変わります。Perlはこれらを好みませんが、引用符で囲まれているように扱います。したがってeal<+eval<+..."eal" < +eval<+...。これはプログラムの動作に影響を及ぼしません。なぜなら、基本的には、ネストされたevals(とにかく使用しない)から結果を取得し、整数にキャストし、その上で無意味な比較を行うからです。(この種のことは、通常の状況では明らかに有用ではないため、多くの警告スパムを引き起こします。削除を吸収するためにそれを使用しているだけです。)これにより、必要な閉じ山かっこの数が変わります(開きかっこ代わりに比較演算子として解釈されるようになりました)が、最後にある一連のコメントにより、文字列が何回ネストされても安全に終了することが保証されます。(#ここで厳密に必要とされるよりも多くの兆候があります。プログラムをより圧縮可能にし、クインを保存するためにより少ないデータを使用できるようにするために書きました。)
  • 場合は<削除される、コードは今のように解析しますeval(eval<...>)eval評価対象のプログラムは、プログラムとして実際の効果をもたらすものを何も返さないので、2番目の外部は効果がありません(通常返される場合、通常はヌル文字列またはベアワードです;より一般的には、例外eval。null文字列を返すかexit、まったく返さないようにするために使用します)。
  • +が削除された場合、隣接するコードが損なわれていない場合、これはすぐには影響しません。単項+はプログラムに影響しません。(元+のsが存在する理由は、損傷の修復を支援するためです。関係演算子ではなく<単項として解釈される状況の数が増えます。<>つまり、無効なプログラムを作成するには、さらに削除する必要があります。)

ラッパー十分な削除で破損する可能性がありますが、解析されない何かを生成するには、一連の削除を行う必要があります。4つの削除により、これを行うことができます。

eal<evl<eval+<...

また、Perlでは、関係演算子<は非連想演算子であるため、構文エラーが発生します(同じエラーが発生します1<2<3)。そのため、記述されているプログラムの上限はn = 3です。単項変数を追加する+ことは、それを増やす有望な方法のように思えますが、ラッパーの内部も壊れる可能性がますます高まるため、プログラムの新しいバージョンが機能することを確認するのは非常に困難です。

ラッパーが非常に貴重である理由はeval、Perlで(たとえば)構文エラーをコンパイルしようとすると発生する例外などの例外をキャッチするためです。これevalは文字列リテラルであるため、文字列のコンパイルは実行時に行われ、リテラルがコンパイルに失敗すると、結果の例外がキャッチされます。これによりeval、null文字列が返され、エラーインジケーター$@が設定されますが、いずれのチェックも行われません(プログラムのいくつかの変更されたバージョンで、返されたnull文字列を時々実行する場合を除く)。重要なのは、これは、内部のコードに何かが発生した場合に、ラッパーは構文エラーを引き起こし、その後、ラッパーはコードに代わりに何もさせません(そして、プログラムはそれ自体の破損していないコピーを見つけようとして実行を続けます)。したがって、内部コードは、ラッパーと同じくらい耐放射線性である必要はありません。私たちが気にするのは、破損している場合、プログラムの破損していないバージョンと同じように動作するか、クラッシュするか(eval例外をキャッチして続行できる)、何も印刷せずに正常に終了することです。

ラッパーの内側

ラッパー内のコードは、基本的には次のようになります(再び、Control _があります-Stack Exchange はの直前に表示されません-+)。

eval+(q(...)=~y=A-Z=-+;-AZz-~=r)

このコードは、グロブ安全な文字で書かれた、その目的は、文字列リテラル(私たちが使用することはできませんが翻字と評価を経て、実際のプログラムを記述することを可能にする句読点の新しいアルファベットを追加することです'か、"私たちの引用符としてただし、q()はPerlで文字列を形成する有効な方法です)。(印刷できない文字の理由は、プログラムでリテラルのスペース文字を使用せずに何かをスペース文字に音訳する必要があるためです。したがって、ASCII 31で始まる範囲を形成し、スペースを範囲の2番目の要素としてキャッチします。)明らかに、音訳を介していくつかのキャラクターを作成している場合、文字を犠牲にして、大文字はあまり有用ではなく、句読点にアクセスするよりも、大文字にアクセスする方がはるかに簡単に書くことができます。

これは、グロブの結果として使用可能になる句読点のアルファベットです(上の行はエンコードを示し、下の行はエンコードする文字を示します)。

BCDEFGHIJKLMNOPQRSTUVWXYZ
 ! "#$%& '()* +; <=>?@ AZz {|}〜 

最も注目すべきは、globセーフではないが、スペース文字と一緒にPerlプログラムを書くのに役立つ句読点がたくさんあることです。また、2つの大文字、リテラルAand Z(これは自分自身ではなく、TおよびUにエンコードします。これAは、上限および下限のエンドポイントとして必要だったためです)。これにより、新しいエンコードされた文字セットを使用して音訳命令自体を書くことができます(大文字はそれほど便利ではありませんが、大文字への変更を指定するには便利です)。利用できない最も注目すべき文字は、、およびですが[、どれも必要ありません(出力に改行が必要なときは、暗黙的な改行を使用して生成しました\]say書く必要はあり\nません。chr 10うまくいきますが、より冗長です)。

いつものように、ラッパーの内部が文字列リテラルの外側で破損した場合、どうなるかを心配する必要があります。破損evalすると、何も実行できなくなります。大丈夫です。引用符が破損すると、文字列の内側が有効なPerlではないため、ラッパーがそれをキャッチします(文字列の多数の減算は、有効なPerlを作成できたとしても、何もしないことを意味します。許容できる結果です)。音訳の損傷、それは構文エラーでない場合は、一般的に引き起こして、評価されている文字列をマングルされます、それは構文エラーになるために。これが壊れるケースがないか100%確信しているわけではありませんが、現時点ではそれを強引に強制しているので、もしあれば修正するのは簡単です。

エンコードされたプログラム

私が使用するエンコーディング、および追加の空白を逆に、文字列リテラル内で見ると、それを読みやすくするために、我々は、これは(再び、前の制御、アンダースコアを想像し得る-+としてエンコードされ、A):

$o=q<
  length$o  ==181 || zzzz((()));
  do {
    chop ($t = "eval+<"x4);
    $r = '=-+;-AZz-~=';
    $s = '$o=q<' . $o . '>;eval$o';
    eval '$s=~y' . $r . 'A-Z=';
    say "$t(q($s)=~y=A-Z${r}r)" . "####>"x6;
    say ";" for 1..4
  } for 1..4;
  exit>;
eval $o

クインに慣れている人は、この一般的な構造を認識するでしょう。最も重要な部分は最初にあり、$ oが破損していないことを確認します。文字が削除された場合は、その長さが一致しません181、我々は実行するので、zzzz((()))それが原因比類のないブラケットに構文エラーでない場合のいずれもいるので、あなたが任意の3つの文字を削除しても、ランタイムエラーになりますこれ、zzzzzzzzz、そしてz関数であり、削除(((して曖昧な構文エラーを引き起こす以外の関数として解析するのを防ぐ方法はありません。小切手自体も損傷を受けません。は||破損する可能性があります|が、それによりzzzz((()))呼び出しが無条件に実行されます。あなたのいずれかを比較しているので、不一致が発生します変数や定数を損傷し0180179178の桁のいくつかのサブセットに平等のために181、1つ=を削除すると解析エラーが発生し、2つ=を削除するとLHSが整数0またはNULL文字列に評価され、どちらも偽になります。

更新:以前のバージョンのプログラムではこのチェックが少し間違っていたため、問題を修正するために編集する必要がありました。デコード後の以前のバージョンは次のようになりました。

length$o==179||zzzz((()))

これを取得するために最初の3つの句読点を削除することができました。

lengtho179||zzz((()))

lengtho179、裸語であることは真実であり、したがってチェックを破ります。B空白文字をエンコードする余分な2 文字を追加することでこれを修正しました。つまり、最新バージョンのクインはこれを行います。

length$o  ==181||zzzz((()))

構文エラーを生成せずに=記号と$記号の両方を非表示にすることは不可能になりました。(私はの長さがあるため二つの空間ではなく、1を追加する必要がありました180リテラル置く0整数比較成功裸の単語、とゼロ。この文脈で悪用される可能性がソースの中に文字を)終了更新

長さのチェックに合格すると、少なくとも文字が削除されているという点で、コピーが破損していないことがわかります。そのため、そこからすべてが単純なクインです(破損したデコードテーブルによる句読点の置換は、このチェックでは検出されません) 、しかし、デコードテーブルのみから3つの削除がクインを壊さないことをブルートフォースで既に確認しました;おそらくそれらのほとんどが構文エラーを引き起こすでしょう)。$oすでに変数を持っているので、外側のラッパーをハードコードするだけです(ある程度の圧縮を行います。質問の部分は完全に省略しませんでした)。1つの秘isは、エンコードテーブルの大部分を$r; 内部ラッパーのエンコードテーブルセクションを生成するために文字どおりに印刷するかeval、デコードプロセスを逆に実行するためにその周りにいくつかのコードを連結します(エンコードされたバージョンの$ oがわかるようにします) 、この時点でデコードされたバージョンのみが利用可能です)。

最後に、完全なコピーであり、元のプログラム全体を出力できる場合exit、他のコピーもプログラムを印刷しようとするのを防ぐために呼び出します。

検証スクリプト

あまりきれいではありませんが、誰かが尋ねたのでそれを投稿します。私はさまざまな設定でこれを数回実行しました(通常は変更$min$max、関心のあるさまざまな領域をチェックします)。完全に自動化されたプロセスではありませんでした。他の場所でのCPU負荷が重いため、実行を停止する傾向があります。これが起こったとき、私$minは最初の値に変更し、$x完全にはチェックされず、スクリプトの実行を続けました(したがって、範囲内のすべてのプログラムが最終的にチェックされるようになりました)。プログラムの最初のコピーからの削除だけをチェックしました。これは、他のコピーからの削除ではそれ以上のことができないことは明らかだからです。

use 5.010;
use IPC::Run qw/run/;
undef $/;
my $program = <>;
my $min = 1;
my $max = (length $program) / 4 - 3;
for my $x ($min .. $max) {
    for my $y ($x .. $max) {
        for my $z ($y .. $max) {
            print "$x, $y, $z\n";
            my $p = $program;
            substr $p, $x, 1, "";
            substr $p, $y, 1, "";
            substr $p, $z, 1, "";
            alarm 4;
            run [$^X, '-M5.010'], '<', \$p, '>', \my $out, '2>', \my $err;
            if ($out ne $program) {
                print "Failed deleting at $x, $y, $z\n";
                print "Output: {{{\n$out}}}\n";
                exit;
            }
        }
    }
}

say "All OK!";

3
OPは少しあいまいです。しかし、スコアは(1116 * 1116)/ 3になると思いました。
グレッグマーティン

@GregMartin:(1116 * 1116)/ 3は415152であるため、このような状況でもこのエントリは勝ちます。ただし、複数の文字の削除を処理できるようにするインセンティブはほとんどないため、OPが意味することはないと思います。このクインは、1文字の削除を処理するためにのみ必要な場合は、長さの半分未満にすることができます。そのように解釈すると、スコアで有効な÷4が得られます。これは、n = 3から得られる÷3を上回るため、実際にはスコアの低いn = 1エントリの方が優れていることを意味します。

2
得点をより明確にしました。とにかく、これは絶対に信じられないです。誰もn> 1になるとは思わなかった
タクラ

1
それは句読点なしよりも文字のないプログラムを書くことは簡単だということはPerlについて何かを言う
ロバート・フレイザー

35

Befunge-98、884、n = 14、スコア≈2.636

f00f00f00f00f00f00f00f00f00f00f00f00f00f00f0xxxxxxxxxxxxxxx"""""""""""""""fffffffffffffff'''''''''''''''000000000000000\\\\\\\\\\\\\\\'''''''''''''''000000000000000\\\\\\\\\\\\\\\'''''''''''''''fffffffffffffff\\\\\\\\\\\\\\\111111111111111---------------:::::::::::::::!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!000000000000000aaaaaaaaaaaaaaa---------------bbbbbbbbbbbbbbb---------------***************jjjjjjjjjjjjjjj$$$$$$$$$$$$$$$'''''''''''''''+++++++++++++++kkkkkkkkkkkkkkk,,,,,,,,,,,,,,,333333333333333kkkkkkkkkkkkkkk$$$$$$$$$$$$$$$000000000000000{{{{{{{{{{{{{{{'''''''''''''''888888888888888uuuuuuuuuuuuuuu'''''''''''''''!!!!!!!!!!!!!!!111111111111111+++++++++++++++'''''''''''''''xxxxxxxxxxxxxxx###############;;;;;;;;;;;;;;;:::::::::::::::!!!!!!!!!!!!!!!kkkkkkkkkkkkkkk@@@@@@@@@@@@@@@dddddddddddddddkkkkkkkkkkkkkkk:::::::::::::::eeeeeeeeeeeeeeekkkkkkkkkkkkkkk,,,,,,,,,,,,,,,;;;;;;;;;;;;;;;

オンラインでお試しください!

これは、正確に14文字を削除する場合だけでなく、最大 14文字を削除する場合でも機能します。

n = 14非常にarbitrary意的な選択のように思えるかもしれませんが、実際に使用した手法は、実際には1から14までの耐放射線性の命令にしか使用できませんが、それを超えることは簡単ではありません(可能かもしれませんが、方法はわかりません)。次数1のクインはたった73バイトです(ただし、大きいには当てはまらないいくつかのゴルフトリックを採用していますn)。

200 20 xx""''ÈÈ..aa22**..33kk$$00{{''!!uu''!!11++''xx##;;::!!kk@@::,,,,;;

説明

この答えに取り組んでいたとき(2,0)、次のスニペットを使用して、耐放射線性の条件下で命令ポインターのデルタを設定できることがわかりました。

20020xx

これが機能する理由については、その回答をご覧ください。私は手で少しいじるだけでこれを見つけましたが、これは複数の文字の除去の下で堅牢な類似のパターンがあるかどうかという疑問を提起しました。そこで、これらを総当たりで検索する短いMathematicaスクリプトを作成しました。

n = 14;
m = 4;
Print @ FromDigits @ {
      m + 1, 0, 
      ## & @@ ((m + 1) IntegerDigits[#, 2, n - 4]),
      m + 1, 0
} & /@ Select[
   Range[0, 2^(n - 4) - 1], 
   AllTrue[
     Subsets[{
         m + 1, 0, 
         ## & @@ ((m + 1) IntegerDigits[#, 2, n - 4]),
         m + 1, 0
       }, 
       {n - m, n - 1}
     ] //. {a___, _, m + 1} | {a___, 0, _} :> {a}, 
     MatchQ@{___, m + 1, 0}
  ] &
];

これは非常に迅速にパターンを明らかにしました。最大でn文字を削除するために機能する対応するスニペットを取得する(m0x){n}m0mn+1、where is およびxis mまたはorのいずれかを使用できます0。したがって、次のすべてが最大2文字の削除に使用できます。

30030030
30030330
30330030
30330330

これを証明することは可能だと確信していますが、n最大でを検証しました7。もちろん、これn+1は1桁で表現できる場合にのみ機能し、Befunge 98の最大の桁はf15を表します。そのため、私のアプローチはに制限されていn = 14ます。誰かがデルタをより確実に大きく設定する方法を見つけた場合n+1、この耐放射線性のクインの次数を無期限に増やすことが可能です。

実際のコードを見てみましょう。基本的に2つの部分があります。最初に、(15,0)前述のようにデルタを設定します。

f00f00f00f00f00f00f00f00f00f00f00f00f00f00f0xxxxxxxxxxxxxxx

そして、残りのコードでは各コマンドが15回繰り返され、ソースが出力されます。繰り返しを削除すると、次のようになります。

"f'0\'0\'f\1-:!!0a-b-*j$'+k,3k$0{'8u'!1+'x#;:!k@dk:ek,;

これ"は標準の2Dクイニング手法です。文字列モードを開始し、すべての文字(それ自体を除く)をスタックにプッシュし、ラップアラウンド後に文字列モードを終了します。全体であるため、これは、私たちは後半のすべてのコード・ポイントを得ることができますが、それは私たちに前半から有用な何かを得るために失敗するf00f00...f0ビット、それが唯一のいずれであってもよい2つの文字(記録しますfまたは0文字が削除されたかに依存します)。ただし、その部分は15回繰り返される文字で構成されていないため、とにかく個別に印刷する必要があります。

より便利なのは、変更されていないクインでは、の前の文字列の長さ"です-1 (mod 15)。どんなに私たちがいることを、削除文字数(14まで)ことをこれは保証番号の文字は常に3(ある記録xと2のf0)。これは、14までのすべての放射線次数に対して実際に当てはまります。

f00f00...f0部品の印刷から始めます。

f'0\'0\'f\1-:!!0a-b-*j$'+k,

f          Push 15, a loop counter.
'0\'0\'f\  Put "00f" underneath the loop counter.
1-         Decrement the loop counter.
:!!        Copy it, and turn it into a 1 if it's positive.
0a-b-      Push -21.
*          Multiply by 0 if the loop counter is zero, or by 1 otherwise.
j          Jump that many steps. If the value was 0, this is a no-op and
           the loop ends. Otherwise, this brings us back after the f.
$          Pop the loop counter (which is now 0).
'+k,       Print the top of the stack 43 times, which gives us all of
           the "f00f00...f0" and leaves one "0" on top of the stack.

次は、プログラムの最初からプッシュされた3つの文字と同様に3k$それ0を単に破棄し"ます。スタックには、削除された文字に応じて"、元の文字の後だけでなく、元の文字の下f00f00...f0にある文字のみが含まれるようになりました。

ここで、スタックの一番上(残りの文字を含む)を反転し、それぞれを15回印刷するだけです。

0{     Start a new, empty stack. This pushes two zeros onto the original stack.
'8u    Move the top 56 values from the original stack to the new one, which
       is the 54 characters after the " as well as those two zeros. This is
       implemented as pop-push loop, so it reverses the order of those elements.
'!1+   Push a " by incrementing a !.
'x     Push an x. Now we've got all the characters that are repeated 15 times.
#;     Enter a loop. This is a standard technique for Befunge-98: the ; is
       a bit like a comment character, that ignores everything until the next
       ;, but we jump over the first one with #, so that from now on only
       the code inside will be executed (over and over).
  :!     Copy the top of the stack, and compute logical NOT (1 if 0, 0 otherwise).
  k@     Terminate the program that many times (i.e. when the top of the
         stack is zero).
  dk:    Make 14 copies of the top of the stack.
  ek,    Print 15 characters from the top of the stack.
;

以上です。:)


16

JavaScript(ES6)、927バイト、n = 1、スコア= 859329

注:これを実行するために(ブラウザコンソールのような)REPLを使用しないでください。

これはコード長が要因になる前に書かれたため、まだゴルフされていません。

これは非常に難しく、徹底的な説明に値します。これについては、この課題をもう少し詳しく検討した後で説明します。

etTimeout=stTimeout=seTimeout=setimeout=setTmeout=setTieout=setTimout=setTimeut=setTimeot=setTimeou=unescape=>42;
setTimeout
`c="function f(){x=String.fromCharCode(96);n=String.fromCharCode(10);q=String.fromCharCode(34);y='etTimeout=stTimeout=seTimeout=setimeout=setTmeout=setTieout=setTimout=setTimeut=setTimeot=setTimeou=unescape=>42;'+n;z='setTimeout'+n+x+'c='+q+f+';f();_=1'+q+';if(window._);else if(c.length>339)eval(c)//'+x+'///'+x+n+n;console.log(y+z+z)};f();_=1";if(window._);else if(c.length>339)eval(c)//`///`

setTimeout
`c="function f(){x=String.fromCharCode(96);n=String.fromCharCode(10);q=String.fromCharCode(34);y='etTimeout=stTimeout=seTimeout=setimeout=setTmeout=setTieout=setTimout=setTimeut=setTimeot=setTimeou=unescape=>42;'+n;z='setTimeout'+n+x+'c='+q+f+';f();_=1'+q+';if(window._);else if(c.length>339)eval(c)//'+x+'///'+x+n+n;console.log(y+z+z)};f();_=1";if(window._);else if(c.length>339)eval(c)//`///`

注:末尾に改行があります

基本的に、最初の行はすべての「スペルミス」の名前setTimeoutを有効な関数に変更するように慎重に構成されているため、いずれかの文字が文字から削除されsetTimeoutてもコードはエラーにならず、無傷のバージョンが実行できます。また、最初の行からいずれかの文字が削除されてもエラーが発生せず、残りのコードが影響を受けずに実行できるように記述されています。

2番目と3番目のブロックはまったく同じです。一方が完了まで実行されると、_変数を設定して、もう一方がクインを複製しないようにします。これらのブロックの1つがエラーになった場合、を使用して非同期に呼び出されたため、他のブロックには影響しませんsetTimeout。このエラーは_設定されないため、他のブロックは正常に終了します。メインコードは文字列内にあり、各ブロックの長さをチェックして、削除されていないことを確認します。

次の行にあるテンプレート文字列は、テンプレート文字列の最後にコメントが付いているため、テンプレート文字列を形成するバックティックの1つが削除された場合、コードがエラーになりません。終了するバックティックが削除された場合、テンプレート文字列はコメント内のバックティックによって終了します。開始バックティックが削除されると、setTimeoutは未割り当て関数(no-op)として評価され、setTimeoutなしで通常どおりコードが実行されます。最後のバックティックは別のコメントによって無効にされます。


あなたは何と言いますか?あなたはそれを試してみたいですか?もうこれ以上言わない!

全ページモードを推奨。

入力ボックスを無視すると、このスニペットは入力を受け取りません。

コードから任意の1文字を削除してみてください!

信じられない?通常のコードがしますまだ仕事(それはないQUINEでしょう...)のようなものを試してみてくださいconsole.log(5)

注:REPL機能を無効にするには、スニペットをわずかに変更する必要があったため、この回答のみの複数の出力機能を削除しました。

etTimeout=stTimeout=seTimeout=setimeout=setTmeout=setTieout=setTimout=setTimeut=setTimeot=setTimeou=unescape=>42;
setTimeout
`c="function f(){x=String.fromCharCode(96);n=String.fromCharCode(10);q=String.fromCharCode(34);y='etTimeout=stTimeout=seTimeout=setimeout=setTmeout=setTieout=setTimout=setTimeut=setTimeot=setTimeou=unescape=>42;'+n;z='setTimeout'+n+x+'c='+q+f+';f();_=1'+q+';if(window._);else if(c.length>339)eval(c)//'+x+'///'+x+n+n;console.log(y+z+z)};f();_=1";if(window._);else if(c.length>339)eval(c)//`///`

setTimeout
`c="function f(){x=String.fromCharCode(96);n=String.fromCharCode(10);q=String.fromCharCode(34);y='etTimeout=stTimeout=seTimeout=setimeout=setTmeout=setTieout=setTimout=setTimeut=setTimeot=setTimeou=unescape=>42;'+n;z='setTimeout'+n+x+'c='+q+f+';f();_=1'+q+';if(window._);else if(c.length>339)eval(c)//'+x+'///'+x+n+n;console.log(y+z+z)};f();_=1";if(window._);else if(c.length>339)eval(c)//`///`
<!--                               Try the test suite below!                              --><strong id="bytecount" style="display:inline; font-size:32px; font-family:Helvetica"></strong><strong id="bytediff" style="display:inline; margin-left:10px; font-size:32px; font-family:Helvetica; color:lightgray"></strong><br><br><pre style="margin:0">Code:</pre><textarea id="textbox" style="margin-top:5px; margin-bottom:5px"></textarea><br><pre style="margin:0">Input:</pre><textarea id="inputbox" style="margin-top:5px; margin-bottom:5px"></textarea><br><button id="testbtn">Test!</button><button id="resetbtn">Reset</button><br><p><strong id="origheader" style="font-family:Helvetica; display:none">Original Code Output:</strong><p><div id="origoutput" style="margin-left:15px"></div><p><strong id="newheader" style="font-family:Helvetica; display:none">New Code Output:</strong><p><div id="newoutput" style="margin-left:15px"></div><script type="text/javascript" id="golfsnippet">var bytecount=document.getElementById("bytecount");var bytediff=document.getElementById("bytediff");var textbox=document.getElementById("textbox");var inputbox=document.getElementById("inputbox");var testbtn=document.getElementById("testbtn");var resetbtn=document.getElementById("resetbtn");var origheader=document.getElementById("origheader");var newheader=document.getElementById("newheader");var origoutput=document.getElementById("origoutput");var newoutput=document.getElementById("newoutput");textbox.style.width=inputbox.style.width=window.innerWidth-50+"px";var _originalCode=null;function getOriginalCode(){if(_originalCode!=null)return _originalCode;var allScripts=document.getElementsByTagName("script");for(var i=0;i<allScripts.length;i++){var script=allScripts[i];if(script.id!="golfsnippet"){originalCode=script.textContent.trim();return originalCode}}}function getNewCode(){return textbox.value.trim()}function getInput(){try{var inputText=inputbox.value.trim();var input=eval("["+inputText+"]");return input}catch(e){return null}}function setTextbox(s){textbox.value=s;onTextboxChange()}function setOutput(output,s){output.innerHTML=s}function addOutput(output,data){output.innerHTML='<pre style="background-color:'+(data.type=="err"?"lightcoral":"lightgray")+'">'+escape(data.content)+"</pre>"}function getByteCount(s){return(new Blob([s],{encoding:"UTF-8",type:"text/plain;charset=UTF-8"})).size}function onTextboxChange(){var newLength=getByteCount(getNewCode());var oldLength=getByteCount(getOriginalCode());bytecount.innerHTML=newLength+" bytes";var diff=newLength-oldLength;if(diff>0){bytediff.innerHTML="(+"+diff+")";bytediff.style.color="lightcoral"}else if(diff<0){bytediff.innerHTML="("+diff+")";bytediff.style.color="lightgreen"}else{bytediff.innerHTML="("+diff+")";bytediff.style.color="lightgray"}}function onTestBtn(evt){origheader.style.display="inline";newheader.style.display="inline";setOutput(newoutput,"");setOutput(origoutput,"");var input=getInput();if(input===null){addOutput(origoutput,{type:"err",content:"Input is malformed. Using no input."});addOutput(newoutput,{type:"err",content:"Input is malformed. Using no input."});input=[]}doInterpret(getNewCode(),input,function(data){addOutput(newoutput,data)});doInterpret(getOriginalCode(),input,function(data){addOutput(origoutput,data)});evt.stopPropagation();return false}function onResetBtn(evt){setTextbox(getOriginalCode());origheader.style.display="none";newheader.style.display="none";setOutput(origoutput,"");setOutput(newoutput,"")}function escape(s){return s.toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}window.alert=function(){};window.prompt=function(){};function doInterpret(code,input,cb){var workerCode=interpret.toString()+";function stdout(s){ self.postMessage( {'type': 'out', 'content': s} ); }"+" function stderr(s){ self.postMessage( {'type': 'err', 'content': s} ); }"+" function kill(){ self.close(); }"+" self.addEventListener('message', function(msg){ interpret(msg.data.code, msg.data.input); });";var interpreter=new Worker(URL.createObjectURL(new Blob([workerCode])));interpreter.addEventListener("message",function(msg){cb(msg.data)});interpreter.postMessage({"code":code,"input":input});setTimeout(function(){interpreter.terminate()},1E4)}setTimeout(function(){getOriginalCode();textbox.addEventListener("input",onTextboxChange);testbtn.addEventListener("click",onTestBtn);resetbtn.addEventListener("click",onResetBtn);setTextbox(getOriginalCode())},100);function interpret(code,input){_=undefined;window={};alert=function(s){stdout(s)};window.alert=alert;console.log=alert;prompt=function(s){if(input.length<1)stderr("not enough input");else{var nextInput=input[0];input=input.slice(1);return nextInput.toString()}};window.prompt=prompt;(function(){try{_=undefined;eval(code);if(typeof evalResult=="disabled_function_evaluation"){var callResult=evalResult.apply(this,input);if(typeof callResult!="undefined")stdout(callResult)}}catch(e){stderr(e.message)}})()};</script>

より良い説明が近づいています。それまでの間、@ jrichのチャットでコメントや質問、批評をお寄せください。


ああ、大丈夫:|
ダウンゴート

4
this代わりに使用しますwindow
ママファンロール

3
生命の意味をソースコードに含めるための+1
Cyoce
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.