放射線硬化照射器を書く


17

タスクは、放射線硬化照射装置を作成することです。それはどういう意味ですか?

照射器は、入力として文字列が与えられると、1文字が削除された文字列のすべての可能なバージョンを出力するプログラムです。たとえば、入力が与えられるHello, world!と、プログラムは次を出力します。

ello, world!
Hllo, world!
Helo, world!
Helo, world!
Hell, world!
Hello world!
Hello,world!
Hello, orld!
Hello, wrld!
Hello, wold!
Hello, word!
Hello, worl!
Hello, world

ただし、照射器はその放射線から保護する必要があるため、作成した照射器はそれ自体を通過したときにも存続する必要があります。つまり、プログラムの1バイトが削除されても、プログラムは適切に機能する必要があります。

テストケース

abc -> bc; ac; ab
foo bar -> oo bar:fo bar:fo bar:foobar:foo ar:foo br:foo ba
source -> ource;surce;sorce;souce;soure;sourc;

仕様書

  • 標準のI / Oルールで受け入れ可能な任意の方法で入力することができます
  • 出力は、文字列のリスト、または文字または文字のグループで区切られた印刷リストのいずれかです。末尾の区切り文字は許容されます
  • 出力は、可能なすべてのバージョンが含まれている限り、どのような順序でもかまいません
  • 重複エントリ(2つなど) Helo, world!最初の例のつなど)は除外される場合がありますが、これは必須ではありません
  • これはであるため、バイト単位の最小プログラムが勝ちます

...またはコンマ?
ジョナサンアラン

4
Cプログラムのため、この1は本当に、ゴルフの言語に有利さvvoid削除がコンパイルされません
クシシュトフSzewczyk

3
@Krzysztof tbhすべてではないにしても、ほとんどの実用的な言語は、冗長性と構文のために放射線硬化に耐えられないと思います。この課題だけでなく、すべてのRHの課題。
朝琴シエル

回答:


13

05AB1E29 26バイト

æIg<ùˆ\æIg<ùˆ\æIg<ùˆ¯¯{Å`s

オンラインでお試しください!、またはすべての照射バージョンを試してください

私が見つけることができる最短の照射器は5バイトです:

æ        # powerset of the input
 Ig      # length of the input
   <     # - 1
    ù    # elements of a with length b

これを3回繰り返してから、多数決を行うという考え方です。

æIg<ù         # irradiate
     ˆ        # add the result to the global array
      \       # pop (in case the above instruction gets irradiated)
æIg<ùˆ\       # idem
æIg<ùˆ        # no pop, it's okay to dirty the stack at this point
¯             # push global array
 ¯            # and again, so at least one goes through
  {           # sort
   Å          # conveniently ignored by the parser
    `         # dump
     s        # swap
              # and implicitly output

Åは2バイトのコマンドのプレフィックスですが、コマンドÅ`はないため、Å getsは無視されます。ただし、後で必要になります。

ソートにより、多数決が配列の中央にあることが確認されます。ダンプしてからスワップすると、その値がスタックの一番上になります。

最初の部分の照射は、グローバル配列のエラーのみをもたらし、これは多数決によって解決されます。最後の部分の照射は、以下{Å`sについて推論するのがはるかに難しいです。

  • Å とにかく無視されるので、それを照射しても大丈夫です

  • バッククォートが照射されると、Å`sなるとÅs、拡張コマンド「アレイの真ん中の取得」です。

  • {またはs照射されている場合、それは他に何もないことを意味するため、グローバル配列は同じ値である3回です。その場合、ソート/スワッピングは必要ありません。どの値でも機能します。


3
非常に印象的!RHチャレンジで05AB1Eの回答が表示されるとは思いませんでした。すぐにこの答えに報いるために賞金を追加します(そして、チャレンジにもう少し露出を与えます)。あなたは私の非常に多くの答えをゴルフしたので、あなたもそれらの多くの信用に値します!:)
Kevin Cruijssen

3
実際、以前にRHチャレンジに関する05AB1Eの回答を見たことがあります。それでも、非常に印象的です!
ケビンクルーッセン

5

8086マシンコード(MS-DOS .COM)、83バイト

DOSBoxまたはお好みの蒸気動力のコンピューティングエンジンで実行可能。照射する文字列は、コマンドライン引数として指定されます。

バイナリ:

00000000 : EB 28 28 8A 0E 80 00 49 BD 83 00 B4 02 51 8A 0E : .((....I.....Q..
00000010 : 80 00 BE 82 00 AC 39 EE 74 04 88 C2 CD 21 E2 F5 : ......9.t....!..
00000020 : 59 45 B2 0A CD 21 E2 E5 C3 90 EB D7 D7 8A 0E 80 : YE...!..........
00000030 : 00 49 BD 83 00 B4 02 51 8A 0E 80 00 BE 82 00 AC : .I.....Q........
00000040 : 39 EE 74 04 88 C2 CD 21 E2 F5 59 45 B2 0A CD 21 : 9.t....!..YE...!
00000050 : E2 E5 C3                                        : ...

読みやすい:

cpu 8086
org 0x100
    jmp part2
    db 0x28

part1:
    mov cl, [0x80]
    dec cx
    mov bp, 0x83
    mov ah, 0x02

.l:
    push cx
    mov cl, [0x80]
    mov si, 0x82
.k:
    lodsb
    cmp si, bp
    je .skip
    mov dl, al
    int 0x21
.skip:
    loop .k
    pop cx
    inc bp
    mov dl, 10
    int 0x21
    loop .l
    ret

    nop
part2:
    jmp part1
    db 0xd7
    mov cl, [0x80]
    dec cx
    mov bp, 0x83
    mov ah, 0x02

.l:
    push cx
    mov cl, [0x80]
    mov si, 0x82
.k:
    lodsb
    cmp si, bp
    je .skip
    mov dl, al
    int 0x21
.skip:
    loop .k
    pop cx
    inc bp
    mov dl, 10
    int 0x21
    loop .l
    ret

流れ落ちる

アクティブ部分は複製されているため、常に放射線の影響を受けない部分があります。ジャンプを使用して健全なバージョンを選択します。各ジャンプは短いジャンプであるため、2バイトの長さしかありません。2番目のバイトは変位(つまり、方向を決定する符号付きのジャンプまでの距離)です。

コードを照射可能な4つの部分に分割できます。ジャンプ1、コード1、ジャンプ2、およびコード2。アイデアは、クリーンなコード部分が常に使用されるようにすることです。コード部分の1つが照射された場合、もう1つを選択する必要がありますが、ジャンプの1つが照射された場合、両方のコード部分がきれいになるため、どちらを選択してもかまいません。

ジャンプ部分が2つある理由は、最初の部分のジャンプを飛び越えて検出するためです。最初のコード部分が照射されると、マークから1バイト離れて到着することを意味します。そのような失敗した着陸がコード2を選択し、適切な着陸がコード1を選択することを確認すると、黄金色になります。

両方のジャンプについて、変位バイトを複製し、各ジャンプ部分を3バイト長にします。これにより、最後の2バイトのいずれかを照射しても、ジャンプが有効になります。最後の2バイトは完全に異なる命令を形成するため、最初のバイトの照射はジャンプの発生をまったく停止します。

最初のジャンプをしてください:

EB 28 28        jmp +0x28 / db 0x28

いずれかの0x28バイトが削除されても、同じ場所にジャンプします。場合は0xEB、バイトが削除され、我々は代わりになってしまいます

28 28           sub [bx + si], ch

これはMS-DOS上の良性の命令であり(他のフレーバーは同意しない場合があります)、コード1に進みます。損傷はジャンプ1であったため、クリーンでなければなりません。

ジャンプが行われた場合、2回目のジャンプで着陸します。

EB D7 D7        jmp -0x29 / db 0xd7

このバイトシーケンスに問題がなく、マークに到達した場合、コード1はクリーンであり、この命令はその部分にジャンプして戻ります。複製されたディスプレイスメントバイトは、これらのディスプレイスメントバイトのいずれかが破損した場合でも、これを保証します。(損傷したコード1または1のジャンプのために)1バイトを着陸するか、その0xEBバイトが損傷したバイトである場合、残りの2つのバイトもここで問題ありません。

D7 D7           xlatb / xlatb

いずれにせよ、これら2つの命令を実行することになった場合、ジャンプ1、コード1、またはジャンプ2のいずれかが照射されたことがわかり、コード2へのフォールスルーが安全になります。

テスト中

次のプログラムは、.COMファイルのすべてのバージョンを自動的に作成するために使用されました。また、ターゲット環境で実行可能なBATファイルを作成します。このファイルは、照射された各バイナリを実行し、出力を個別のテキストファイルにパイプします。検証する出力ファイルの比較は簡単ですが、DOSBoxにはないfcため、BATファイルに追加されませんでした。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    FILE *fin, *fout, *fbat;
    int fsize;
    char *data;

    if (!(fin = fopen(argv[1], "rb")))
    {
        fprintf(stderr, "Could not open input file \"%s\".\n", argv[1]);
        exit(1);
    }

    if (!(fbat = fopen("tester.bat", "w")))
    {
        fprintf(stderr, "Could not create BAT test file.\n");
        exit(2);
    }

    fseek(fin, 0L, SEEK_END);
    fsize = ftell(fin);
    fseek(fin, 0L, SEEK_SET);

    if (!(data = malloc(fsize)))
    {
        fprintf(stderr, "Could not allocate memory.\n");
        exit(3);
    }

    fread(data, 1, fsize, fin);

    fprintf(fbat, "@echo off\n");

    for (int i = 0; i < fsize; i++)
    {
        char fname[512];

        sprintf(fname, "%03d.com", i);
        fprintf(fbat, "%s Hello, world! > %03d.txt\n", fname, i);

        fout = fopen(fname, "wb");

        fwrite(data, 1, i, fout);
        fwrite(data + i + 1, 1, fsize - i - 1, fout);

        fclose(fout);
    }

    free(data);
    fclose(fin);
    fclose(fbat);
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.