zsh, 603 594 566 561 548 440 415 399 378 370 bytes
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;}
Depends on coreutils + dc.
Try it online!
That was... a journey.
Ця відповідь має три частини. Перші 4 рядки обробляють певні особливі випадки для спрощення коду, що випливає. Наступні два рядки і останній рядки виконують по суті одне і те ж, але саме один запускається з будь-яким видаленням символів. Вони записуються в основному взаємодоповнюючими наборами символів, так що видалення будь-яких символів порушує лише один максимум, що дозволяє іншому продовжувати функціонувати.
Дивлячись на першу частину, ми спочатку справляємося
- видалення нового рядка з
ec\nho \\n
- видалення місця з
ca t<<<$'\x20'(з подальшим exi tуникненням запуску більш пізнього коду, що призведе до стороннього виводу)
$видалення з d$c -e8BC6P( 8BC6= 9226є 36*256 + 10, а 36 і 10 - значення байтів $символів і рядків у новому рядку відповідно; ми використовуємо шістнадцяткові цифри у десяткових знаках, щоб уникнути необхідності включення їх у великий коментар у рядку 6)
0видалення з d0c -eKp( Kотримує десяткову точність, яка 0за замовчуванням)
У наступній частині використовуються єдині символи (окрім сміття в кінці другого рядка) $'\01234567v;, пробіл та новий рядок. З них четверо були обліковані, тому решта ( '\1234567v) не може бути в останньому рядку. Розгортаючи восьмеричні втечі ( $'\123'представляє символ ASCII зі значенням 123 8 ), отримуємо:
zsh -c 'for v in {#..\}};{ fgrep -q $v '$0'||<<<$v;}'
eval ':;:&&exit'
Перший рядок пробирає всі символи, які використовуються в програмі, і шукає кожного з них у власному вихідному коді ( $0це ім'я файлу запущеного сценарію), друкуючи будь-який символ, який не знайдено.
Другий рядок виглядає дещо дивно, і, здається, робить те саме, що і exitз купою сосків. Однак кодування exitяк вісімкового прямо призводить до того $'\145\170\151\164', що не містить 2або 3. Нам фактично потрібно зробити це менш стійким до видалення. Це відбувається тому, що якщо будь-який з '\014567vвидалених, порушуючи перший рядок, другий рядок також розривається, дозволяючи виконувати залишок коду. Однак нам це потрібно, щоб воно також було розірвано, якщо 2або 3видалено, щоб лінії 3 і 4 могли працювати. Це досягається за допомогою вбирання в :і;, which have a 2 and 3 in their octal representation respectively.
Небажана в кінці рядка 2 просто є для того, щоб кожен друкуваний символ ASCII, який можна роздрукувати, з’явився хоча б один раз, оскільки цього вимагає спосіб перевірки шляхом прокручування кожного з них.
Якщо exitв першому розділі не було викликано (тобто воно було порушено видаленням одного з '\01234567v), ми переходимо до другого, в якому ми повинні виконати те саме, не використовуючи жодного з цих символів. Останній рядок схожий на декодований перший рядок, за винятком того, що ми можемо скоротити діапазон циклу, щоб зберегти кілька байт, тому що ми вже знаємо, що всі символи, за винятком '\01234567v, були охоплені. Він також має 0# $#перед цим, який коментує це та заважає йому створювати сторонні результати, якщо 0або $були видалені.