Tugasnya adalah untuk menulis iradiator yang dikeraskan dengan radiasi. Apa yang saya maksud dengan itu, tepatnya?
Sebuah irradiator adalah program yang, ketika diberi string sebagai input, akan menampilkan semua versi string yang mungkin dengan satu karakter dihapus. Misalnya, diberi input Hello, world!
, program harus menampilkan:
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
Iradiator, bagaimanapun, harus dilindungi dari sinarnya, sehingga iradiator yang Anda tulis juga harus bertahan ketika dimasukkan melalui dirinya sendiri. Yaitu, ketika byte tunggal dari program Anda dihapus, program tersebut masih harus berfungsi dengan baik.
Uji kasus
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;
Spesifikasi
- Anda dapat mengambil input dengan metode apa pun yang dapat diterima oleh aturan I / O Standar kami
- Outputnya bisa berupa daftar string atau daftar cetak yang dibatasi oleh karakter atau kelompok karakter. Pembatas trailing dapat diterima
- Output mungkin dalam urutan apa pun asalkan berisi semua versi yang mungkin
- Entri duplikat (seperti dua
Helo, world!
s pada contoh pertama) dapat disaring, tetapi ini tidak perlu - Karena ini adalah kode-golf , program terkecil, dalam byte, menang
code-golf
radiation-hardening
TheOnlyMrCat
sumber
sumber
v
divoid
dihapus tidak akan mengkompilasiJawaban:
05AB1E ,
2926 byteCobalah online! , atau coba semua versi iradiasi .
Iradiator terpendek yang dapat saya temukan adalah 5 byte:
Idenya adalah mengulangi itu 3 kali, lalu lakukan voting mayoritas:
Å
adalah awalan untuk perintah 2-byte, tetapi tidak adaÅ`
perintah, itulah mengapaÅ
diabaikan. Kami akan membutuhkannya nanti.Penyortiran memastikan suara terbanyak ada di tengah array. Membuang lalu menukar membuat nilai itu ke atas tumpukan.
Setiap iradiasi di bagian awal hanya menghasilkan kesalahan dalam array global, yang diselesaikan dengan suara terbanyak. Iradiasi pada
{Å`s
bit terakhir jauh lebih sulit untuk dipikirkan:Å
tetap diabaikan, jadi tidak apa-apa untuk menyinari ituJika backtick diiradiasi,
Å`s
menjadiÅs
, yang merupakan perintah "get middle of the array".Jika
{
ataus
diradiasi, itu berarti tidak ada yang lain, jadi array global adalah nilai yang sama tiga kali. Dalam hal ini kita tidak perlu menyortir / bertukar, nilai apa pun akan berfungsi.sumber
8086 kode mesin (MS-DOS .COM), 83 byte
Runnable di DOSBox atau mesin komputasi bertenaga uap favorit Anda. String untuk iradiasi diberikan sebagai argumen baris perintah.
Biner:
Dapat dibaca:
Kehabisan
Bagian aktif diduplikasi sehingga selalu ada satu yang tidak tersentuh oleh radiasi. Kami memilih versi sehat dengan cara melompat. Setiap lompatan adalah lompatan pendek, dan panjangnya hanya dua byte, di mana byte kedua adalah perpindahan (yaitu jarak untuk melompat, dengan tanda yang menentukan arah).
Kita dapat membagi kode menjadi empat bagian yang dapat diiradiasi: lompat 1, kode 1, lompat 2, dan kode 2. Idenya adalah untuk memastikan bagian kode yang bersih selalu digunakan. Jika salah satu bagian kode diiradiasi, yang lain harus dipilih, tetapi jika salah satu lompatan diiradiasi, kedua bagian kode akan bersih, sehingga tidak masalah mana yang dipilih.
Alasan memiliki dua bagian lompatan adalah untuk mendeteksi iradiasi pada bagian pertama dengan melompati bagian itu. Jika bagian kode pertama diiradiasi, itu berarti kita akan tiba satu byte dari sasaran. Jika kami memastikan bahwa pendaratan yang gagal memilih kode 2, dan pendaratan yang tepat memilih kode 1, kami emas.
Untuk kedua lompatan, kami menduplikasi byte perpindahan, membuat masing-masing lompatan bagian 3 byte. Ini memastikan bahwa iradiasi di salah satu dari dua byte terakhir masih akan membuat lompatan valid. Iradiasi pada byte pertama akan menghentikan lompatan yang terjadi sama sekali, karena dua byte terakhir akan membentuk instruksi yang sama sekali berbeda.
Ambil lompatan pertama:
Jika salah satu dari
0x28
byte tersebut dihapus, masih akan melompat ke tempat yang sama. Jika0xEB
byte dihapus, kita akan berakhir denganyang merupakan instruksi jinak pada MS-DOS (rasa lain mungkin tidak setuju), dan kemudian kita masuk ke kode 1, yang harus bersih, karena kerusakan pada lompatan 1.
Jika lompatan diambil, kami mendarat di lompatan kedua:
Jika urutan byte ini utuh, dan kami mendarat tepat pada tanda, itu berarti bahwa kode 1 bersih, dan instruksi ini melompat kembali ke bagian itu. Byte perpindahan duplikat menjamin ini, bahkan jika itu adalah salah satu byte perpindahan ini yang rusak. Jika kita mendaratkan satu byte off (karena kode 1 rusak atau melompat 1) atau
0xEB
byte itu rusak, dua byte yang tersisa juga akan menjadi tidak berbahaya:Apapun masalahnya, jika kita akhirnya mengeksekusi kedua instruksi itu, kita tahu bahwa lompatan 1, kode 1, atau lompatan 2 diiradiasi, yang membuat keamanan dari kode 2 jatuh.
Pengujian
Program berikut ini digunakan untuk secara otomatis membuat semua versi file .COM. Ini juga menciptakan file BAT yang dapat dijalankan di lingkungan target, yang menjalankan setiap biner yang diiradiasi, dan menyalurkan outputnya ke file teks yang terpisah. Membandingkan file output untuk divalidasi cukup mudah, tetapi DOSBox tidak punya
fc
, jadi itu tidak ditambahkan ke file BAT.sumber