Quine รังสีแข็งตัว


39

อย่างที่คุณควร (หวังว่า) รู้ว่าควินที่ผ่านการฉายรังสีนั้นเป็นควินที่คุณสามารถลบตัวละครตัวใดตัวหนึ่งออกจากและยังพิมพ์ต้นฉบับต้นฉบับที่ได้รับการแก้ไข สิ่งนี้คือโดยส่วนใหญ่คุณสามารถลบอักขระหนึ่งตัวเท่านั้น มิฉะนั้นทุกอย่างจะพัง นี่คือสิ่งที่มานี้ เป้าหมายของคุณคือสร้างควินที่ผ่านการแผ่รังสีซึ่งสามารถกำจัดตัวละครได้มากที่สุด ภาษาใด ๆ ที่เป็นไปตามกฎนั้นใช้ได้

กฎระเบียบ

  • โปรแกรมต้องมีความยาวอย่างน้อยหนึ่งตัว
  • ภาษาที่ใช้จะต้องทำให้สมบูรณ์ (ภาษาเช่น HQ9 + ไม่ผ่านการรับรอง)
  • กฎอื่น ๆ ทั้งหมดที่ใช้กับ quines ปกติก็ใช้ที่นี่
  • โซลูชันprogram_length^(2/n)ที่มีชุดnอักขระน้อยที่สุดสามารถถูกลบออกได้ในขณะที่ยังคงพิมพ์รหัสต้นฉบับดั้งเดิมให้ชนะ

1
ฉันพยายามหาวิธีแก้ปัญหาSubleqมา ฉันคิดว่ามันจะเหมาะสำหรับความท้าทายแบบนี้!


อาจเปลี่ยนชื่อเนื่องจากนี่ไม่ใช่สิ่งเดียวกับควินเคี่ยวที่แผ่รังสี? อาจจะเป็น " ควินหลักฐานรังสี"?
Cyoce

@Cyoce ความแตกต่างเพียงอย่างเดียวที่ฉันสามารถบอกได้คือความท้าทายนี้มีไว้สำหรับการลบจำนวนใด ๆ ในขณะที่ส่วนใหญ่ (ถ้าไม่ทั้งหมด) quines รังสีแข็งอื่น ๆ อนุญาตเพียงหนึ่ง
takra

โซลูชันทับทิมจาก "mame" ที่มีชื่อเสียง github.com/mame/radiation-hardened-quine
mbomb007

คำตอบ:


57

Perl, 1116 1124 ไบต์, n = 3, คะแนน = 1124 ^ (2/3) หรือประมาณ 108.1

อัปเดต : ตอนนี้ฉันตรวจสอบแล้วว่าสิ่งนี้ใช้ได้กับ n = 3 โดยใช้กำลังดุร้าย (ซึ่งใช้เวลาสองสามวัน); ด้วยโปรแกรมที่ซับซ้อนนี้มันยากที่จะตรวจสอบความต้านทานการแผ่รังสีด้วยมือ (และฉันทำพลาดหนึ่งครั้งในเวอร์ชันก่อนหน้าซึ่งเป็นสาเหตุที่จำนวนไบต์เพิ่มขึ้น) จบการอัพเดท

ฉันขอแนะนำให้เปลี่ยนเส้นทาง stderr บางแห่งที่คุณจะไม่เห็น โปรแกรมนี้สร้างคำเตือนมากมายเกี่ยวกับไวยากรณ์ที่น่าสงสัยแม้ว่าคุณจะไม่ได้ลบอักขระออกไปก็ตาม

เป็นไปได้ว่าโปรแกรมสามารถย่อให้สั้นลงได้ การทำงานในลักษณะนี้ค่อนข้างเจ็บปวดทำให้ง่ายต่อการพลาดในการเพิ่มประสิทธิภาพของไมโคร ฉันส่วนใหญ่มีเป้าหมายเพื่อให้ได้จำนวนตัวอักษรที่สามารถลบได้สูงที่สุดเท่าที่จะเป็นไปได้ (เพราะนั่นเป็นส่วนที่ท้าทายอย่างยิ่งของโปรแกรม) และปฏิบัติต่อtie tiebreak เป็นสิ่งที่ดีที่จะตั้งเป้าหมายไว้ ความพยายามที่ไร้สาระในการเพิ่มประสิทธิภาพ (บนพื้นฐานที่ว่ามันง่ายมากที่จะทำลายความต้านทานรังสีโดยไม่ได้ตั้งใจ)

โปรแกรม

หมายเหตุ: มีการควบคุมตัวอักษร_ตัวอักษร (ASCII 31) -+ทันทีก่อนที่แต่ละแห่งที่สี่การเกิดขึ้นของ ฉันไม่คิดว่ามันจะคัดลอกและวางลงใน StackOverflow อย่างถูกต้องดังนั้นคุณจะต้องเพิ่มอีกครั้งก่อนที่จะเรียกใช้โปรแกรม

eval+<eval+<eval+<eval+(q(FoPqOlengthFoBBPP181XXVVVVJJJKKKNdoWchopJFtPDevalMODx4KNFrPIPA-MN-TUV-ZPINFsPIFoPqOI.Fo.IQNevalFoINevalIFsPZyI.Fr.IT-UPINsayDFtJqJFsKPZyPT-UFWrYrKD.DEEEEQDx6NsayDNDforB1..4YforB1..4NexitQNevalFo)=~y=A-Z=-+;-AZz-~=r)####>####>####>####>####>####>
;
;
;
;
eval+<eval+<eval+<eval+(q(FoPqOlengthFoBBPP181XXVVVVJJJKKKNdoWchopJFtPDevalMODx4KNFrPIPA-MN-TUV-ZPINFsPIFoPqOI.Fo.IQNevalFoINevalIFsPZyI.Fr.IT-UPINsayDFtJqJFsKPZyPT-UFWrYrKD.DEEEEQDx6NsayDNDforB1..4YforB1..4NexitQNevalFo)=~y=A-Z=-+;-AZz-~=r)####>####>####>####>####>####>
;
;
;
;
eval+<eval+<eval+<eval+(q(FoPqOlengthFoBBPP181XXVVVVJJJKKKNdoWchopJFtPDevalMODx4KNFrPIPA-MN-TUV-ZPINFsPIFoPqOI.Fo.IQNevalFoINevalIFsPZyI.Fr.IT-UPINsayDFtJqJFsKPZyPT-UFWrYrKD.DEEEEQDx6NsayDNDforB1..4YforB1..4NexitQNevalFo)=~y=A-Z=-+;-AZz-~=r)####>####>####>####>####>####>
;
;
;
;
eval+<eval+<eval+<eval+(q(FoPqOlengthFoBBPP181XXVVVVJJJKKKNdoWchopJFtPDevalMODx4KNFrPIPA-MN-TUV-ZPINFsPIFoPqOI.Fo.IQNevalFoINevalIFsPZyI.Fr.IT-UPINsayDFtJqJFsKPZyPT-UFWrYrKD.DEEEEQDx6NsayDNDforB1..4YforB1..4NexitQNevalFo)=~y=A-Z=-+;-AZz-~=r)####>####>####>####>####>####>
;
;
;
;

คำอธิบาย

โปรแกรมนี้ค่อนข้างชัดเจนทำจากโปรแกรมขนาดเล็กที่เหมือนกันสี่รายการที่ต่อกันเข้าด้วยกัน แนวคิดพื้นฐานคือแต่ละสำเนาของโปรแกรมจะตรวจสอบว่ามีความเสียหายมากเกินไปที่จะเรียกใช้หรือไม่ ถ้าเป็นเช่นนั้นมันจะไม่ทำอะไรเลย (นอกเหนือจากการเตือนคาย) และปล่อยให้การคัดลอกครั้งต่อไปทำงานได้ หากยังไม่ได้รับ (เช่นไม่มีการลบหรือตัวละครที่ถูกลบเป็นสิ่งที่สร้างความแตกต่างให้กับการทำงานของโปรแกรม) มันจะทำสิ่งที่น่าสงสัย (พิมพ์รหัสต้นฉบับของโปรแกรมเต็มนี่คือ quine ที่เหมาะสม ด้วยแต่ละส่วนที่มีการเข้ารหัสของรหัสที่มาทั้งหมด) แล้วออก (ป้องกันไม่ให้สำเนาที่ไม่เสียหายอื่น ๆ จากการพิมพ์รหัสต้นฉบับออกมาอีกครั้งและทำให้การทำลายควินินโดยการพิมพ์ข้อความมากเกินไป)

แต่ละส่วนทำจากสองส่วนซึ่งเป็นอิสระต่อการใช้งานอย่างมีประสิทธิภาพ wrapper ภายนอกและรหัสภายในบางอย่าง ด้วยเหตุนี้เราสามารถพิจารณาแยกต่างหาก

เสื้อคลุมด้านนอก

โดยทั่วไปแล้ว wrapper ด้านนอกeval<+eval<+eval< ... >####>####...>###(รวมอัฒภาคและบรรทัดใหม่ที่มีจุดประสงค์ที่ชัดเจนควรให้แน่ใจว่าส่วนของโปรแกรมจะแยกออกจากกันไม่ว่าเซมิโคลอนบางอันหรือบรรทัดใหม่ก่อนหน้าจะถูกลบทิ้ง ) นี่อาจดูเรียบง่ายพอสมควร แต่ก็มีหลายวิธีและเหตุผลที่ฉันเลือก Perl สำหรับความท้าทายนี้

อันดับแรกให้ดูที่วิธีการทำงานของ wrapper ในสำเนาของโปรแกรมที่ไม่เสียหาย evalแยกวิเคราะห์เป็นฟังก์ชั่นในตัวซึ่งใช้เวลาหนึ่งอาร์กิวเมนต์ เนื่องจากข้อโต้แย้งคาดว่า+นี่คือ unary +(ซึ่งจะคุ้นเคยกับนักกอล์ฟ Perl โดยขณะนี้พวกเขามามีประโยชน์บ่อยครั้งอย่างแปลกใจ) เรายังคงคาดหวังข้อโต้แย้ง (เราเพิ่งเห็นโอเปอเรเตอร์ unary) ดังนั้นสิ่ง<ที่ตามมาจะถูกตีความว่าเป็นจุดเริ่มต้นของ<>โอเปอเรเตอร์ (ซึ่งไม่มีคำนำหน้าหรืออาร์กิวเมนต์ของคำนำหน้าหลังและสามารถใช้ในตำแหน่งตัวถูกดำเนินการ)

<>เป็นผู้ประกอบการที่ค่อนข้างแปลก วัตถุประสงค์ปกติของมันคือการอ่าน filehandles และคุณวางชื่อ filehandle ไว้ในวงเล็บเหลี่ยม อีกทางเลือกหนึ่งถ้านิพจน์ไม่ถูกต้องเป็นชื่อ filehandle มันจะทำให้เกิดความกลมกลืน (โดยทั่วไปกระบวนการเดียวกับที่เชลล์ UNIX ใช้ในการแปลข้อความที่ผู้ใช้ป้อนไปยังลำดับของอาร์กิวเมนต์บรรทัดคำสั่ง; Perl รุ่นเก่าที่ใช้จริงมาก เชลล์สำหรับสิ่งนี้ แต่ทุกวันนี้ Perl จัดการกับสิ่งที่อยู่ภายใน) วัตถุประสงค์การใช้งานจึงเป็นตามสายของซึ่งโดยทั่วไปแล้วจะกลับรายการเช่น<*.c> ("foo.c", "bar.c")ในบริบทเซนต์คิตส์และเนวิส (เช่นอาร์กิวเมนต์ไปeval) เพียงแค่ส่งคืนรายการแรกที่พบในครั้งแรกที่เรียกใช้ (เทียบเท่ากับอาร์กิวเมนต์แรก) และจะส่งคืนรายการอื่น ๆ ในการรันในอนาคตตามสมมติฐานที่ไม่เคยเกิดขึ้น

ตอนนี้เชลล์มักจัดการกับอาร์กิวเมนต์บรรทัดคำสั่ง ถ้าคุณให้อะไรที่-rไม่มีข้อโต้แย้งมันก็จะถูกส่งไปยังคำต่อคำของโปรแกรมโดยไม่คำนึงว่ามีชื่อไฟล์นั้นหรือไม่ Perl ทำหน้าที่ในลักษณะเดียวกันตราบใดที่เรามั่นใจว่าไม่มีตัวอักษรที่พิเศษสำหรับเชลล์หรือ Perl ระหว่าง<และการจับคู่>เราสามารถใช้มันได้อย่างมีประสิทธิภาพเช่นสตริงตัวอักษรที่น่าอึดอัดใจจริงๆ ยิ่งไปกว่านั้น parser ของ Perl สำหรับตัวดำเนินการที่มีเครื่องหมายคำพูดมีแนวโน้มที่จะบังคับให้จับคู่วงเล็บในบริบทเช่นนี้ซึ่งมันไม่มีเหตุผลดังนั้นเราจึงสามารถซ้อน<>อย่างปลอดภัย (ซึ่งเป็นการค้นพบที่จำเป็นสำหรับโปรแกรมนี้เพื่อให้เป็นไปได้) ข้อเสียที่สำคัญของซ้อนกันทั้งหมดเหล่านี้<>คือการหลบหนีเนื้อหาของ<>เป็นไปไม่ได้เกือบ ดูเหมือนว่าจะมีสองเลเยอร์ของการหลบหลีกกับแต่ละ<>ดังนั้นเพื่อหนีบางสิ่งบางอย่างที่อยู่ภายในทั้งสามมันจะต้องนำหน้าด้วยแบ็กสแลช 63 ฉันตัดสินใจว่าแม้ว่าขนาดรหัสเป็นเพียงข้อพิจารณาที่สองในปัญหานี้ แต่ก็แทบจะไม่คุ้มที่จะจ่ายค่าปรับนี้กับคะแนนของฉันดังนั้นฉันจึงตัดสินใจเขียนโปรแกรมส่วนที่เหลือโดยไม่ใช้อักขระที่ละเมิด

แล้วจะเกิดอะไรขึ้นถ้าส่วนต่าง ๆ ของเสื้อคลุมถูกลบ?

  • การลบคำว่าevalทำให้มันกลายเป็นbarewordสตริงที่ไม่มีความหมาย Perl ไม่ชอบสิ่งเหล่านี้ แต่มันปฏิบัติต่อพวกเขาราวกับว่าพวกเขาถูกล้อมรอบด้วยคำพูด; จึงeal<+eval<+...ถูกตีความว่าเป็น"eal" < +eval<+.... สิ่งนี้ไม่มีผลกระทบต่อการทำงานของโปรแกรมเพราะโดยทั่วไปแล้วจะได้ผลลัพธ์จาก evals ที่ซ้อนกันอย่างมาก (ซึ่งเราไม่ได้ใช้อยู่แล้ว) ส่งไปที่จำนวนเต็มและทำการเปรียบเทียบแบบไม่มีจุดหมาย (สิ่งนี้ทำให้เกิดการเตือนสแปมจำนวนมากเนื่องจากไม่ใช่สิ่งที่มีประโยชน์ที่จะทำภายใต้สถานการณ์ปกติเราแค่ใช้เพื่อดูดซับการลบ) การเปลี่ยนแปลงจำนวนวงเล็บเหลี่ยมมุมที่เราต้องการ (เพราะวงเล็บเปิด ขณะนี้กำลังถูกตีความว่าเป็นตัวดำเนินการเปรียบเทียบแทน) แต่ห่วงโซ่ความคิดเห็นในตอนท้ายทำให้มั่นใจได้ว่าสตริงจะสิ้นสุดอย่างปลอดภัยไม่ว่าจะซ้อนกันกี่ครั้งก็ตาม (มี#สัญญาณมากกว่าที่จำเป็นอย่างยิ่งที่นี่ฉันเขียนมันเหมือนที่ฉันทำเพื่อให้โปรแกรมบีบอัดได้มากขึ้นทำให้ฉันใช้ข้อมูลน้อยลงเพื่อเก็บควินิน)
  • หากได้รับการลบรหัสตอนนี้จะแยกวิเคราะห์เป็น< eval(eval<...>)รองนอกevalไม่มีผลกระทบเนื่องจากโปรแกรมที่เราประเมินไม่ส่งคืนสิ่งใดที่มีผลกระทบที่แท้จริงในฐานะโปรแกรม (ถ้าพวกเขากลับมาตามปกติเลยปกติแล้วมันจะเป็นสตริง null หรือ bareword โดยทั่วไปแล้วพวกเขากลับผ่าน ข้อยกเว้นซึ่งทำให้evalคืนสตริงว่างหรือใช้exitเพื่อหลีกเลี่ยงการส่งคืน)
  • หาก+ได้รับการลบนี่จะไม่มีผลทันทีหากรหัสที่อยู่ติดกันไม่เป็นอันตราย เอก+จะไม่มีผลกับโปรแกรม (เหตุผลที่ต้นฉบับ+มีไว้เพื่อช่วยซ่อมแซมความเสียหายพวกเขาเพิ่มจำนวนสถานการณ์ที่<ตีความว่าเป็นเอกภาพ<>แทนที่จะเป็นผู้ดำเนินการเชิงสัมพันธ์หมายความว่าคุณต้องการการลบมากกว่าเพื่อสร้างโปรแกรมที่ไม่ถูกต้อง)

เสื้อคลุมอาจเสียหายได้ด้วยการลบที่เพียงพอ แต่คุณจำเป็นต้องทำชุดการลบเพื่อสร้างสิ่งที่ไม่แยกวิเคราะห์ ด้วยการลบสี่รายการคุณสามารถทำสิ่งนี้:

eal<evl<eval+<...

และใน Perl ตัวดำเนินการเชิงสัมพันธ์<นั้นไม่เกี่ยวข้องและทำให้คุณได้รับข้อผิดพลาดทางไวยากรณ์ (อันเดียวกับที่คุณจะได้รับ1<2<3) ดังนั้น cap สำหรับโปรแกรมตามที่เขียนคือ n = 3 การเพิ่ม unary มากขึ้น+ดูเหมือนเป็นวิธีที่มีแนวโน้มในการเพิ่ม แต่ก็ทำให้มีโอกาสมากขึ้นที่ด้านในของ wrapper อาจแตกได้เช่นกันการตรวจสอบว่าโปรแกรมเวอร์ชันใหม่ทำงานได้ยากมาก

เหตุผลที่ wrapper มีค่ามากคือevalใน Perl จับข้อยกเว้นเช่น (ตัวอย่าง) ข้อยกเว้นที่คุณได้รับเมื่อคุณพยายามรวบรวมข้อผิดพลาดทางไวยากรณ์ เนื่องจากสิ่งนี้evalเป็นของตัวอักษรสตริงการรวบรวมของสตริงเกิดขึ้นที่รันไทม์และหากตัวอักษรไม่สามารถรวบรวมข้อยกเว้นที่เกิดขึ้นได้รับการติด นี่เป็นสาเหตุevalให้ส่งคืนสตริง null และตั้งค่าตัวบ่งชี้ข้อผิดพลาด$@แต่เราไม่เคยตรวจสอบอย่างใดอย่างหนึ่ง (ยกเว้นบางครั้งเรียกใช้งานสตริง null ที่ส่งคืนในโปรแกรมกลายพันธุ์บางรุ่น) ซึ่งหมายความว่าหากสิ่งที่ควรเกิดขึ้นกับรหัสภายในwrapper ทำให้เกิดข้อผิดพลาดทางไวยากรณ์จากนั้น wrapper จะทำให้โค้ดไม่ทำอะไรแทน (และโปรแกรมจะดำเนินการต่อไปเพื่อพยายามค้นหาสำเนาที่ไม่เสียหายของตัวเอง) ดังนั้นรหัสด้านในไม่จำเป็นต้องมีความต้านทานการแผ่รังสีเหมือนกับแผ่นห่อ สิ่งที่เราใส่ใจคือถ้าเกิดความเสียหายมันอาจจะทำหน้าที่เหมือนกับรุ่นที่ไม่เสียหายของโปรแกรมหรือมิฉะนั้นมันก็จะพัง (อนุญาตให้evalจับยกเว้นและดำเนินการต่อ) หรือออกตามปกติโดยไม่ต้องพิมพ์อะไร

ด้านในเสื้อคลุม

รหัสภายใน wrapper โดยพื้นฐานแล้วจะมีลักษณะเช่นนี้ (อีกครั้งมีการควบคุม - _ที่ Exchange Exchange จะไม่แสดงทันทีก่อน-+):

eval+(q(...)=~y=A-Z=-+;-AZz-~=r)

รหัสนี้เขียนด้วยตัวอักษรแบบกลมปลอดภัยและมีจุดประสงค์เพื่อเพิ่มตัวอักษรใหม่ของเครื่องหมายวรรคตอนที่ทำให้สามารถเขียนโปรแกรมจริงผ่านการถอดเสียงและประเมินสตริงตัวอักษร (เราไม่สามารถใช้'หรือ"เป็นคำพูดของเรา เครื่องหมาย แต่q(... )ยังเป็นวิธีที่ถูกต้องในการสร้างสตริงใน Perl) (เหตุผลสำหรับตัวละครที่ไม่สามารถพิมพ์ได้คือเราต้องถอดทอนบางสิ่งบางอย่างลงในช่องว่างโดยไม่ต้องใช้ตัวอักษรช่องว่างในโปรแกรมดังนั้นเราจึงสร้างช่วงที่เริ่มต้นที่ ASCII 31 และจับพื้นที่เป็นองค์ประกอบที่สองของช่วง) เห็นได้ชัดว่าถ้าเราผลิตตัวละครบางตัวผ่านการทับศัพท์เราต้องเสียสละตัวละครเพื่อถอดเสียงจากแต่ตัวอักษรตัวพิมพ์ใหญ่ไม่ได้มีประโยชน์มากและง่ายต่อการเขียนโดยไม่ต้องเข้าถึงตัวอักษรเหล่านั้นมากกว่าการเข้าถึงเครื่องหมายวรรคตอน

นี่คือตัวอักษรของเครื่องหมายวรรคตอนที่สามารถใช้งานได้เนื่องจาก glob (บรรทัดบนแสดงการเข้ารหัสบรรทัดล่างของอักขระที่เข้ารหัส):

BCDEFGHIJKLMNOPQRSTUVWXYZ
 ! "# $% & '() + *? <=> @ Azz {|} ~ 

ที่โดดเด่นที่สุดคือเรามีเครื่องหมายวรรคตอนมากมายที่ไม่ปลอดภัย แต่มีประโยชน์ในการเขียนโปรแกรม Perl พร้อมกับอักขระเว้นวรรค ฉันยังบันทึกตัวอักษรตัวพิมพ์ใหญ่สองตัวตัวอักษรAและZ(ซึ่งเข้ารหัสไม่ให้ตัวเอง แต่ถึงTและUเพราะAจำเป็นสำหรับทั้งบนและล่างช่วงปลายทาง); สิ่งนี้ช่วยให้เราสามารถเขียนคำสั่งการถอดเสียงได้เองโดยใช้ชุดอักขระที่เข้ารหัสใหม่ (แม้ว่าตัวอักษรตัวพิมพ์ใหญ่จะไม่เป็นประโยชน์ แต่ก็มีประโยชน์ในการระบุการเปลี่ยนแปลงตัวอักษรตัวพิมพ์ใหญ่) ตัวละครที่โดดเด่นที่สุดที่เราไม่สามารถหาได้คือ[, \และ], แต่ไม่มีสิ่งจำเป็น (เมื่อฉันต้องการขึ้นบรรทัดใหม่ในผลลัพธ์, ฉันสร้างมันขึ้นมาโดยใช้บรรทัดใหม่โดยนัยจากsayมากกว่าที่จะต้องเขียน\n; chr 10ก็จะได้ผลเช่นกัน

ตามปกติเราจำเป็นต้องกังวลเกี่ยวกับสิ่งที่เกิดขึ้นหากภายในของเสื้อคลุมได้รับความเสียหายนอกตัวอักษรสตริง ความเสียหายevalจะป้องกันไม่ให้สิ่งใดทำงาน เราไม่เป็นไร หากเครื่องหมายคำพูดได้รับความเสียหายภายในของสตริงจะไม่ถูกต้อง Perl และดังนั้นเสื้อคลุมจะจับมัน (และการลบจำนวนมากบนสตริงหมายความว่าแม้ว่าคุณสามารถทำให้มันถูกต้อง Perl ก็จะไม่ทำอะไรซึ่ง เป็นผลลัพธ์ที่ยอมรับได้) ความเสียหายให้กับการทับศัพท์ถ้ามันไม่ได้เป็นข้อผิดพลาดทางไวยากรณ์จะฉีกสตริงถูกประเมินมักจะก่อให้เกิดมันจะกลายเป็นข้อผิดพลาดทางไวยากรณ์; ฉันไม่แน่ใจ 100% ว่าไม่มีกรณีที่การหยุดพักนี้ แต่ฉันกำลังบังคับให้ทำอย่างนั้นในขณะนี้เพื่อให้แน่ใจและควรง่ายพอที่จะแก้ไขหากมี

โปรแกรมที่เข้ารหัส

เมื่อมองเข้าไปในสตริงตัวอักษรการย้อนกลับของการเข้ารหัสที่ฉันใช้และเพิ่มช่องว่างเพื่อให้อ่านได้ง่ายขึ้นเราจะได้รับสิ่งนี้ (อีกครั้งให้จินตนาการถึงขีดล่างควบคุมก่อนหน้า-+ซึ่งเข้ารหัสเป็นA)

$o=q<
  length$o  ==181 || zzzz((()));
  do {
    chop ($t = "eval+<"x4);
    $r = '=-+;-AZz-~=';
    $s = '$o=q<' . $o . '>;eval$o';
    eval '$s=~y' . $r . 'A-Z=';
    say "$t(q($s)=~y=A-Z${r}r)" . "####>"x6;
    say ";" for 1..4
  } for 1..4;
  exit>;
eval $o

ผู้ที่เคยใช้ในการทดสอบจะรับรู้โครงสร้างทั่วไปนี้ ส่วนที่สำคัญที่สุดคือการเริ่มต้นที่เราตรวจสอบว่า $ o ไม่เสียหาย ถ้าตัวละครที่ได้รับการลบความยาวของมันจะไม่ตรงกับ181ดังนั้นเราจึงทำงานzzzz((()))ซึ่งถ้ามันไม่ได้เป็นข้อผิดพลาดทางไวยากรณ์เนื่องจากวงเล็บตรงกันจะเป็นข้อผิดพลาด runtime แม้ว่าคุณจะลบใด ๆ ที่ตัวละครทั้งสามเพราะไม่มีzzzz, zzz, zz, และzเป็นฟังก์ชั่นและไม่มีวิธีที่จะป้องกันไม่ให้มันแยกเป็นฟังก์ชั่นอื่นนอกเหนือจากการลบ(((และทำให้เกิดข้อผิดพลาดทางไวยากรณ์ที่น่ารังเกียจ การตรวจสอบตัวเองยังมีความเสียหาย ||ได้รับความเสียหายไป|แต่ที่จะทำให้เกิดการzzzz((()))เรียกร้องให้ทำงานโดยไม่มีเงื่อนไข ตัวแปรหรือค่าคงที่จะทำให้เกิดความเสียหายที่ไม่ตรงกันเพราะคุณกำลังเปรียบเทียบหนึ่ง0,180, 179, 178เพื่อความเท่าเทียมกันในการเซตบางส่วนของตัวเลขของ181; และการลบออก=จะทำให้เกิดความล้มเหลวในการแยกวิเคราะห์และอีกสองรายการที่=จะทำให้ LHS ต้องประเมินค่าเป็นจำนวนเต็ม 0 หรือสตริง null ซึ่งทั้งคู่เป็นเท็จ

อัปเดต : การตรวจสอบนี้ผิดเล็กน้อยในโปรแกรมรุ่นก่อนหน้าดังนั้นฉันต้องแก้ไขเพื่อแก้ไขปัญหา รุ่นก่อนหน้ามีลักษณะเช่นนี้หลังจากถอดรหัส:

length$o==179||zzzz((()))

และเป็นไปได้ที่จะลบเครื่องหมายวรรคตอนสามตัวแรกเพื่อให้ได้สิ่งนี้:

lengtho179||zzz((()))

lengtho179เป็น bareword เป็นความจริงและทำให้แบ่งการตรวจสอบ ฉันแก้ไขสิ่งนี้โดยการเพิ่มBอักขระพิเศษสองตัว (ซึ่งเข้ารหัสอักขระช่องว่าง) ซึ่งหมายถึงควินินเวอร์ชันล่าสุดทำสิ่งนี้

length$o  ==181||zzzz((()))

ตอนนี้มันเป็นไปไม่ได้ที่จะซ่อนทั้ง=เครื่องหมายและ$สัญญาณโดยไม่สร้างข้อผิดพลาดทางไวยากรณ์ (ฉันต้องเพิ่มช่องว่างสองช่องแทนที่จะเป็นช่องว่างหนึ่งอันเนื่องจากความยาวของ180จะใส่0อักขระตามตัวอักษรลงในแหล่งที่มาซึ่งอาจถูกใช้ในบริบทนี้เป็นศูนย์เปรียบเทียบจำนวนเต็มกับ bareword ซึ่งประสบความสำเร็จ) อัปเดตสุดท้าย

เมื่อการตรวจสอบความยาวผ่านไปแล้วเรารู้ว่าสำเนานั้นไม่เสียหายอย่างน้อยก็ในแง่ของการลบตัวอักษรออกไปดังนั้นมันจึงเป็นเพียงแค่การคว้านออกมาจากตรงนั้น (การแทนที่เครื่องหมายวรรคตอนเนื่องจากตารางถอดรหัสที่เสียหายจะไม่ถูกตรวจจับ แต่ฉันได้ตรวจสอบแล้วผ่านการเดรัจฉานบังคับว่าไม่มีการลบสามจากเฉพาะตารางถอดรหัสแบ่งควินนั้นน่าจะส่วนใหญ่ทำให้เกิดข้อผิดพลาดทางไวยากรณ์) เรามี$oตัวแปรอยู่แล้วดังนั้นสิ่งที่เราต้องทำก็คือ hardcode ตัวห่อหุ้มภายนอก (ด้วยการบีบอัดเล็กน้อยบางอันฉันไม่ได้ข้ามส่วนของของคำถามทั้งหมด ) เคล็ดลับอย่างหนึ่งคือเราจัดเก็บตารางการเข้ารหัสไว้จำนวนมาก$r; เราสามารถพิมพ์มันอย่างแท้จริงเพื่อสร้างส่วนตารางการเข้ารหัสของ wrapper ภายในหรือเชื่อมต่อโค้ดบางส่วนรอบ ๆ มันและevalเพื่อรันกระบวนการถอดรหัสในสิ่งที่ตรงกันข้าม (ช่วยให้เราทราบว่ารุ่นที่เข้ารหัสของ $ o คืออะไร มีเฉพาะรุ่นถอดรหัสที่มีอยู่ในตอนนี้)

ในที่สุดหากเราเป็นสำเนาที่สมบูรณ์และสามารถส่งออกโปรแกรมต้นฉบับทั้งหมดได้เราจะโทรติดต่อexitเพื่อป้องกันไม่ให้สำเนาอื่นพยายามพิมพ์โปรแกรมออกมา

สคริปต์ยืนยัน

ไม่สวยมาก แต่โพสต์เพราะมีคนถาม ฉันวิ่งไปหลายครั้งด้วยการตั้งค่าที่หลากหลาย (โดยทั่วไปจะเปลี่ยน$minและ$maxตรวจสอบพื้นที่ที่น่าสนใจ); มันไม่ใช่กระบวนการอัตโนมัติอย่างสมบูรณ์ มันมีแนวโน้มที่จะหยุดทำงานเนื่องจากภาระของ CPU ที่หนักอื่น; เมื่อสิ่งนี้เกิดขึ้นฉันเพิ่งเปลี่ยน$minเป็นค่าแรกของ$xที่ไม่ได้รับการตรวจสอบอย่างสมบูรณ์และรันสคริปต์ต่อไป ฉันตรวจสอบการลบจากสำเนาแรกของโปรแกรมเท่านั้นเนื่องจากเห็นได้ชัดว่าการลบจากสำเนาอื่นไม่สามารถทำได้มากกว่า

use 5.010;
use IPC::Run qw/run/;
undef $/;
my $program = <>;
my $min = 1;
my $max = (length $program) / 4 - 3;
for my $x ($min .. $max) {
    for my $y ($x .. $max) {
        for my $z ($y .. $max) {
            print "$x, $y, $z\n";
            my $p = $program;
            substr $p, $x, 1, "";
            substr $p, $y, 1, "";
            substr $p, $z, 1, "";
            alarm 4;
            run [$^X, '-M5.010'], '<', \$p, '>', \my $out, '2>', \my $err;
            if ($out ne $program) {
                print "Failed deleting at $x, $y, $z\n";
                print "Output: {{{\n$out}}}\n";
                exit;
            }
        }
    }
}

say "All OK!";

3
OP ค่อนข้างคลุมเครือเล็กน้อย แต่ฉันคิดว่าคะแนนจะเป็น (1116 * 1116) / 3
Greg Martin

@GregMartin: (1116 * 1116) / 3 คือ 415152 ดังนั้นรายการนี้จะยังคงชนะภายใต้สถานการณ์เหล่านั้น อย่างไรก็ตามฉันไม่คิดว่า OP อาจหมายถึงเพราะมันให้แรงจูงใจน้อยมากที่จะสามารถกำจัดตัวละครหลายตัวได้ ควินินนี้อาจมีความยาวน้อยกว่าครึ่งถ้าคุณต้องการใช้เพื่อจัดการกับการลบหนึ่งอักขระเท่านั้น นั่นจะทำให้ฉันมีประสิทธิภาพ÷ 4 กับคะแนนถ้าเราตีความเช่นนั้นซึ่งจะมีค่าเกิน÷ 3 ที่ฉันได้รับจาก n = 3 และนั่นหมายความว่ารายการ n = 1 ที่น่าสนใจน้อยกว่านั้นคือการให้คะแนนที่ดีกว่า

2
ฉันทำให้คะแนนชัดเจนยิ่งขึ้น อย่างไรก็ตามนี่เป็นเรื่องเหลือเชื่ออย่างยิ่ง ไม่คิดว่าจะมีใครได้รับ n> 1
takra

1
มันบอกอะไรบางอย่างเกี่ยวกับ Perl ที่ง่ายต่อการเขียนโปรแกรมโดยไม่มีตัวอักษรมากกว่าโดยไม่มีเครื่องหมายวรรคตอน
Robert Fraser

35

Befunge-98 , 884, n = 14, คะแนน≈ 2.636

f00f00f00f00f00f00f00f00f00f00f00f00f00f00f0xxxxxxxxxxxxxxx"""""""""""""""fffffffffffffff'''''''''''''''000000000000000\\\\\\\\\\\\\\\'''''''''''''''000000000000000\\\\\\\\\\\\\\\'''''''''''''''fffffffffffffff\\\\\\\\\\\\\\\111111111111111---------------:::::::::::::::!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!000000000000000aaaaaaaaaaaaaaa---------------bbbbbbbbbbbbbbb---------------***************jjjjjjjjjjjjjjj$$$$$$$$$$$$$$$'''''''''''''''+++++++++++++++kkkkkkkkkkkkkkk,,,,,,,,,,,,,,,333333333333333kkkkkkkkkkkkkkk$$$$$$$$$$$$$$$000000000000000{{{{{{{{{{{{{{{'''''''''''''''888888888888888uuuuuuuuuuuuuuu'''''''''''''''!!!!!!!!!!!!!!!111111111111111+++++++++++++++'''''''''''''''xxxxxxxxxxxxxxx###############;;;;;;;;;;;;;;;:::::::::::::::!!!!!!!!!!!!!!!kkkkkkkkkkkkkkk@@@@@@@@@@@@@@@dddddddddddddddkkkkkkkkkkkkkkk:::::::::::::::eeeeeeeeeeeeeeekkkkkkkkkkkkkkk,,,,,,,,,,,,,,,;;;;;;;;;;;;;;;

ลองออนไลน์!

สิ่งนี้ไม่เพียงทำงานได้เมื่อคุณลบตัวอักษร 14 ตัวเท่านั้น แต่ถึงแม้คุณจะลบจำนวนสูงสุด 14 ตัวอักษร

n = 14อาจดูเหมือนเป็นทางเลือกโดยพลการ แต่เทคนิคที่ฉันใช้สามารถจริง ๆ แล้วสามารถใช้สำหรับคำสั่งการชุบรังสีตั้งแต่ 1 ถึง 14 แต่ไม่ง่ายกว่านั้น (อาจเป็นไปได้ แต่ฉันไม่มีเงื่อนงำ) ลำดับควินหาลำดับที่ 1 มีขนาดเพียง 73 ไบต์ (แม้ว่าจะมีเทคนิคการตีลูกกอล์ฟที่ไม่ได้ใช้กับท่าใหญ่n):

200 20 xx""''ÈÈ..aa22**..33kk$$00{{''!!uu''!!11++''xx##;;::!!kk@@::,,,,;;

คำอธิบาย

เมื่อฉันทำงานกับคำตอบนี้ฉันพบว่าเป็นไปได้ที่จะตั้งค่าเดลต้าของตัวชี้คำแนะนำให้(2,0)อยู่ภายใต้เงื่อนไขการชุบแข็งด้วยตัวอย่างต่อไปนี้:

20020xx

ดูคำตอบว่าทำไมงานนี้ ฉันพบสิ่งนี้ด้วยการเล่นซอด้วยมือเล็กน้อย แต่สิ่งนี้ทำให้เกิดคำถามว่ามีรูปแบบที่คล้ายคลึงกันซึ่งแข็งแกร่งภายใต้การลบอักขระหลายตัวหรือไม่ ดังนั้นฉันจึงเขียนสคริปต์ Mathematica สั้น ๆ เพื่อค้นหาสิ่งเหล่านี้โดยใช้กำลังดุร้าย:

n = 14;
m = 4;
Print @ FromDigits @ {
      m + 1, 0, 
      ## & @@ ((m + 1) IntegerDigits[#, 2, n - 4]),
      m + 1, 0
} & /@ Select[
   Range[0, 2^(n - 4) - 1], 
   AllTrue[
     Subsets[{
         m + 1, 0, 
         ## & @@ ((m + 1) IntegerDigits[#, 2, n - 4]),
         m + 1, 0
       }, 
       {n - m, n - 1}
     ] //. {a___, _, m + 1} | {a___, 0, _} :> {a}, 
     MatchQ@{___, m + 1, 0}
  ] &
];

รูปแบบนี้เผยให้เห็นอย่างรวดเร็วมาก เพื่อให้ได้ตัวอย่างที่สอดคล้องกันซึ่งทำงานสำหรับการกำจัดของถึงnตัวละครที่คุณสามารถใช้(m0x){n}m0ที่mเป็นn+1และxเป็นอย่างใดอย่างหนึ่งหรือm 0ดังนั้นทั้งหมดต่อไปนี้จะสามารถลบอักขระได้สูงสุดสองตัว:

30030030
30030330
30330030
30330330

ฉันแน่ใจว่ามันเป็นไปได้ที่จะพิสูจน์เรื่องนี้ แต่ฉันได้รับการตรวจสอบเพียงเพื่อขึ้นไปn 7ของหลักสูตรนี้จะทำงานเฉพาะตราบใดที่เราสามารถเป็นตัวแทนn+1เป็นหลักเดียวและใหญ่ที่สุดในหลักดังกล่าวใน Befunge 98 fซึ่งหมายถึง 15 n = 14นั่นเป็นเหตุผลที่วิธีการของฉันจะถูก หากมีคนพบวิธีตั้งค่าเดลต้าให้ใหญ่ขึ้นอย่างน่าเชื่อถือn+1มันอาจเป็นไปได้ที่จะเพิ่มคำสั่งของควินที่ชุบด้วยรังสีนี้ไปเรื่อย ๆ

ลองดูรหัสจริง โดยทั่วไปมีสองส่วน ก่อนอื่นเราตั้งค่าเดลต้า(15,0)เป็นอย่างที่ฉันเพิ่งพูดถึง:

f00f00f00f00f00f00f00f00f00f00f00f00f00f00f0xxxxxxxxxxxxxxx

และส่วนที่เหลือของรหัสมีคำสั่งซ้ำกัน 15 ครั้งและพิมพ์ต้นฉบับ หากเราลบการทำซ้ำดูเหมือนว่า:

"f'0\'0\'f\1-:!!0a-b-*j$'+k,3k$0{'8u'!1+'x#;:!k@dk:ek,;

นี่"เป็นเทคนิคการคว้านแบบสองมิติมาตรฐาน: มันเริ่มโหมดสตริงผลักอักขระทั้งหมด (ยกเว้นตัวเอง) ลงบนสแต็กและจบโหมดสตริงอีกครั้งหลังจากล้อมรอบ สิ่งนี้ช่วยให้เราได้รับคะแนนรหัสทั้งหมดในครึ่งหลัง แต่จะไม่สามารถให้เรามีประโยชน์อะไรจากครึ่งแรกเพราะตลอดf00f00...f0บิตนั้นจะบันทึกเพียงอักขระสองตัวเท่านั้น (ซึ่งอาจเป็นได้fหรือ0ขึ้นอยู่กับตัวละครที่ถูกลบ ) แต่เนื่องจากส่วนนั้นไม่ได้ประกอบไปด้วยตัวละครซ้ำอีก 15 ครั้งเราจึงต้องพิมพ์แยกต่างหาก

สะดวกยิ่งขึ้นในควินแปรความยาวของสตริงก่อนที่จะเป็น" -1 (mod 15)สิ่งนี้รับประกันได้ว่าไม่ว่าเราจะลบตัวอักษรกี่ตัว (ไม่เกิน 14 ตัว) ว่าจำนวนตัวอักษรที่บันทึกไว้นั้นมี 3 (หนึ่งxและสองfและ0) นี่เป็นความจริงสำหรับทุกคำสั่งรังสีที่สูงถึง 14

ตอนนี้เราเริ่มต้นด้วยการพิมพ์f00f00...f0ส่วน:

f'0\'0\'f\1-:!!0a-b-*j$'+k,

f          Push 15, a loop counter.
'0\'0\'f\  Put "00f" underneath the loop counter.
1-         Decrement the loop counter.
:!!        Copy it, and turn it into a 1 if it's positive.
0a-b-      Push -21.
*          Multiply by 0 if the loop counter is zero, or by 1 otherwise.
j          Jump that many steps. If the value was 0, this is a no-op and
           the loop ends. Otherwise, this brings us back after the f.
$          Pop the loop counter (which is now 0).
'+k,       Print the top of the stack 43 times, which gives us all of
           the "f00f00...f0" and leaves one "0" on top of the stack.

ถัดไป3k$เพียงแค่ทิ้งว่า0ตัวละครทั้งสามที่ถูกผลักโดย"จากจุดเริ่มต้นของโปรแกรม สแต็กตอนนี้มีเพียงตัวอักษรที่อยู่หลัง"และขยะบางส่วนที่อยู่ด้านล่างของต้นฉบับf00f00...f0ขึ้นอยู่กับตัวละครที่ถูกลบ

ตอนนี้เราแค่ต้องย้อนกลับด้านบนของสแต็ก (มีอักขระที่เหลืออยู่) และพิมพ์หนึ่งในนั้น 15 ครั้ง

0{     Start a new, empty stack. This pushes two zeros onto the original stack.
'8u    Move the top 56 values from the original stack to the new one, which
       is the 54 characters after the " as well as those two zeros. This is
       implemented as pop-push loop, so it reverses the order of those elements.
'!1+   Push a " by incrementing a !.
'x     Push an x. Now we've got all the characters that are repeated 15 times.
#;     Enter a loop. This is a standard technique for Befunge-98: the ; is
       a bit like a comment character, that ignores everything until the next
       ;, but we jump over the first one with #, so that from now on only
       the code inside will be executed (over and over).
  :!     Copy the top of the stack, and compute logical NOT (1 if 0, 0 otherwise).
  k@     Terminate the program that many times (i.e. when the top of the
         stack is zero).
  dk:    Make 14 copies of the top of the stack.
  ek,    Print 15 characters from the top of the stack.
;

และนั่นคือมัน :)


16

JavaScript (ES6), 927 ไบต์, n = 1, คะแนน = 859329

หมายเหตุ: อย่าใช้ REPL (เช่นคอนโซลเบราว์เซอร์) เพื่อเรียกใช้สิ่งนี้

สิ่งนี้ถูกเขียนขึ้นก่อนที่ความยาวของรหัสจะเป็นปัจจัยดังนั้นจึงยังไม่ได้ตีกอล์ฟ

นี่เป็นเรื่องยากมากและสมควรได้รับคำอธิบายอย่างละเอียด ซึ่งฉันจะเขียนในภายหลังหลังจากที่ฉันสำรวจความท้าทายนี้อีกเล็กน้อย!

etTimeout=stTimeout=seTimeout=setimeout=setTmeout=setTieout=setTimout=setTimeut=setTimeot=setTimeou=unescape=>42;
setTimeout
`c="function f(){x=String.fromCharCode(96);n=String.fromCharCode(10);q=String.fromCharCode(34);y='etTimeout=stTimeout=seTimeout=setimeout=setTmeout=setTieout=setTimout=setTimeut=setTimeot=setTimeou=unescape=>42;'+n;z='setTimeout'+n+x+'c='+q+f+';f();_=1'+q+';if(window._);else if(c.length>339)eval(c)//'+x+'///'+x+n+n;console.log(y+z+z)};f();_=1";if(window._);else if(c.length>339)eval(c)//`///`

setTimeout
`c="function f(){x=String.fromCharCode(96);n=String.fromCharCode(10);q=String.fromCharCode(34);y='etTimeout=stTimeout=seTimeout=setimeout=setTmeout=setTieout=setTimout=setTimeut=setTimeot=setTimeou=unescape=>42;'+n;z='setTimeout'+n+x+'c='+q+f+';f();_=1'+q+';if(window._);else if(c.length>339)eval(c)//'+x+'///'+x+n+n;console.log(y+z+z)};f();_=1";if(window._);else if(c.length>339)eval(c)//`///`

หมายเหตุ: มีการขึ้นบรรทัดใหม่ที่ต่อท้าย

โดยพื้นฐานแล้วบรรทัดแรกจะถูกสร้างขึ้นอย่างระมัดระวังเพื่อเปลี่ยนชื่อ 'การสะกดผิด' ทั้งหมดของsetTimeoutฟังก์ชันที่ถูกต้องดังนั้นหากอักขระถูกลบออกจากsetTimeoutรหัสใดรหัสหนึ่งจะไม่มีข้อผิดพลาดและรุ่นที่ไม่มีอันตรายสามารถทำงานได้ มันถูกเขียนขึ้นเพื่อให้ถ้าตัวละครตัวใดตัวหนึ่งถูกลบออกจากบรรทัดแรกจะไม่มีข้อผิดพลาดและส่วนที่เหลือของรหัสสามารถทำงานได้รับผลกระทบ

บล็อกที่สองและสามนั้นเทียบเท่ากันทุกประการ หากหนึ่งรันจนเสร็จสมบูรณ์ก็จะตั้งค่า_ตัวแปรเพื่อให้คนอื่นรู้ว่าจะไม่ทำสำเนาควิน หากหนึ่งในข้อผิดพลาดเหล่าบล็อกออกมาก็ไม่ได้ส่งผลกระทบต่อบล็อกอื่น ๆ setTimeoutเพราะมันถูกเรียกว่าไม่พร้อมใช้ ข้อผิดพลาดจะทำให้_ไม่ถูกตั้งค่าดังนั้นบล็อกอื่นจะ quine สำเร็จ รหัสหลักอยู่ในสตริงซึ่งมีการตรวจสอบความยาวในแต่ละบล็อกเพื่อให้แน่ใจว่าไม่มีการลบออก

สตริงเทมเพลตในบรรทัดถัดไปที่มีความคิดเห็นบางส่วนที่ส่วนท้ายของสตริงเท็มเพลตปกป้องโค้ดจากการผิดพลาดหากหนึ่งใน backticks ที่สร้างสตริงเทมเพลตถูกลบออก ถ้า backtick ที่สิ้นสุดถูกลบออกสตริงของเท็มเพลตจะสิ้นสุดโดย backtick ในความคิดเห็น ถ้า backtick เริ่มต้นถูกลบ setTimeout จะถูกประเมินว่าเป็นฟังก์ชั่นที่ไม่ได้รับมอบหมาย (ไม่มีตัวเลือก) และรหัสจะทำงานตามปกติโดยไม่ต้อง setTimeout backtick ที่สิ้นสุดจะถูกยกเลิกโดยความคิดเห็นอื่น


คุณพูดว่าอะไร คุณต้องการที่จะลอง? อย่าพูดอีกเลย!

แนะนำโหมดเต็มหน้า

ละเว้นกล่องอินพุตข้อมูลโค้ดนี้จะไม่มีการป้อนข้อมูล

ลองลบตัวละครตัวใดตัวหนึ่งออกจากรหัส!

ไม่เชื่อเหรอ รหัสปกติจะยังใช้งานได้ (แต่จะไม่เป็นข้อผิดพลาด ... ) ลองทำเช่นนี้console.log(5)!

หมายเหตุ: ต้องมีการแก้ไขข้อมูลโค้ดเล็กน้อยเพื่อปิดใช้งานคุณสมบัติ REPL ดังนั้นฉันจึงลบความสามารถในการแสดงผลหลายคำตอบออกไปเท่านั้น

etTimeout=stTimeout=seTimeout=setimeout=setTmeout=setTieout=setTimout=setTimeut=setTimeot=setTimeou=unescape=>42;
setTimeout
`c="function f(){x=String.fromCharCode(96);n=String.fromCharCode(10);q=String.fromCharCode(34);y='etTimeout=stTimeout=seTimeout=setimeout=setTmeout=setTieout=setTimout=setTimeut=setTimeot=setTimeou=unescape=>42;'+n;z='setTimeout'+n+x+'c='+q+f+';f();_=1'+q+';if(window._);else if(c.length>339)eval(c)//'+x+'///'+x+n+n;console.log(y+z+z)};f();_=1";if(window._);else if(c.length>339)eval(c)//`///`

setTimeout
`c="function f(){x=String.fromCharCode(96);n=String.fromCharCode(10);q=String.fromCharCode(34);y='etTimeout=stTimeout=seTimeout=setimeout=setTmeout=setTieout=setTimout=setTimeut=setTimeot=setTimeou=unescape=>42;'+n;z='setTimeout'+n+x+'c='+q+f+';f();_=1'+q+';if(window._);else if(c.length>339)eval(c)//'+x+'///'+x+n+n;console.log(y+z+z)};f();_=1";if(window._);else if(c.length>339)eval(c)//`///`
<!--                               Try the test suite below!                              --><strong id="bytecount" style="display:inline; font-size:32px; font-family:Helvetica"></strong><strong id="bytediff" style="display:inline; margin-left:10px; font-size:32px; font-family:Helvetica; color:lightgray"></strong><br><br><pre style="margin:0">Code:</pre><textarea id="textbox" style="margin-top:5px; margin-bottom:5px"></textarea><br><pre style="margin:0">Input:</pre><textarea id="inputbox" style="margin-top:5px; margin-bottom:5px"></textarea><br><button id="testbtn">Test!</button><button id="resetbtn">Reset</button><br><p><strong id="origheader" style="font-family:Helvetica; display:none">Original Code Output:</strong><p><div id="origoutput" style="margin-left:15px"></div><p><strong id="newheader" style="font-family:Helvetica; display:none">New Code Output:</strong><p><div id="newoutput" style="margin-left:15px"></div><script type="text/javascript" id="golfsnippet">var bytecount=document.getElementById("bytecount");var bytediff=document.getElementById("bytediff");var textbox=document.getElementById("textbox");var inputbox=document.getElementById("inputbox");var testbtn=document.getElementById("testbtn");var resetbtn=document.getElementById("resetbtn");var origheader=document.getElementById("origheader");var newheader=document.getElementById("newheader");var origoutput=document.getElementById("origoutput");var newoutput=document.getElementById("newoutput");textbox.style.width=inputbox.style.width=window.innerWidth-50+"px";var _originalCode=null;function getOriginalCode(){if(_originalCode!=null)return _originalCode;var allScripts=document.getElementsByTagName("script");for(var i=0;i<allScripts.length;i++){var script=allScripts[i];if(script.id!="golfsnippet"){originalCode=script.textContent.trim();return originalCode}}}function getNewCode(){return textbox.value.trim()}function getInput(){try{var inputText=inputbox.value.trim();var input=eval("["+inputText+"]");return input}catch(e){return null}}function setTextbox(s){textbox.value=s;onTextboxChange()}function setOutput(output,s){output.innerHTML=s}function addOutput(output,data){output.innerHTML='<pre style="background-color:'+(data.type=="err"?"lightcoral":"lightgray")+'">'+escape(data.content)+"</pre>"}function getByteCount(s){return(new Blob([s],{encoding:"UTF-8",type:"text/plain;charset=UTF-8"})).size}function onTextboxChange(){var newLength=getByteCount(getNewCode());var oldLength=getByteCount(getOriginalCode());bytecount.innerHTML=newLength+" bytes";var diff=newLength-oldLength;if(diff>0){bytediff.innerHTML="(+"+diff+")";bytediff.style.color="lightcoral"}else if(diff<0){bytediff.innerHTML="("+diff+")";bytediff.style.color="lightgreen"}else{bytediff.innerHTML="("+diff+")";bytediff.style.color="lightgray"}}function onTestBtn(evt){origheader.style.display="inline";newheader.style.display="inline";setOutput(newoutput,"");setOutput(origoutput,"");var input=getInput();if(input===null){addOutput(origoutput,{type:"err",content:"Input is malformed. Using no input."});addOutput(newoutput,{type:"err",content:"Input is malformed. Using no input."});input=[]}doInterpret(getNewCode(),input,function(data){addOutput(newoutput,data)});doInterpret(getOriginalCode(),input,function(data){addOutput(origoutput,data)});evt.stopPropagation();return false}function onResetBtn(evt){setTextbox(getOriginalCode());origheader.style.display="none";newheader.style.display="none";setOutput(origoutput,"");setOutput(newoutput,"")}function escape(s){return s.toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}window.alert=function(){};window.prompt=function(){};function doInterpret(code,input,cb){var workerCode=interpret.toString()+";function stdout(s){ self.postMessage( {'type': 'out', 'content': s} ); }"+" function stderr(s){ self.postMessage( {'type': 'err', 'content': s} ); }"+" function kill(){ self.close(); }"+" self.addEventListener('message', function(msg){ interpret(msg.data.code, msg.data.input); });";var interpreter=new Worker(URL.createObjectURL(new Blob([workerCode])));interpreter.addEventListener("message",function(msg){cb(msg.data)});interpreter.postMessage({"code":code,"input":input});setTimeout(function(){interpreter.terminate()},1E4)}setTimeout(function(){getOriginalCode();textbox.addEventListener("input",onTextboxChange);testbtn.addEventListener("click",onTestBtn);resetbtn.addEventListener("click",onResetBtn);setTextbox(getOriginalCode())},100);function interpret(code,input){_=undefined;window={};alert=function(s){stdout(s)};window.alert=alert;console.log=alert;prompt=function(s){if(input.length<1)stderr("not enough input");else{var nextInput=input[0];input=input.slice(1);return nextInput.toString()}};window.prompt=prompt;(function(){try{_=undefined;eval(code);if(typeof evalResult=="disabled_function_evaluation"){var callResult=evalResult.apply(this,input);if(typeof callResult!="undefined")stdout(callResult)}}catch(e){stderr(e.message)}})()};</script>

คำอธิบายที่ดีกว่ากำลังจะมา ในขณะเดียวกันก็สามารถ ping ฉันในการแชท @jrich ด้วยความเห็น / คำถาม / การวิจารณ์!


อ่าโอเคอ๊ะ: |
Downgoat

4
ใช้แทนthis window
Mama Fun Roll

3
+1 สำหรับการรวมความหมายของชีวิตในซอร์สโค้ดของคุณ
Cyoce
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.