ข้อผิดพลาด (หรือคำเตือน) ควินที่เป็นควินปกติ [ปิด]


9

(ได้รับแรงบันดาลใจจากความคิดเห็นนี้กับคำถามเก่า ๆ )

พื้นหลัง

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

งาน

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

ชี้แจง

  • ในกรณีส่วนใหญ่จะเห็นได้ชัดว่าอะไรคืออะไรและไม่ใช่ข้อความแสดงข้อผิดพลาด / คำเตือน เราไม่แยกความแตกต่างระหว่างสองอย่างนี้ ในกรณีที่คลุมเครือให้กำหนดข้อความแสดงข้อผิดพลาด / คำเตือนเป็นข้อความใด ๆ ที่ส่งออกโดยการนำไปปฏิบัติอย่างใดอย่างหนึ่ง: 1. เป็นผลมาจากสิ่งอื่นนอกเหนือจากการดำเนินการคำสั่ง หรือ 2. นั่นไม่ใช่ส่วนหนึ่งของอินพุตไปยังคำสั่งที่สร้างมันเป็นเอาต์พุต
  • ส่วนข้อผิดพลาด / คำเตือนของควินินไม่จำเป็นต้องเป็นควินที่เหมาะสม (แม้ว่าโดยส่วนใหญ่แล้วจะเกิดขึ้นโดยบังเอิญเนื่องจากข้อผิดพลาดและข้อความเตือนส่วนใหญ่มีข้อความคงที่จำนวนมาก)
  • เป็นที่ยอมรับได้สำหรับโปรแกรมที่จะส่งออกข้อผิดพลาด / คำเตือนหลายอย่างซึ่งเป็นแหล่งที่มาของโปรแกรมเมื่อต่อกันเข้าด้วยกัน ไม่สามารถยอมรับข้อผิดพลาด / คำเตือนเอาต์พุตที่ไม่ปรากฏในแหล่งที่มา
  • ไม่เหมือนกับความท้าทายมากมายสวิตช์ที่มอบให้คอมไพเลอร์และชื่อไฟล์ของโปรแกรมนั้นมีความเกี่ยวข้องสูงในการท้าทายนี้ ระบุว่าความท้าทายอาจเป็นไปไม่ได้เป็นอย่างอื่นฉันยินดีที่จะมีความยืดหยุ่นที่นี่แม้ว่าคุณจะดำเนินการในลักษณะที่ผิดปกติโปรดจำไว้ว่ากฎ PPCG คิดค่าปรับแบบไบต์ต่อการทำเช่นนั้น (เท่ากับจำนวนอักขระเพิ่มเติมที่ คุณจะต้องเพิ่มบรรทัดคำสั่งในวิธี "ปกติ" ที่สั้นที่สุดเพื่อเรียกใช้โปรแกรม) ดังนั้นคุณจะต้องระบุขนาดของการลงโทษในโพสต์ของคุณ (ตัวอย่างเช่นหากล่ามที่คุณใช้อ่านโปรแกรมจากไฟล์และไม่มีข้อ จำกัด ในชื่อไฟล์วิธีที่สั้นที่สุดในการเรียกใช้โปรแกรมปกติจะมาจากไฟล์ที่มีชื่อไฟล์ 1 ตัวดังนั้น
  • เวอร์ชันคอมไพเลอร์ / ล่ามที่คุณใช้อาจมีความเกี่ยวข้องดังนั้นในฐานะส่วนหนึ่งของการส่งของคุณโปรดระบุคอมไพเลอร์หรือล่ามเฉพาะที่โปรแกรมของคุณทำงานและเวอร์ชันที่จำเป็นต้องใช้ (ตัวอย่างเช่นการส่ง C อาจระบุ "C (gcc 6.2.0)" ในส่วนหัว)
  • โปรดทราบว่างานนี้อาจไม่สามารถทำได้ในทุกภาษา ในภาษาที่มันเป็นวิธีที่ง่ายที่สุดน่าจะเป็นการหาข้อผิดพลาดหรือข้อความเตือนที่เป็นไปได้ในการปรับแต่งบางส่วนของข้อความ (ผ่านการเปลี่ยนชื่อของสิ่งที่ได้รับการยกมาในข้อความ; ที่นี่ แต่ไม่ใช่เพียงอันเดียว) ฉันจะต้องประทับใจโดยเฉพาะอย่างยิ่ง (และประหลาดใจ) ถ้ามีคนพบวิธีที่จะทำเช่นนี้โดยใช้เพียงความผิดพลาดและข้อความเตือนที่มีข้อความที่ได้รับการแก้ไข

เงื่อนไขชัยชนะ

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


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

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

ฉันคิดว่าคำถามนั้นไม่ชัดเจนและไม่มีเกณฑ์ความถูกต้องตามวัตถุประสงค์ ฉันยอมรับว่าการเปลี่ยนแปลงที่เสนอของฉันอาจทำให้สิ่งเลวร้ายลงไปอีก วิธีการหนึ่งที่เป็นไปได้ของการดำเนินการคือการระงับความท้าทายไว้แล้วลงในกล่องทราย
Dennis

1
ตอนนี้ฉันได้หยุดการท้าทายไว้แล้ว ฉันหวังว่าคุณจะพิจารณาใหม่อีกครั้งในกล่องทราย มันเป็นความคิดที่น่าสนใจมากและน่าเสียดายที่ปล่อยให้มันเสียเปล่า
Dennis

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

คำตอบ:


9

JavaScript (Firefox 50), 153 ไบต์

Error: "Error: 1.replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x.slice(7)})".replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x.slice(7)})

คำอธิบาย

ความคิดที่นี่คือการเริ่มต้นด้วยquine JS แก้ไขได้ง่ายที่สุดที่ฉันได้พบ:

".replace(/.+/,x=>alert(uneval(x)+x))".replace(/.+/,x=>alert(uneval(x)+x))

throwคำหลักเป็นวิธีที่ง่ายที่จะทำให้มันโยนรหัสของตัวเองเช่นกัน:

".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})

แต่มีปัญหาเล็กน้อย: Firefox prepends Error:ข้อความโยนด้วย โชคดีError: mycodeที่ JavaScript นั้นใช้งานได้จริง! (หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับเรื่องนี้โปรดไปที่ MDN )

Error: ".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})Error: ".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})

อุ๊ปส์แจ้งเตือนสิ่งผิดปกติ:

".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})Error: ".replace(/.+/,x=>{alert(x=uneval(x)+x);throw x})Error: 

เนื่องจากเครื่องหมายคำพูดไม่ได้อยู่ที่จุดเริ่มต้นของรหัสอีกต่อไปแล้วuneval(x)+xจะไม่ให้ผลลัพธ์ที่ถูกต้องกับเรา วิธีที่ดีที่สุดในการแก้ไขปัญหานี้คือการเพิ่มตัวยึดตำแหน่งแทนที่สตริงที่ซ้อนกัน:

Error: "Error: 1.replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x})".replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x})

เอ่อ - ตอนนี้มีError:ข้อผิดพลาดพิเศษใน มาแก้ไขด้วยการแบ่งสตริง:

Error: "Error: 1.replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x.slice(7)})".replace(/.+/,x=>{alert(x=x.replace(1,uneval(x)));throw x.slice(7)})

และในที่สุดทั้งผลลัพธ์และข้อความแสดงข้อผิดพลาดจะเหมือนกันกับรหัส! ฉันจะเพิ่ม Stack Snippet แต่ดูเหมือนว่าจะไม่ทำงานใน snippet ในเบราว์เซอร์ใด ๆ


5

Python 2, 217 80 51 ไบต์

ต้องการการป้อนบรรทัดต่อท้าย

s='s=%r;print s%%s;exit(s%%s)';print s%s;exit(s%s)


ลองออนไลน์

ฉันเริ่มต้นด้วย quine ง่าย ๆ :

s='s=%r;print s%%s';print s%s

แล้วฉันจะเพิ่มที่สิ้นสุดจะโยนraiseIOError

s='s=%r;print s%%s;raise IOError(s%%s)';print s%s;raise IOError(s%s)

น่าเสียดายที่การย้อนกลับเป็นสาเหตุของปัญหา (ฉันไม่สามารถทำให้หายไปได้อย่างสมบูรณ์) และชื่อของข้อยกเว้นนั้นจะถูกพิมพ์อยู่ด้านหน้าเสมอIOError: <code here>แม้ว่าฉันจะลบการติดตามกลับออกไปก็ตาม

จากนั้นฉันก็พบคำตอบ SO ที่เป็นประโยชน์และแก้ไขเพื่อจุดประสงค์ของฉัน

จากนั้นฉันก็พบว่าฉันสามารถข้ามการสร้างคลาสของตัวเองและสามารถใช้งานsys.exitได้ทำให้รหัสของฉันสั้นลงมาก


1
ฉันไม่คิดว่าสอดคล้องนี้กับความหมายของข้อผิดพลาดในข้อมูลจำเพาะท้าทายเพราะมันไม่ได้เป็นผลมาจากสิ่งอื่นที่ไม่ใช่รันคำสั่งที่ไม่เป็นมันก็ไม่ได้เป็นส่วนหนึ่งของการป้อนข้อมูลเพื่อคำสั่งที่ผลิตเป็นเอาท์พุท ที่กล่าวว่าexitทำงานธรรมดาได้ดีที่นี่ sysไม่จำเป็นต้อง
Dennis

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