Lỗi (hoặc cảnh báo) quine đó cũng là một quine thông thường [đã đóng]


9

(Lấy cảm hứng từ nhận xét này về một câu hỏi cũ.)

Lý lịch

Một quine lỗi (còn được gọi là "Kimian quine") là một chương trình, khi được biên dịch hoặc chạy, sẽ khiến trình biên dịch / trình thông dịch / thời gian chạy in một thông báo lỗi có văn bản giống hệt với chương trình và không có gì khác. Đối với mục đích của thử thách này, chúng tôi đang xác định rộng rãi "lỗi", bao gồm cả các cảnh báo.

Bài tập

Trong thử thách này, chúng tôi đang tìm kiếm một đó là cũng một Quine lỗi. Khi được thực thi, chương trình phải in mã nguồn của chính nó một cách bình thường (nghĩa là không phải là thông báo lỗi / cảnh báo); đây phải là một quine thích hợp (nghĩa là một phần của chương trình phải mã hóa một phần khác của đầu ra). Ngoài ra, việc biên dịch và thực thi chương trình cũng phải khiến mã nguồn của chương trình - và không có gì khác - được in dưới dạng thông báo lỗi hoặc cảnh báo khi triển khai. (Lưu ý rằng điều này có nghĩa là bạn sẽ không thể sử dụng các lỗi thời gian biên dịch, trong các ngôn ngữ mà các chương trình đó ngăn chương trình thực thi bình thường.) Vì vậy, nói cách khác, mã nguồn của chương trình sẽ được in hai lần, mỗi lần qua mỗi phương thức.

Làm rõ

  • Trong hầu hết các trường hợp, rõ ràng đây không phải là thông báo lỗi / cảnh báo; chúng tôi không phân biệt giữa hai ở đây. Trong các trường hợp không rõ ràng, hãy xác định một thông báo lỗi / cảnh báo là bất kỳ văn bản nào được tạo ra bởi việc triển khai: 1. do hậu quả của việc gì đó ngoài việc thực hiện lệnh (hoặc bất cứ điều gì tương đương gần nhất với ngôn ngữ); hoặc 2. đó không phải là một phần của đầu vào cho lệnh đã tạo ra nó làm đầu ra.
  • Phần lỗi / cảnh báo của quine không cần phải là một quine thích hợp (mặc dù trong hầu hết các trường hợp, đó sẽ là tình cờ, vì hầu hết các thông báo lỗi và cảnh báo đều chứa một lượng đáng kể văn bản cố định).
  • Chương trình có thể chấp nhận để đưa ra nhiều lỗi / cảnh báo, tạo thành nguồn của chương trình khi được nối với nhau. Không thể chấp nhận các lỗi / cảnh báo đầu ra không xuất hiện trong nguồn.
  • Không giống như trong nhiều thử thách, các công tắc được cung cấp cho trình biên dịch và tên tệp chương trình, có khả năng có liên quan cao trong thử thách này. Cho rằng thách thức có thể không thể xảy ra nếu không, tôi sẵn sàng linh hoạt ở đây, mặc dù nếu bạn thực hiện việc triển khai theo cách khác thường, hãy nhớ rằng các quy tắc PPCG tính phí phạt byte khi làm như vậy (bằng số lượng ký tự bổ sung mà bạn cần thêm vào dòng lệnh theo cách "bình thường" ngắn nhất để chạy chương trình), và do đó bạn sẽ cần chỉ định kích thước của hình phạt trong bài đăng của mình. (Ví dụ: nếu trình thông dịch bạn đang sử dụng đọc chương trình từ một tệp và không có hạn chế cụ thể nào đối với tên tệp, thì cách thông thường ngắn nhất để chạy chương trình sẽ là từ một tệp có tên tệp 1 ký tự;
  • Phiên bản trình biên dịch / trình thông dịch bạn sử dụng cũng có thể có liên quan, vì vậy là một phần trong bài gửi của bạn, vui lòng nêu một trình biên dịch hoặc trình thông dịch cụ thể mà chương trình của bạn hoạt động và phiên bản nào là bắt buộc. (Ví dụ: một bài nộp C có thể ghi "C (gcc 6.2.0)" trong tiêu đề.)
  • Lưu ý rằng nhiệm vụ này có thể không thực hiện được trong tất cả các ngôn ngữ. Trong các ngôn ngữ, ngôn ngữ dễ nhất có thể là tìm lỗi hoặc thông báo cảnh báo để có thể tùy chỉnh một số tập hợp con của văn bản (thông qua thay đổi tên của nội dung được trích dẫn trong tin nhắn; tên tệp là một lựa chọn phổ biến ở đây, nhưng không phải là người duy nhất). Tôi sẽ đặc biệt ấn tượng (và ngạc nhiên) nếu ai đó tìm ra cách để làm điều này chỉ bằng các thông báo lỗi và cảnh báo có văn bản được sửa.

Điều kiện chiến thắng

Đây là một thử thách , vì vậy một mục được coi là tốt hơn nếu nó có số byte nhỏ hơn. Như vậy, một khi bạn đã làm cho chương trình của mình hoạt động hoàn toàn, bạn muốn tối ưu hóa nó để giảm số lượng byte càng nhiều càng tốt. (Tuy nhiên, đừng nản lòng nếu đã có một mục ngắn hơn, đặc biệt là nếu nó bằng một ngôn ngữ khác; điều chúng tôi thực sự tìm kiếm ở đây là rút ngắn một thuật toán hoặc ý tưởng cụ thể đằng sau một chương trình càng nhiều càng tốt, nhưng nhìn thấy nhiều các giải pháp trong các ngôn ngữ khác nhau hoặc dựa trên các nguyên tắc khác nhau luôn luôn có giá trị.)


2
Như tôi đã nói trong trò chuyện, tôi nghĩ rằng gạch đầu dòng không rõ ràng. Trong hầu hết các trường hợp, rõ ràng đây không phải là thông báo lỗi / cảnh báo chỉ đóng vai trò là điểm khởi đầu cho các cuộc thảo luận và lập pháp ngôn ngữ.
Dennis

@Dennis: Về nguyên tắc, tôi đồng ý rằng tình hình không tốt lắm, nhưng mặt khác không thể nghĩ ra một cách cụ thể để cải thiện nó; loại bỏ ngoại lệ cho những thứ rõ ràng là thông báo lỗi có khả năng dẫn đến một số tình huống rất ngoài ý muốn trong một số ngôn ngữ, điều này có thể gây ra thiệt hại nhiều hơn so với cách chữa; nếu bạn nghĩ rằng bạn có thể cải thiện câu hỏi, tôi không phản đối việc nó được chỉnh sửa (và tôi thực sự không nghĩ rằng câu hỏi về PPCG nên có "quyền sở hữu", mặc dù đó là một vấn đề khác)

Vì nó là, tôi nghĩ rằng câu hỏi không rõ ràng và thiếu một tiêu chí hợp lệ khách quan. Tôi đồng ý rằng sự thay đổi được đề xuất của tôi có thể khiến mọi thứ trở nên tồi tệ hơn. Một hành động khả thi sẽ là tạm dừng thử thách và đăng lại nó trong hộp cát.
Dennis

1
Bây giờ tôi đã đặt thử thách. Tôi hy vọng bạn xem xét lại việc đăng lại nó trong hộp cát. Đó là một ý tưởng rất thú vị, và sẽ thật xấu hổ khi để nó lãng phí.
Dennis

1
Sandbox bài viết ở đây . (Tôi đang xem xét chỉnh sửa câu hỏi đó, nhưng điều đó sẽ đưa bài đăng vào hàng đợi mở lại, điều này sẽ rất phản tác dụng vì nó sẽ khó mở lại nếu và khi vấn đề được giải quyết.)

Câu trả lời:


9

JavaScript (Firefox 50), 153 byte

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)})

Giải trình

Ý tưởng ở đây là bắt đầu với quine JS có thể sửa đổi dễ dàng nhất mà tôi đã tìm thấy:

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

Các throwtừ khóa là một cách đơn giản để làm cho nó ném mã riêng của mình cũng như:

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

Tuy nhiên, có một vấn đề nhỏ: Firefox chuẩn bị tin nhắn bị ném Error:. May mắn thay, Error: mycodethực sự là JavaScript hợp lệ! (Để tìm hiểu thêm về điều này, hãy truy cập MDN .)

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

Rất tiếc, điều này cảnh báo điều sai:

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

Vì dấu ngoặc kép không còn ở đầu mã, nên uneval(x)+xsẽ không cung cấp cho chúng tôi kết quả chính xác. Cách tốt nhất để khắc phục điều này là thêm một trình giữ chỗ thay cho chuỗi lồng nhau:

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})

Uh-oh, bây giờ có thêm một Error:thông báo lỗi. Hãy khắc phục điều đó bằng cách cắt chuỗi:

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)})

Và cuối cùng, cả đầu ra và thông báo lỗi đều giống hệt mã! Tôi đã thêm một Stack Snippet, nhưng nó dường như không hoạt động trong một đoạn mã trong bất kỳ trình duyệt nào.


5

Python 2, 217 80 51 byte

Các linefeed trailing là bắt buộc.

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

Dùng thử trực tuyến

Tôi bắt đầu với một câu hỏi đơn giản:

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

Sau đó tôi thêm raisevào cuối để ném một IOError.

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

Thật không may, truy nguyên đã gây ra sự cố (tôi không thể làm cho nó biến mất hoàn toàn) và tên của ngoại lệ luôn được in ở phía trước như thế IOError: <code here>, ngay cả khi tôi đã xóa dấu vết đó.

Sau đó, tôi tìm thấy câu trả lời SO hữu ích này và sửa đổi nó cho mục đích của tôi.

Sau đó, tôi thấy rằng tôi có thể bỏ qua việc tạo lớp của riêng mình và chỉ có thể sử dụng sys.exit, làm cho mã của tôi ngắn hơn nhiều.


1
Tôi không nghĩ rằng điều này tuân thủ định nghĩa lỗi trong thông số thử thách vì nó không phải là hậu quả của việc gì đó ngoài việc thực thi lệnh cũng không phải là một phần của đầu vào cho lệnh tạo ra nó làm đầu ra . Điều đó nói rằng, exitcông việc đơn giản chỉ tốt ở đây. Không cần sys.
Dennis

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.