zsh, 603 594 566 561 548 440 415 399 378 370 ไบต์
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;}
ขึ้นอยู่กับ coreutils dc
+
ลองออนไลน์!
นั่นคือ ... การเดินทาง
คำตอบนี้มีสามส่วน 4 บรรทัดแรกจัดการกรณีพิเศษบางอย่างเพื่อให้รหัสที่ตามมาง่ายขึ้น 2 บรรทัดถัดไปและบรรทัดสุดท้ายทั้งสองประสบความสำเร็จโดยพื้นฐานแล้วสิ่งเดียวกัน แต่หนึ่งบรรทัดนั้นถูกรันด้วยการลบอักขระที่กำหนด พวกเขาเขียนด้วยชุดอักขระส่วนใหญ่ที่สมบูรณ์ดังนั้นการลบอักขระใด ๆ จะแบ่งได้เพียงชุดเดียวมากที่สุดทำให้ผู้อื่นสามารถทำงานต่อไปได้
ดูที่ส่วนแรกเราจัดการก่อน
- การลบบรรทัดใหม่ด้วย
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
) จะไม่สามารถเกิดขึ้นได้ในบรรทัดสุดท้าย การขยายค่า Escape ฐานแปด ( $'\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 สามารถทำงานได้ สิ่งนี้สามารถทำได้โดยการใส่รองเท้าใน:
และ;
ซึ่งมี 2 และ 3 ในการแสดงฐานแปดของพวกเขาตามลำดับ
ขยะที่ท้ายบรรทัด 2 นั้นอยู่ที่นั่นเพื่อให้แน่ใจว่าทุกตัวอักษร ASCII ที่พิมพ์ได้จะปรากฏขึ้นอย่างน้อยหนึ่งครั้งเนื่องจากวิธีการตรวจสอบทำได้โดยการวนซ้ำผ่านแต่ละอันที่ต้องการ
หากexit
ไม่ได้รับการเรียกในส่วนแรก (เช่นมันถูกทำให้ยุ่งเหยิงโดยการลบหนึ่งใน'\01234567v
) เราจะย้ายไปยังส่วนที่สองซึ่งเราต้องทำสิ่งเดียวกันให้สำเร็จโดยไม่ต้องใช้ตัวอักษรเหล่านี้ บรรทัดสุดท้ายคล้ายกับบรรทัดแรกที่ถอดรหัสยกเว้นว่าเราสามารถสัญญาช่วงของลูปเพื่อบันทึกสองสามไบต์เพราะเรารู้แล้วว่าตัวละครทั้งหมดยกเว้น'\01234567v
ได้รับการคุ้มครอง นอกจากนี้ยังมี0# $#
ก่อนหน้าซึ่งแสดงความคิดเห็นและป้องกันไม่ให้สร้างผลลัพธ์ภายนอกหาก0
หรือ$
ลบออก