zsh, 603 594 566 561 548 440 415 399 378 370 byte
ec
ho \\n;ca t<<<$'\x20';exi t
d$c -e8BC6P
d0c -eKp
$'\172\163\150' $'\055\143' $'\146\157\162 v \151\156 \173\043\056\056\134\175\175\073\173 \146\147\162\145\160 \055\161 $\166 '$0$'\174\174\074\074\074$\166\073\175'
$'\145v\141\154' $':\073\072\046\046\145\170\151\164';#%&()*+,/9=>?@ADEFGHIJLMNOQRSTUVWXYZ[]^_`jklmsuwy
0# $#;for b in {$..z};{ fgrep -q $b $0||<<<$b;}
Tergantung pada coreutils + dc
.
Cobalah online!
Itu ... perjalanan.
Jawaban ini memiliki tiga bagian. 4 baris pertama menangani kasus khusus tertentu untuk menyederhanakan kode yang mengikuti. 2 baris berikutnya dan baris terakhir keduanya pada dasarnya menyelesaikan hal yang sama, tetapi tepat satu dijalankan dengan penghapusan karakter tertentu. Mereka ditulis dengan sebagian besar set karakter komplementer, sehingga menghapus setiap karakter hanya memecah satu karakter paling banyak, memungkinkan yang lain untuk terus berfungsi.
Melihat bagian pertama, kami pertama menangani
- penghapusan baris baru dengan
ec\nho \\n
- penghapusan ruang dengan
ca t<<<$'\x20'
(diikuti oleh exi t
untuk menghindari menjalankan kode yang lebih baru, yang akan menghasilkan keluaran asing)
$
penghapusan dengan d$c -e8BC6P
( 8BC6
= 9226
adalah 36*256 + 10
, dan 36 dan 10 adalah nilai byte $
masing-masing dan karakter baris baru; kami menggunakan digit hex dalam desimal untuk menghindari keharusan memasukkannya dalam komentar besar di baris 6)
0
penghapusan dengan d0c -eKp
( K
mendapatkan presisi desimal, yang secara 0
default)
Di bagian selanjutnya, satu-satunya karakter yang digunakan (selain dari sampah di akhir baris kedua) adalah $'\01234567v;
, spasi, dan baris baru. Dari jumlah tersebut, empat telah diperhitungkan, sehingga sisanya ( '\1234567v
) tidak dapat terjadi di baris terakhir. Memperluas lolos oktal ( $'\123'
mewakili karakter ASCII dengan nilai 123 8 ), kita mendapatkan:
zsh -c 'for v in {#..\}};{ fgrep -q $v '$0'||<<<$v;}'
eval ':;:&&exit'
Baris pertama loop melalui semua karakter yang digunakan dalam program dan mencari masing-masing dalam kode sumbernya sendiri ( $0
adalah nama file dari skrip yang sedang dijalankan), mencetak karakter apa pun yang tidak ditemukan.
Baris kedua terlihat sedikit aneh, dan tampaknya melakukan hal yang sama exit
dengan sekelompok orang. Namun, pengodean exit
sebagai oktal langsung menghasilkan $'\145\170\151\164'
, yang tidak mengandung 2
atau 3
. Kami benar-benar perlu membuat ini kurang tahan terhadap pemindahan. Ini karena jika ada '\014567v
yang dihapus, melanggar baris pertama, baris kedua juga rusak, yang memungkinkan sisa kode untuk dieksekusi. Namun, kita perlu juga memutus jika 2
atau 3
dihapus sehingga baris 3 dan 4 dapat berjalan. Ini dicapai dengan memilih di :
dan ;
, yang masing-masing memiliki 2 dan 3 dalam representasi oktal mereka.
Sampah di akhir baris 2 ada di sana untuk memastikan setiap karakter ASCII yang dapat dicetak muncul setidaknya satu kali, karena cara pemeriksaan dilakukan dengan mengulangi masing-masing membutuhkan ini.
Jika exit
tidak dipanggil di bagian pertama (yaitu rusak oleh penghapusan salah satu '\01234567v
), kita beralih ke yang kedua, di mana kita harus mencapai hal yang sama tanpa menggunakan salah satu karakter ini. Baris terakhir mirip dengan baris pertama yang didekodekan, kecuali bahwa kita dapat mengontrak rentang loop untuk menyimpan beberapa byte, karena kita sudah tahu bahwa semua karakter kecuali '\01234567v
telah tercakup. Ia juga memiliki 0# $#
sebelumnya, yang berkomentar dan mencegahnya menghasilkan output yang asing jika 0
atau $
telah dihapus.