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;}
Phụ thuộc vào coreutils + dc
.
Hãy thử trực tuyến!
Đó là ... một hành trình.
Câu trả lời này có ba phần. 4 dòng đầu tiên xử lý một số trường hợp đặc biệt để đơn giản hóa mã theo sau. Cả hai dòng tiếp theo và dòng cuối cùng đều thực hiện cùng một thứ, nhưng chính xác thì một dòng được chạy với bất kỳ loại bỏ ký tự nào. Chúng được viết với hầu hết các bộ ký tự bổ sung, do đó việc loại bỏ bất kỳ ký tự nào chỉ phá vỡ tối đa một ký tự, cho phép các ký tự khác tiếp tục hoạt động.
Nhìn vào phần đầu tiên, chúng tôi xử lý đầu tiên
- xóa dòng mới với
ec\nho \\n
- loại bỏ không gian bằng
ca t<<<$'\x20'
(theo sau exi t
để tránh chạy mã sau này, điều này sẽ dẫn đến đầu ra không liên quan)
$
loại bỏ với d$c -e8BC6P
( 8BC6
= 9226
is 36*256 + 10
và 36 và 10 là các giá trị byte của các $
ký tự và dòng mới tương ứng, chúng tôi sử dụng các chữ số thập phân ở dạng thập phân để tránh phải đưa chúng vào nhận xét lớn trong dòng 6)
0
xóa bằng d0c -eKp
( K
lấy độ chính xác thập phân, 0
theo mặc định)
Trong phần tiếp theo, các ký tự duy nhất được sử dụng (ngoài thùng rác ở cuối dòng thứ hai) là $'\01234567v;
, khoảng trắng và dòng mới. Trong số này, bốn cái đã được tính, vì vậy phần còn lại ( '\1234567v
) không thể xảy ra ở dòng cuối cùng. Mở rộng các lối thoát bát phân ( $'\123'
đại diện cho ký tự ASCII có giá trị 123 8 ), chúng tôi nhận được:
zsh -c 'for v in {#..\}};{ fgrep -q $v '$0'||<<<$v;}'
eval ':;:&&exit'
Dòng đầu tiên lặp qua tất cả các ký tự được sử dụng trong chương trình và tìm kiếm từng ký tự trong mã nguồn riêng của nó ( $0
là tên tệp của tập lệnh đang chạy), in bất kỳ ký tự nào không tìm thấy.
Dòng thứ hai trông hơi lạ, và dường như làm điều tương tự như exit
với một loạt các cảnh sát. Tuy nhiên, mã hóa exit
dưới dạng bát phân trực tiếp dẫn đến $'\145\170\151\164'
, không chứa 2
hoặc 3
. Chúng tôi thực sự cần phải làm cho điều này ít đàn hồi hơn để loại bỏ. Điều này là do nếu bất kỳ phần nào '\014567v
bị xóa, phá vỡ dòng đầu tiên, dòng thứ hai cũng bị phá vỡ, cho phép phần còn lại của mã được thực thi. Tuy nhiên, chúng tôi cần nó cũng bị 2
hỏng nếu hoặc 3
bị xóa để dòng 3 và 4 có thể chạy. Điều này được thực hiện bằng cách đánh giày :
và ;
, có 2 và 3 trong biểu diễn bát phân của chúng tương ứng.
Rác ở cuối dòng 2 chỉ đơn giản là ở đó để đảm bảo mọi ký tự ASCII có thể in xuất hiện ít nhất một lần, vì cách kiểm tra được thực hiện bằng cách lặp qua từng yêu cầu này.
Nếu exit
không được gọi trong phần đầu tiên (nghĩa là nó được xử lý bằng cách loại bỏ một trong số đó '\01234567v
), chúng ta chuyển sang phần thứ hai, trong đó chúng ta phải hoàn thành điều tương tự mà không sử dụng bất kỳ ký tự nào trong số này. Dòng cuối cùng tương tự như dòng đầu tiên được giải mã, ngoại trừ việc chúng ta có thể hợp đồng phạm vi của vòng lặp để lưu một vài byte, bởi vì chúng ta đã biết rằng tất cả các ký tự ngoại trừ '\01234567v
đã được bao phủ. Nó cũng có 0# $#
trước nó, nó nhận xét và ngăn nó tạo ra đầu ra bên ngoài nếu 0
hoặc $
bị loại bỏ.