Golf bạn một quine cho tốt tuyệt vời!


204

Sử dụng ngôn ngữ của bạn, golf một quine .

Một quine là một chương trình máy tính không trống, không có đầu vào và tạo ra một bản sao của mã nguồn riêng của nó làm đầu ra duy nhất của nó.

Không gian lận - điều đó có nghĩa là bạn không thể chỉ đọc tệp nguồn và in nó. Ngoài ra, trong nhiều ngôn ngữ, một tập tin trống cũng là một câu hỏi: đó cũng không được coi là một câu hỏi hợp pháp.

Không có quines lỗi - đã có một thách thức riêng cho các quines lỗi.

Điểm cho:

  • Mã nhỏ nhất (tính bằng byte)
  • Hầu hết các giải pháp che khuất / tối nghĩa
  • Sử dụng các ngôn ngữ bí truyền / tối nghĩa
  • Sử dụng thành công các ngôn ngữ khó chơi golf

Đoạn mã sau đây có thể được sử dụng để có được cái nhìn nhanh về điểm số hiện tại trong mỗi ngôn ngữ và do đó để biết ngôn ngữ nào có câu trả lời hiện có và loại mục tiêu bạn phải đánh bại:


4
Bạn không có ý, "Chơi golf cho bạn một câu hỏi hay hơn!"?
Mateen Ulhaq

50
@muntoo đó là một trò chơi trên "Tìm hiểu cho bạn một Haskell cho những điều tốt đẹp".
Rafe Kettler

Câu trả lời:


106

Hexagony , chiều dài phụ 17 16, 816 705 byte

180963109168843880558244491673953327577233938129339173058720504081484022549811402058271303887670710274969455065557883702369807148960608553223879503892017157337685576056512546932243594316638247597075423507937943819812664454190530214807032600083287129465751195839469777849740055584043374711363571711078781297231590606019313065042667406784753422844".".>.@.#.#.#.#.#.#.#.>.(...........................<.".......".".>./.4.Q.;.+.<.#.>...........................<.".....".".>.#.#.>.N.2.'.\.>.............=.=......._.<.".....".".>.>.;.'.=.:.\.>.......................<."...".".>.\.'.%.'.<.#.>..............._.....<."...".".>.#.#.>.<.#.>...............=.=.<.".".".>.#.\.'.R./.>.................<.".!.........../.>.

Hãy thử trực tuyến!

Đây là những gì nó trông giống như mở ra:

                1 8 0 9 6 3 1 0 9 1 6 8 8 4 3 8
               8 0 5 5 8 2 4 4 4 9 1 6 7 3 9 5 3
              3 2 7 5 7 7 2 3 3 9 3 8 1 2 9 3 3 9
             1 7 3 0 5 8 7 2 0 5 0 4 0 8 1 4 8 4 0
            2 2 5 4 9 8 1 1 4 0 2 0 5 8 2 7 1 3 0 3
           8 8 7 6 7 0 7 1 0 2 7 4 9 6 9 4 5 5 0 6 5
          5 5 7 8 8 3 7 0 2 3 6 9 8 0 7 1 4 8 9 6 0 6
         0 8 5 5 3 2 2 3 8 7 9 5 0 3 8 9 2 0 1 7 1 5 7
        3 3 7 6 8 5 5 7 6 0 5 6 5 1 2 5 4 6 9 3 2 2 4 3
       5 9 4 3 1 6 6 3 8 2 4 7 5 9 7 0 7 5 4 2 3 5 0 7 9
      3 7 9 4 3 8 1 9 8 1 2 6 6 4 4 5 4 1 9 0 5 3 0 2 1 4
     8 0 7 0 3 2 6 0 0 0 8 3 2 8 7 1 2 9 4 6 5 7 5 1 1 9 5
    8 3 9 4 6 9 7 7 7 8 4 9 7 4 0 0 5 5 5 8 4 0 4 3 3 7 4 7
   1 1 3 6 3 5 7 1 7 1 1 0 7 8 7 8 1 2 9 7 2 3 1 5 9 0 6 0 6
  0 1 9 3 1 3 0 6 5 0 4 2 6 6 7 4 0 6 7 8 4 7 5 3 4 2 2 8 4 4
 " . " . > . @ . # . # . # . # . # . # . # . > . ( . . . . . .
  . . . . . . . . . . . . . . . . . . . . . < . " . . . . . .
   . " . " . > . / . 4 . Q . ; . + . < . # . > . . . . . . .
    . . . . . . . . . . . . . . . . . . . . < . " . . . . .
     " . " . > . # . # . > . N . 2 . ' . \ . > . . . . . .
      . . . . . . . = . = . . . . . . . _ . < . " . . . .
       . " . " . > . > . ; . ' . = . : . \ . > . . . . .
        . . . . . . . . . . . . . . . . . . < . " . . .
         " . " . > . \ . ' . % . ' . < . # . > . . . .
          . . . . . . . . . . . _ . . . . . < . " . .
           . " . " . > . # . # . > . < . # . > . . .
            . . . . . . . . . . . . = . = . < . " .
             " . " . > . # . \ . ' . R . / . > . .
              . . . . . . . . . . . . . . . < . "
               . ! . . . . . . . . . . . / . > .
                . . . . . . . . . . . . . . . .

À, đây hoàn toàn là tàu lượn siêu tốc đầy cảm xúc ... Tôi đã ngừng đếm số lần tôi chuyển đổi giữa "haha, đây là sự điên rồ" và "chờ đợi, nếu tôi làm điều này thì thực sự có thể thực hiện được". Các ràng buộc áp đặt cho mã theo quy tắc bố cục của Hexagony là ... nghiêm trọng.

Có thể giảm 1 hoặc 2 độ dài cạnh mà không thay đổi cách tiếp cận chung, nhưng sẽ rất khó khăn (chỉ các ô #hiện không được sử dụng có sẵn cho bộ giải mã). Hiện tại tôi cũng hoàn toàn không còn ý tưởng nào về cách tiếp cận hiệu quả hơn, nhưng tôi chắc chắn một phương pháp tồn tại. Tôi sẽ suy nghĩ điều này trong vài ngày tới và có thể cố gắng đánh gôn một chiều, trước khi tôi thêm một lời giải thích và mọi thứ.

Ít nhất, tôi đã chứng minh điều đó là có thể ...

Một số tập lệnh CJam để tham khảo trong tương lai của riêng tôi:


51
Dear pete đây là gì.
Conor O'Brien

2
Mất bao lâu để thực hiện điều này?
Ad Nam

3
@AandN Tôi đã chơi xung quanh với các khái niệm cho một "mẫu" chung từ hôm qua và sau đó (điều đó không liên quan đến bất kỳ thử nghiệm thực tế nào ... chỉ cần gõ một số nội dung trên lưới 7x7 và xem liệu nó có thể hoạt động không .. Tôi đã loại bỏ khoảng nửa tá cách tiếp cận đã có). Việc mã hóa thực tế sau đó mất tối nay ... có thể là 3 giờ, tôi nói.
Martin Ender

10
Các từ không thể giải thích tôi ngạc nhiên như thế nào khi thấy điều này hoạt động với IDE bí truyền từng bước ... Để ai có thể muốn hiểu điều này, Hexagon này mã hóa phần "bộ giải mã" thành một số nguyên được in !và sau đó bằng một số nguyên nhân bản /trên dòng thứ 2 cuối cùng, nó đi vào bộ giải mã để in mã bộ giải mã để hoàn thành quine. Điều này có một công dụng kỳ diệu <>đọc số nguyên rất lớn và xây dựng khu vực để lưu trữ bộ giải mã. Tôi thực sự muốn biết "hàng tá cách tiếp cận" đang được xem xét?
Nắng Pun

3
Giải trình? ---
MD XF

77

MySQL, 167 ký tự

SELECT REPLACE(@v:='SELECT REPLACE(@v:=\'2\',1+1,REPLACE(REPLACE(@v,\'\\\\\',\'\\\\\\\\\'),\'\\\'\',\'\\\\\\\'\'));',1+1,REPLACE(REPLACE(@v,'\\','\\\\'),'\'','\\\''));

Đúng rồi. :-)

Tôi thực sự đã viết cái này cho mình. Nó ban đầu được đăng tại trang web của tôi .


72

GolfScript, 2 byte

1

(lưu ý dòng mới) Điều này đẩy số 1 lên ngăn xếp. Vào cuối chương trình, GolfScript in ra tất cả các mục trong ngăn xếp (không có khoảng trắng ở giữa), sau đó in một dòng mới.

Đây là một câu hỏi thực sự (như được liệt kê trong câu hỏi), bởi vì nó thực sự thực thi mã; nó không chỉ "đọc tệp nguồn và in nó" (không giống như trình PHP).


Ví dụ khác, đây là chương trình GolfScript để in 12345678:

9,(;
  1. 9: đẩy 9 đến ngăn xếp
  2. ,: tiêu thụ số 9 làm đối số, đẩy mảng [0 1 2 3 4 5 6 7 8]lên ngăn xếp
  3. (: tiêu thụ mảng làm đối số, đẩy mảng [1 2 3 4 5 6 7 8]và mục 0vào ngăn xếp
  4. ;: loại bỏ mục trên cùng của ngăn xếp

Bây giờ ngăn xếp chứa mảng [1 2 3 4 5 6 7 8]. Điều này được ghi vào đầu ra tiêu chuẩn không có khoảng cách giữa các thành phần, theo sau là một dòng mới.


18
Hoặc PowerShell hoặc PHP :-)
Joey

6
Bạn đã không quay ngược thời gian và đưa ra ý tưởng để phát minh ra GolfScript, phải không?
Mateen Ulhaq

78
Về mặt kỹ thuật, 1không phải là một điểm yếu trong GolfScript: nó xuất ra 1\n, trong đó \nbiểu thị một dòng mới. Tuy nhiên, chương trình hai char 1\n một quine.
Ilmari Karonen

17
Chương trình một char \ncó lẽ cũng là?
Lynn

10
@Pseudonymous a quine đúng nghĩa là một chương trình in nguồn riêng của nó. Tôi không nghĩ có bất kỳ hạn chế tùy tiện nào về "cấu trúc".
Hugo Zink

71

Brain-Flak , 9.8e580 1.3e562 9.3e516 12818 11024 4452 4332 4240 4200 4180 3852 3656 3616 3540 2485 + 3 = 2488 byte

Bây giờ phù hợp trong vũ trụ quan sát được!

(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(())(())(()())(())(())(())(()())(()()()())(())(()()()()())(()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(())(())(()())(())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(())(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(()()())(())(()()())(())(())(())(()())(()()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(())(())(())(()()())(())(())(())(()())(())(()())(()()()())(())(())(()()()()())(()())(()())(())(()()())(())(())(())(())(()()())(()())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(()()()()())(())(()()())(())(())(()())(())(()()()()())(())(()()()()())(())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()()()())(())(()()()()())(())(())(())(()())(())(()()()()())(())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()()()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(())(()())(()()()())(())(())(()())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(()()())(())(())(()())(())(())(()()()()())(()()()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(()()()())(()()()())(()())([[]]){({}()<(([{}]())<{({}())<>(((((()()()()()){}){}){}())[()])<>{({}())<>{}({}(((()()()){}())){}{})<>{({}())<>({}(((()()()()()){})){}{}())<>{{}<>({}(((()()()()){}){}){})(<>)}}<>(({})[()()])<>}}{}<>({}(<()>)<><{({}<>)<>}<>>){({}<>)<>}{}(<>)<>{({}<>)<>}{}(((((((()()()()()){}){}){}))()))>){({}()<((({}[()])()))>)}{}<>{({}<>)<>}{}>)}{}<>{({}<>)<>}<>

Hãy thử trực tuyến!


Giải trình

Quine này hoạt động giống như hầu hết các Quines trong các ngôn ngữ bí truyền; Nó có hai phần là một bộ mã hóa và một bộ giải mã. Bộ mã hóa là tất cả các dấu ngoặc đơn ở đầu và bộ giải mã là phần phức tạp hơn ở cuối.

Một cách mã hóa chương trình ngây thơ sẽ là đưa giá trị ASCII của mọi ký tự vào bộ giải mã vào ngăn xếp. Đây không phải là một ý tưởng hay vì Brain-Flak chỉ sử dụng 8 ký tự ( ()<>[]{}) nên cuối cùng bạn phải trả khá nhiều byte để mã hóa rất ít thông tin. Một ý tưởng thông minh hơn, và ý tưởng được sử dụng cho đến bây giờ là gán cho mỗi trong số 8 dấu ngoặc nhọn thành một số nhỏ hơn nhiều (1-8) và chuyển đổi chúng thành các giá trị ASCII bằng bộ giải mã của chúng tôi. Điều này là tốt bởi vì chi phí không quá 18 byte để mã hóa một ký tự trái ngược với 252 trước đó.

Tuy nhiên chương trình này không. Nó dựa vào thực tế là các chương trình Brain-Flak đều được cân bằng để mã hóa 8 dấu ngoặc nhọn với số lượng lên đến 5. Nó mã hóa chúng như sau.

(       -> 2
<       -> 3
[       -> 4
{       -> 5
),>,],} -> 1

Tất cả các dấu ngoặc nhọn được gán 1 vì chúng ta có thể sử dụng ngữ cảnh để xác định chúng cần sử dụng trong số chúng trong một kịch bản cụ thể. Điều này nghe có vẻ như là một nhiệm vụ khó khăn đối với chương trình Brain-Flak, nhưng thực sự không phải vậy. Lấy ví dụ các bảng mã sau với các dấu ngoặc mở được giải mã và các dấu ngoặc nhọn được thay thế bằng .:

(.
((..
<([.{...

Hy vọng rằng bạn có thể thấy rằng thuật toán này khá đơn giản, chúng tôi đọc từ trái sang phải, mỗi lần chúng tôi bắt gặp một cú đúp mở, chúng tôi đẩy cú đúp của nó đến một ngăn xếp tưởng tượng và khi chúng tôi gặp một .giá trị hàng đầu và đặt nó vào vị trí của .. Mã hóa mới này giúp chúng tôi tiết kiệm một số lượng lớn byte trong bộ mã hóa trong khi chỉ mất một số byte trên bộ giải mã.

Giải thích cấp thấp

Công việc đang tiến triển


25
Tôi nghĩ rằng bạn giành chiến thắng cho giải pháp lâu nhất cho một thử thách chơi gôn ...
Mego

18
Chỉ cần làm một golf đơn lớn nhất trong lịch sử của PPCG Nope. 9.8e580 vẫn rất ấn tượng.
Dennis

19
+1 để phù hợp với vũ trụ quan sát được. Ngoài ra, với TIO Nexus, permalink sẽ phù hợp với câu trả lời. tio.run/nexus/ Kẻ
Dennis

3
... gôn rất lớn ...
Lemon phá hủy

3
Tôi nghĩ bạn thắng được hầu hết các byte bị cắt
Christopher

68

Mở đầu , 5157 4514 2348 1761 1537 664 569 535 423 241 214 184 178 175 169 148 142 136 133 byte

Cảm ơn Sp3000 đã lưu 3 byte.

Điều này khá dài ... (được thôi, nó vẫn còn dài ... ít nhất là nó đã đánh bại cuộc thi Brainfuck C # ngắn nhất được biết đến trong thử thách này bây giờ) nhưng đó là câu hỏi đầu tiên tôi tự khám phá (bài nộp Lua và Julia của tôi thực sự chỉ là bản dịch của kỹ thuật quine tiêu chuẩn sang các ngôn ngữ khác) theo như tôi biết thì không ai đã viết một câu chuyện trong Prelude cho đến nay, vì vậy tôi thực sự khá tự hào về điều này. :)

7( -^^^2+8+2-!( 6+ !
  ((#^#(1- )#)8(1-)8)#)4337435843475142584337433447514237963742423434123534455634423547524558455296969647344257)

Số lượng lớn các chữ số đó chỉ là một mã hóa của mã lõi, đó là lý do tại sao quine quá dài.

Các chữ số mã hóa quine đã được tạo bằng tập lệnh CJam này .

Điều này đòi hỏi một trình thông dịch tuân thủ tiêu chuẩn, in các ký tự (sử dụng các giá trị làm mã ký tự). Vì vậy, nếu bạn đang sử dụng trình thông dịch Python, bạn sẽ cần phải đặt NUMERIC_OUTPUT = False.

Giải trình

Đầu tiên, một vài từ về Prelude: mỗi dòng trong Prelude là một "giọng nói" riêng biệt điều khiển ngăn xếp của chính nó. Các ngăn xếp này được khởi tạo với số lượng 0 vô hạn. Chương trình được thực hiện theo từng cột, trong đó tất cả các lệnh trong cột được thực thi "đồng thời" dựa trên các trạng thái ngăn xếp trước đó. Các chữ số được đẩy lên ngăn xếp riêng lẻ, do đó 42sẽ đẩy a 4, sau đó a 2. Không có cách nào để đẩy số lượng lớn hơn trực tiếp, bạn sẽ phải thêm chúng lên. Các giá trị có thể được sao chép từ các ngăn xếp liền kề với v^. Các vòng lặp kiểu Brainfuck có thể được giới thiệu với dấu ngoặc đơn. Xem liên kết trong tiêu đề để biết thêm thông tin.

Đây là ý tưởng cơ bản của quine: đầu tiên chúng ta đẩy vô số chữ số lên ngăn xếp mã hóa lõi của quine. Lõi đã nói sau đó lấy các chữ số đó, giải mã chúng để tự in và sau đó in các chữ số khi chúng xuất hiện trong mã (và dấu )).

Điều này hơi phức tạp bởi thực tế là tôi đã phải chia lõi trên nhiều dòng. Ban đầu tôi có mã hóa khi bắt đầu, nhưng sau đó cần phải đệm các dòng khác có cùng số khoảng trắng. Đây là lý do tại sao điểm số ban đầu rất lớn. Bây giờ tôi đã đặt mã hóa ở cuối, nhưng điều này có nghĩa là trước tiên tôi cần bỏ qua lõi, sau đó ấn các chữ số và quay lại bắt đầu và thực hiện in.

Mã hóa

Vì mã chỉ có hai tiếng nói và kề nhau là tuần hoàn ^vđồng nghĩa. Điều đó tốt bởi vì vcó mã ký tự lớn nhất, do đó, tránh sử dụng nó bằng cách luôn luôn sử dụng ^mã hóa đơn giản hơn. Bây giờ tất cả các mã ký tự nằm trong phạm vi 10 đến 94, bao gồm. Điều này có nghĩa là tôi có thể mã hóa mỗi ký tự với chính xác hai chữ số thập phân. Mặc dù có một vấn đề: một số ký tự, đặc biệt là nguồn cấp dữ liệu, có số 0 trong biểu diễn thập phân của chúng. Đó là một vấn đề bởi vì số không không dễ dàng phân biệt với đáy của ngăn xếp. May mắn thay, có một cách khắc phục đơn giản: chúng tôi bù các mã ký tự 2, vì vậy chúng tôi có phạm vi từ 12 đến 96, bao gồm, vẫn thoải mái vừa với hai chữ số thập phân. Bây giờ trong số tất cả các nhân vật có thể xuất hiện trong chương trình Prelude,0có 0 trong đại diện của nó (50), nhưng chúng tôi thực sự không cần 0gì cả. Vì vậy, đó là mã hóa tôi đang sử dụng, đẩy từng chữ số riêng lẻ.

Tuy nhiên, vì chúng tôi đang làm việc với một ngăn xếp, các biểu diễn được đẩy ngược lại. Vì vậy, nếu bạn nhìn vào phần cuối của mã hóa:

...9647344257

Chia thành các cặp và đảo ngược, sau đó trừ hai, và sau đó tìm mã ký tự:

57 42 34 47 96
55 40 32 45 94
 7  (     -  ^

nơi 32tương ứng với không gian. Lõi thực hiện chính xác sự chuyển đổi này, và sau đó in các ký tự.

Lõi

Vì vậy, hãy nhìn vào cách những con số này thực sự được xử lý. Đầu tiên, điều quan trọng cần lưu ý là các dấu ngoặc đơn phù hợp không phải nằm trên cùng một dòng trong Prelude. Chỉ có thể có một dấu ngoặc đơn trên mỗi cột, vì vậy không có sự mơ hồ trong đó dấu ngoặc đơn thuộc về nhau. Cụ thể, vị trí thẳng đứng của dấu ngoặc đơn đóng luôn không liên quan - ngăn xếp được kiểm tra để xác định xem vòng lặp có kết thúc (hoặc bị bỏ qua hoàn toàn) sẽ luôn là vị trí có (.

Chúng tôi muốn chạy mã chính xác hai lần - lần đầu tiên, chúng tôi bỏ qua lõi và đẩy tất cả các số ở cuối, lần thứ hai chúng tôi chạy lõi. Trên thực tế, sau khi chúng tôi chạy lõi, chúng tôi sẽ đẩy tất cả các số đó một lần nữa, nhưng vì vòng lặp chấm dứt sau đó, điều này không liên quan. Điều này mang lại cho bộ xương sau:

7(
  (                   )43... encoding ...57)

Đầu tiên, chúng tôi phát 7ra tiếng nói đầu tiên - nếu chúng tôi không làm điều này, chúng tôi sẽ không bao giờ vào vòng lặp (đối với bộ xương, điều quan trọng là nó khác không ... tại sao cụ thể 7chúng tôi sẽ thấy sau) . Sau đó chúng ta vào vòng lặp chính. Bây giờ, giọng nói thứ hai chứa một vòng lặp khác. Ở lượt đi đầu tiên, vòng lặp này sẽ bị bỏ qua vì ngăn xếp thứ hai trống / chỉ chứa 0s. Vì vậy, chúng tôi nhảy thẳng vào mã hóa và đẩy tất cả các chữ số đó lên ngăn xếp. Các 7chúng ta đẩy vào stack đầu tiên là vẫn còn, do đó lặp đi lặp lại vòng lặp.

Lần này, cũng có một 7ngăn xếp thứ hai, vì vậy chúng tôi nhập vòng lặp vào giọng nói thứ hai. Vòng lặp trên giọng nói thứ hai được thiết kế sao cho ngăn xếp lại trống ở cuối, do đó, nó chỉ chạy một lần. Nó cũng sẽ làm cạn kiệt ngăn xếp đầu tiên ... Vì vậy, khi chúng tôi rời khỏi vòng lặp trên giọng nói thứ hai, chúng tôi lại đẩy tất cả các chữ số, nhưng bây giờ, 7ngăn xếp đầu tiên đã bị loại bỏ, vì vậy vòng lặp chính kết thúc và chương trình kết thúc.

Tiếp theo, hãy nhìn vào vòng lặp đầu tiên trong lõi thực tế. Làm mọi thứ đồng thời với một (hoặc )khá thú vị. Tôi đã đánh dấu phần thân vòng ở đây bằng =:

-^^^2+8+2-!
(#^#(1- )#)
 ==========

Điều đó có nghĩa là cột chứa (không được coi là một phần của vòng lặp (các ký tự ở đó chỉ được thực hiện một lần và ngay cả khi vòng lặp bị bỏ qua). Nhưng cột chứa phần ) này là một phần của vòng lặp và được chạy một lần trên mỗi lần lặp.

Vì vậy, chúng tôi bắt đầu với một cái duy nhất -, biến 7ngăn xếp đầu tiên thành -7... một lần nữa, nhiều hơn về sau đó. Đối với vòng lặp thực tế ...

Vòng lặp tiếp tục trong khi chồng các chữ số chưa được làm trống. Nó xử lý hai chữ số cùng một lúc ,. Mục đích của vòng lặp này là để giải mã mã hóa, in ký tự và đồng thời chuyển chồng các chữ số sang giọng nói đầu tiên. Vì vậy, phần này đầu tiên:

^^^
#^#

Cột đầu tiên di chuyển 1 chữ số sang giọng nói đầu tiên. Cột thứ hai sao chép 10 chữ số sang giọng nói thứ nhất đồng thời sao chép 1 chữ số trở lại giọng nói thứ hai. Cột thứ ba di chuyển sao chép lại giọng nói đầu tiên. Điều đó có nghĩa là giọng nói đầu tiên bây giờ có 1 chữ số hai lần và 10 chữ số ở giữa. Giọng nói thứ hai chỉ có một bản sao khác gồm 10 chữ số. Điều đó có nghĩa là chúng ta có thể làm việc với các giá trị trên đỉnh của ngăn xếp và chắc chắn có hai bản sao còn lại trên ngăn xếp đầu tiên cho lần sau.

Bây giờ chúng tôi phục hồi mã ký tự từ hai chữ số:

2+8+2-!
(1- )#

Phía dưới là một vòng lặp nhỏ chỉ giảm 10 chữ số về 0. Đối với mỗi lần lặp, chúng tôi muốn thêm 10 vào đầu. Hãy nhớ rằng đầu tiên 2không phải là một phần của vòng lặp, vì vậy thân vòng lặp thực sự +8+2có thêm 10 (sử dụng lần 2đẩy trước đó) và đẩy thêm 2. Vì vậy, khi chúng ta thực hiện xong vòng lặp, ngăn xếp đầu tiên thực sự có cơ sở- 10 giá trị và giá trị khác 2. Chúng tôi trừ đi 2 với -tài khoản bù cho mã hóa và in ký tự !. Chỉ #cần loại bỏ số 0 ở cuối vòng lặp dưới cùng.

Khi vòng lặp này hoàn thành, ngăn xếp thứ hai trống và ngăn thứ nhất giữ tất cả các chữ số theo thứ tự ngược lại (và a -7ở dưới cùng). Phần còn lại khá đơn giản:

( 6+ !
8(1-)8)#

Đây là vòng lặp thứ hai của lõi, hiện in lại tất cả các chữ số. Để làm như vậy, chúng ta cần 48 đến mỗi chữ số để có được mã ký tự chính xác. Chúng tôi làm điều này với một vòng lặp đơn giản chạy 8thời gian và thêm 6mỗi lần. Kết quả được in với !8ở cuối là cho lần lặp tiếp theo.

Vậy những gì về -7? Vâng, 48 - 7 = 41đó là mã ký tự của ). Ma thuật!

Cuối cùng, khi chúng tôi hoàn thành vòng lặp đó, chúng tôi sẽ loại bỏ vòng mà chúng 8tôi vừa đẩy #để đảm bảo rằng chúng tôi rời khỏi vòng lặp bên ngoài trên giọng nói thứ hai. Chúng tôi đẩy tất cả các chữ số một lần nữa và chương trình chấm dứt.



19
Martin, bạn phải dừng lại ở đâu đó.
xem

3
Tôi thích rằng điều này có hơn 5000 byte được đánh gôn tổng thể, cộng với một sự thừa nhận với Sp3000 để lưu 3 trong số chúng.
Kamil Drakari

2
@KamilDrakari Đó là 3 byte cuối cùng, vì vậy nó là một vấn đề lớn. ;)
Martin Ender

57

Hình lục giác , chiều dài cạnh 11, 314 byte

164248894991581511673077637999211259627125600306858995725520485910920851569759793601722945695269172442124287874075294735023125483.....!/:;.........)%'=a':\....................\...................\..................\.................\................\...............\..............\..$@.........\$><>'?2='%.<\:;_;4Q

Hãy thử trực tuyến!


Phiên bản cũ hơn:

Hình lục giác , chiều dài cạnh 11, 330 byte

362003511553420961423766261426252539048636523959468260999944549820033581478284471415809677091006384959302453627348235790194699306179..../:{;+'=1P'%'a{:..\.....................\...................\..................\.................\................\...............\..............\.............\!$><........\..@>{?2'%<......:;;4Q/

Hãy thử trực tuyến!

Encoder: Hãy thử trực tuyến!

Chương trình này tương đương với mã Python này: Hãy thử trực tuyến!

Mã chưa mở

           3 6 2 0 0 3 5 1 1 5 5
          3 4 2 0 9 6 1 4 2 3 7 6
         6 2 6 1 4 2 6 2 5 2 5 3 9
        0 4 8 6 3 6 5 2 3 9 5 9 4 6
       8 2 6 0 9 9 9 9 4 4 5 4 9 8 2
      0 0 3 3 5 8 1 4 7 8 2 8 4 4 7 1
     4 1 5 8 0 9 6 7 7 0 9 1 0 0 6 3 8
    4 9 5 9 3 0 2 4 5 3 6 2 7 3 4 8 2 3
   5 7 9 0 1 9 4 6 9 9 3 0 6 1 7 9 . . .
  . / : { ; + ' = 1 P ' % ' a { : . . \ .
 . . . . . . . . . . . . . . . . . . . . \
  . . . . . . . . . . . . . . . . . . . \ 
   . . . . . . . . . . . . . . . . . . \  
    . . . . . . . . . . . . . . . . . \   
     . . . . . . . . . . . . . . . . \    
      . . . . . . . . . . . . . . . \     
       . . . . . . . . . . . . . . \      
        . . . . . . . . . . . . . \       
         ! $ > < . . . . . . . . \        
          . . @ > { ? 2 ' % < . .         
           . . . . : ; ; 4 Q / .          

Hai .s mất 1 bit. Bất kỳ ký tự nào khác mất 1 bit và chữ số cơ sở 97.

Giải trình

Nhấp vào hình ảnh cho kích thước lớn hơn. Mỗi phần giải thích có mã Python tương ứng để giúp hiểu.

Phần dữ liệu

Thay vì các cấu trúc phức tạp được sử dụng trong một số câu trả lời khác (với <, "và một số thứ khác), tôi chỉ cho phép các IP đi qua nửa dưới.

Dữ liệu

Đầu tiên, IP chạy qua rất nhiều số và no-op's ( .) và mirror ( \). Mỗi chữ số gắn vào số trong bộ nhớ, vì vậy cuối cùng giá trị bộ nhớ bằng với số khi bắt đầu chương trình.

mem = 362003511...99306179

! in nó

stdout.write(str(mem))

$nhảy qua tiếp theo >.

Bắt đầu từ <. Nếu giá trị bộ nhớ memlà sai ( <= 0nghĩa là điều kiện mem > 0không được thỏa mãn), chúng tôi đã thực hiện in chương trình và nên thoát. IP sẽ đi theo con đường phía trên.

Lối ra

(hãy để IP chạy trên toàn thế giới trong khoảng 33 lệnh trước khi nhấn @(kết thúc chương trình) vì đặt nó ở bất kỳ nơi nào khác phát sinh thêm một số byte)

Nếu đó là sự thật, chúng tôi đi theo con đường thấp hơn, được chuyển hướng một vài lần và thực hiện thêm một số lệnh trước khi nhấn một điều kiện khác.

# Python                    # Hexagony
# go to memory cell (a)     # {
a = 2                       # ?2
# go to memory cell (b)     # '
b = mem % a                 # %

Bây giờ bộ nhớ trông như thế này:

Mem1

Nếu giá trị là trung thực:

if b > 0:

đoạn mã sau được thực thi:

# Python                    # Hexagony
b = ord('Q')                # Q
b = b*10+4                  # 4
# Note: now b == ord('.')+256*3
stdout.write(chr(b%256))    # ;
stdout.write(chr(b%256))    # ;

Xem giải thích cụ thể của Q4ít câu trả lời HelloWorld Hexagony MartinEnder của . Nói tóm lại, mã này in .hai lần.

Ban đầu tôi dự định sẽ in .một lần. Khi tôi nghĩ ra điều này (in .hai lần) và thực hiện nó, khoảng 10 chữ số đã được lưu.

Sau đó,

b = mem // a                # :

Đây là một thực tế quan trọng tôi nhận ra rằng đã tiết kiệm cho tôi khoảng 14 chữ số: Bạn không cần phải ở nơi bạn bắt đầu.


Để hiểu những gì tôi đang nói, hãy có một tương tự BF. (bỏ qua điều này nếu bạn đã hiểu)

Cho mã

while a != 0:
    b, a = a * 2, 0
    a, b = b, 0
    print(a)

Giả sử chúng ta ađặt giá trị của ô hiện tại và blà giá trị của ô bên phải, một bản dịch đơn giản của điều này sang BF là:

[             # while a != 0:
    [->++<]       # b, a = a * 2, 0
    >[-<+>]       # a, b = b, 0
    <.            # print(a)
]

Tuy nhiên, lưu ý rằng chúng ta không cần phải ở cùng một vị trí mọi lúc trong suốt chương trình. Chúng ta có thể để giá trị alà bất cứ thứ gì chúng ta có khi bắt đầu mỗi lần lặp, sau đó chúng ta có mã này:

[             # while a != 0:
    [->++<]       # b, a = a * 2, 0
                  # implicitly let (a) be at the position of (b) now
    .             # print(a)
]

đó là một vài byte ngắn hơn.


Ngoài ra, hành vi gói góc cũng giúp tôi không có \gương ở đó - nếu không có nó, tôi sẽ không thể khớp các chữ số (+2 chữ số cho \chính nó và +2 chữ số cho một cặp không ghép .ở bên phải của nó, không đề cập đến cờ)

(chi tiết:

  • IP vào góc dưới bên trái, hướng sang trái
  • Nó bị vênh sang góc phải, vẫn hướng sang trái
  • Nó gặp một \cái mà phản ánh nó, bây giờ nó đi thẳng lên
  • Nó đi vào góc và bị vênh một lần nữa vào góc dưới bên trái

)


Nếu giá trị (của thao tác mod 2 ở trên) là sai (không), thì chúng ta theo đường dẫn này:

# Python                 # Hexagony   # Memory visualization after execution
b = mem // a             # :          # click here
base = ord('a') # 97     # a
y = b % base             # '%
offset = 33              # P1
z = y + offset           # ='+
stdout.write(chr(z))     # ;          # click here
mem = b // base          # {:         # click here

Tôi sẽ không giải thích quá chi tiết ở đây, nhưng phần bù thực sự không chính xác 33, nhưng phù hợp với 33mod 256. Và chrcó một ẩn ý % 256.


3
Man, đó là rất nhiều no-ops
Jo King

26
Tôi cười "Để hiểu những gì tôi đang nói, chúng ta hãy có một sự tương tự [BrainFuck]." Chỉ có trên PPCG ... :)
Lynn

2
Tôi đã cuộn 3 lần lên đầu câu trả lời để nâng cấp nó, chỉ để biết rằng tôi đã làm điều đó ...
NieDzejkob

2
310 byte bằng cách tận dụng không gian mới từ việc rút ngắn số
Jo King

2
308 byte bằng cách lấy thêm dung lượng
Jo King

46

Vim, 11 byte

q"iq"qP<Esc>hqP
  • iq"qP<Esc>: Chèn thủ công một bản sao của văn bản phải nằm ngoài bản ghi.
  • q"hqP: Ghi trực tiếp bên trong vào ""thanh ghi không tên , để nó có thể được dán ở giữa. Đây hlà sự tái định vị duy nhất cần thiết; nếu bạn đặt nó bên trong macro, nó sẽ được dán vào kết quả.

Biên tập

Một lưu ý về ghi âm với q": Thanh ghi không tên ""là một điều buồn cười. Nó không thực sự là một đăng ký thực sự như những người khác, vì văn bản không được lưu trữ ở đó. Nó thực sự là một con trỏ đến một số thanh ghi khác (thường là "-để xóa không có dòng mới, "0cho yanks hoặc "1để xóa với một dòng mới). q"phá vỡ các quy tắc; nó thực sự viết cho "0. Nếu bạn ""đã trỏ đến một số đăng ký khác "0, q"sẽ ghi đè "0nhưng ""không thay đổi. Khi bạn bắt đầu một Vim mới, ""tự động trỏ đến "0, vì vậy bạn sẽ ổn trong trường hợp đó.

Về cơ bản, Vim là lạ và lỗi.


chờ đợi tại sao điều này không làm việc cho tôi
Lemon phá hủy

@DeststallibleWateriwi Không thể nói chắc chắn, nhưng rất có thể một lời giải thích. Có lẽ nên có nó trong bài viết trước, vì nó có thể ném mọi người đi. Đọc bản chỉnh sửa.
udioica

bạn có lẽ nên đặt một cái gì đó về cách nhấn yhoặc một cái gì đó trước khi chạy có thể giúp đỡ
Lemon

Tại sao bạn không sử dụng để hiển thị nhấn phím <Esc>? Một phần của khối Unicode điều khiển hình ảnh Unicode
mbomb007

4
@ mbomb007 <Esc>Ký hiệu là tiêu chuẩn trong ánh xạ Vim ( :help <>) và đó là những gì vimgolf.com sử dụng. Bất kỳ vimgolfer có kinh nghiệm sẽ được sử dụng để đọc nó. Đối với unicode, tôi phải nheo mắt để đọc các chữ cái nhỏ, và chúng che khuất phương pháp gõ chúng và tìm kiếm tệp trợ giúp.
udioica

44

Khối , 20 byte

3434Qu$v@!<"OOw\o;/"

Gần như có \o/ ...

Mạng :

    3 4
    3 4
Q u $ v @ ! < "
O O w \ o ; / "
    . .
    . .

Dùng thử trực tuyến

Hãy thử nó ở đây !

Ghi chú bổ sung

Bối cảnh câu chuyện

Sau khi bị ấn tượng khi đọc câu trả lời tuyệt vời này của @ ais523, tôi bắt đầu suy nghĩ về việc chơi gôn. Rốt cuộc, có khá nhiều no-op trong đó, và điều đó không cảm thấy rất nén. Tuy nhiên, như kỹ thuật mà câu trả lời của anh ấy (cũng như của tôi) sử dụng, đòi hỏi mã phải trải dài toàn dòng, cần tiết kiệm ít nhất 12 byte. Có một nhận xét trong lời giải thích của anh ấy thực sự khiến tôi suy nghĩ:

Về chủ đề chơi gôn xuống câu hỏi này, [...] nó cần [...] một số cách khác để thể hiện mặt trên của khối [...]

Rồi đột nhiên, khi tôi đứng dậy và bước đi để lấy thứ gì đó để uống, tôi chợt nhận ra: Sẽ thế nào nếu chương trình không sử dụng mã ký tự, mà là những con số để thể hiện khuôn mặt trên cùng? Điều này đặc biệt ngắn nếu số chúng tôi đang in có 2 chữ số. Cubix có 3 hướng dẫn một byte cho đẩy số hai con số: N, SQ, trong đó đẩy 10, 3234tương ứng, vì vậy đây nên được khá golfy, tôi nghĩ.

Điều phức tạp đầu tiên với ý tưởng này là khuôn mặt trên hiện đang chứa đầy những con số vô dụng, vì vậy chúng ta không thể sử dụng nó nữa. Biến chứng thứ hai là mặt trên có kích thước là bình phương kích thước khối vuông và nó cần phải có kích thước chẵn, nếu không, một số cũng sẽ nằm ở vị trí bắt đầu của con trỏ lệnh, dẫn đến ngăn xếp bị ô nhiễm. Do những sự phức tạp này, mã của tôi cần phải phù hợp với một khối có kích thước 2 (có thể chứa 'chỉ' 24 byte, vì vậy tôi đã phải đánh gôn ít nhất 21 byte). Ngoài ra, vì các mặt trên và dưới không thể sử dụng được, tôi chỉ có 16 byte hiệu quả.

Vì vậy, tôi bắt đầu bằng cách chọn số sẽ trở thành một nửa của khuôn mặt hàng đầu. Tôi đã bắt đầu với N(10), nhưng điều đó không hoàn toàn hiệu quả vì cách tiếp cận tôi đang thực hiện để in mọi thứ. Dù bằng cách nào, tôi bắt đầu lại và sử dụng S(32) vì một số lý do. Điều đó đã dẫn đến một câu hỏi thích hợp, hoặc tôi nghĩ vậy. Tất cả đều hoạt động rất tốt, nhưng các trích dẫn bị thiếu. Sau đó, tôi nhận ra rằng Q(34) sẽ thực sự hữu ích. Xét cho cùng, 34 là mã ký tự của trích dẫn kép, cho phép chúng tôi giữ nó trên ngăn xếp, lưu (2, trong bố cục tôi đã sử dụng sau đó) các byte quý giá. Sau khi tôi thay đổi tuyến IP một chút, tất cả những gì còn lại chỉ là một đoạn trích để điền vào chỗ trống.

Làm thế nào nó hoạt động

Mã có thể được chia thành 5 phần. Tôi sẽ đi qua từng người một. Lưu ý rằng chúng tôi đang mã hóa các mặt giữa theo thứ tự ngược lại vì mô hình ngăn xếp là từ đầu đến cuối.

Bước 1: In mặt trên

Các hướng dẫn không liên quan đã được thay thế bằng no-ops ( .). IP bắt đầu dòng thứ ba, ở bên trái, chỉ về hướng đông. Các ngăn xếp (rõ ràng) là trống rỗng.

    . .
    . .
Q u . . . . . .
O O . . . . . .
    . .
    . .

IP kết thúc ở vị trí ngoài cùng bên trái trên dòng thứ tư, chỉ về phía tây, sắp quấn quanh vị trí ngoài cùng bên phải trên cùng dòng đó. Các hướng dẫn được thực hiện là (không có ký tự luồng điều khiển):

QOO
Q   # Push 34 (double quotes) to the stack
 OO # Output twice as number (the top face)

Ngăn xếp chỉ chứa 34, đại diện cho ký tự cuối cùng của nguồn.

Bước 2: Mã hóa dòng thứ tư

Điều này khá nhiều làm những gì bạn mong đợi nó làm: mã hóa dòng thứ tư. IP bắt đầu trên dấu ngoặc kép ở cuối dòng đó và đi về phía tây trong khi đẩy mã ký tự của mỗi ký tự mà nó tiếp tục cho đến khi tìm thấy dấu ngoặc kép phù hợp. Dấu ngoặc kép phù hợp này cũng là ký tự cuối cùng trên dòng thứ tư, bởi vì IP kết thúc một lần nữa khi nó đạt đến cạnh trái.

Thực tế, IP đã di chuyển một vị trí sang bên trái và ngăn xếp hiện chứa biểu diễn của dòng thứ tư theo mã ký tự và thứ tự ngược lại.

Bước 3: Đẩy báo giá khác

Chúng ta cần đẩy một trích dẫn khác, và cách nào tốt hơn là tái chế Qphần đầu của chương trình bằng cách tiếp cận nó từ bên phải? Điều này có thêm phần thưởng mà IP trực tiếp chạy vào trích dẫn mã hóa dòng thứ ba.

Đây là phiên bản mạng cho bước này. Các xâm nhập không liên quan đã được thay thế bằng no-op một lần nữa, các no-op được thực thi đã được thay thế bằng hashtags ( #) cho mục đích minh họa và IP bắt đầu ở ký tự cuối cùng trên dòng thứ tư.

    . .
    . .
Q u $ . . . . .
. . w \ . . / .
    . #
    . #

IP kết thúc ở dòng thứ ba ở hướng dẫn đầu tiên, sắp kết thúc ở cuối dòng đó vì nó chỉ về hướng tây. Các hướng dẫn sau (không bao gồm luồng điều khiển) được thực hiện:

$uQ
$u  # Don't do anthing
  Q # Push the double quote

Trích dẫn kép này đại diện cho một ở cuối dòng thứ ba.

Bước 4: Mã hóa dòng thứ ba

Điều này hoạt động chính xác như bước 2, vì vậy hãy xem đó để được giải thích.

Bước 5: In ngăn xếp

Bây giờ ngăn xếp chứa các dòng thứ tư và thứ ba, theo thứ tự ngược lại, vì vậy tất cả những gì chúng ta cần làm bây giờ, nó in nó. IP bắt đầu từ hướng dẫn áp chót trên dòng thứ ba, di chuyển về phía tây. Đây là phần có liên quan của khối lập phương (một lần nữa, các phần không liên quan đã được thay thế bằng no-op).

    . .
    . .
. . . v @ ! < .
. . . \ o ; / .
    . .
    . .

Đây là một vòng lặp, như bạn có thể đã thấy / mong đợi. Cơ thể chính là:

o;
o  # Print top of stack as character
 ; # Delete top of stack

Vòng lặp kết thúc nếu mục trên cùng là 0, chỉ xảy ra khi ngăn xếp trống. Nếu vòng lặp kết thúc, @được thực hiện, kết thúc chương trình.


ước gì tôi có thể nâng cao điều này hơn nữa
MickyT

Tiền thưởng luôn được chào đón ;-)
Luke

42

Javascript ES6 - 21 byte

$=_=>`$=${$};$()`;$()

Tôi gọi quine này là "The Bling Quine."

Đôi khi, bạn phải chơi golf theo phong cách.


Bạn có !$=_=>`!$=${$}()`()tiết kiệm được 2 byte không?
Hạ cấp

Invalid assignment left hand side. Chúc nó hoạt động :(
Mama Fun Roll

1
@ TùxCräftîñg loại bỏ dấu ngoặc đơn quanh các mẫu chữ chỉ hoạt động trên các hàm nguyên mẫu gốc, như Array.prototype.join.
Mama Fun Roll

2
Hmm, không chắc chắn. Tôi đã viết điều này hơn một năm trước (sau đó nó được coi là hợp lệ) và tôi đã không tuân theo các thay đổi quy tắc quine quá chặt chẽ. Tuy nhiên, việc thêm alerthoặc console.logsau hàm mũi tên và gói chuỗi mẫu trong ngoặc đơn sẽ hoạt động.
Mama Fun Roll

3
Ngoài ra nếu bạn chạy cái này trong concole, nó sẽ ghi đè $ (hàm jQuery) trên trang web này và hàm upvote sẽ không hoạt động nữa. :)
Steven Palinkas

41

Brainf * ck (755 ký tự)

Điều này dựa trên một kỹ thuật được phát triển bởi Erik Bosman (ejbosman tại cs.vu.nl). Lưu ý rằng "ESultanik's Quine!" văn bản là thực sự cần thiết cho nó là một quine!

->++>+++>+>+>++>>+>+>+++>>+>+>++>+++>+++>+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>+>++>>>+++>>>>>+++>+>>>>>>>>>>>>>>>>>>>>>>+++>>>>>>>++>+++>+++>+>>+++>>>+++>+>+++>+>++>+++>>>+>+>+>+>++>+++>+>+>>+++>>>>>>>+>+>>>+>+>++>+++>+++>+>>+++>+++>+>+++>+>++>+++>++>>+>+>++>+++>+>+>>+++>>>+++>+>>>++>+++>+++>+>>+++>>>+++>+>+++>+>>+++>>+++>>>+++++++++++++++>+++++++++++++>++++++>+++++++++++++++>++++++++++>+++>+++>++++>++++++++++++++>+++>++++++++++>++++>++++++>++>+++++>+++++++++++++++>++++++++>++++>++++++++++++>+++++++++++++++>>++++>++++++++++++++>+++>+++>++++>++++++>+++>+++++++++>++++>+>++++>++++++++++>++++>++++++++>++>++++++++++>+>+++++++++++++++>+++++++++++++
ESultanik's Quine!
+[[>>+[>]+>+[<]<-]>>[>]<+<+++[<]<<+]>>+[>]+++[++++++++++>++[-<++++++++++++++++>]<.<-<]

13
Đó là một cách thông minh để làm điều đó.
Peter Olson

13
Làm thế nào nó hoạt động?
tự hào

3
@proudhaskeller IIRC, phần trước khi ESultanik's Quine!thiết lập bộ nhớ dưới dạng mã hóa ngăn xếp ESultanik's Quine!và trở đi, với hai byte bộ nhớ cho mỗi ký tự (giá trị ASCII bù từ 0x1F). Bit cuối cùng của các vòng lặp mã thông qua bộ nhớ, đầu tiên lập trình lại ++>+++…mã cho mỗi ký tự, sau đó thực sự in các ký tự.
ESultanik

4
@CatsAreFluffy Họ được yêu cầu phải là một quine! Mặc dù đúng là chúng có thể bị xóa, người ta cũng sẽ phải thay đổi mã trước đó để duy trì thuộc tính quine.
ESultanik

1
Đúng. Ngoài ra các dòng mới là cần thiết.
Máy

36

Hình lục giác , chiều dài cạnh 15 14 13 12, 616 533 456 383 byte

Sau nhiều ngày chơi golf cẩn thận, sắp xếp lại các vòng lặp và bắt đầu lại, cuối cùng tôi cũng đã xoay sở để đưa nó xuống một hình lục giác 12 cạnh.

1845711724004994017660745324800783542810548755533855003470320302321248615173041097895645488030498537186418612923408209003405383437728326777573965676397524751468186829816614632962096935858"">./<$;-<.....>,.........==.........<"......."">'....>+'\.>.........==........<"......"">:>)<$=<..>..............$..<"...."">\'Q4;="/@>...............<"....."">P='%<.>.............<"..!'<.\=6,'/>

Hãy thử trực tuyến!

Mở ra:

            1 8 4 5 7 1 1 7 2 4 0 0
           4 9 9 4 0 1 7 6 6 0 7 4 5
          3 2 4 8 0 0 7 8 3 5 4 2 8 1
         0 5 4 8 7 5 5 5 3 3 8 5 5 0 0
        3 4 7 0 3 2 0 3 0 2 3 2 1 2 4 8
       6 1 5 1 7 3 0 4 1 0 9 7 8 9 5 6 4
      5 4 8 8 0 3 0 4 9 8 5 3 7 1 8 6 4 1
     8 6 1 2 9 2 3 4 0 8 2 0 9 0 0 3 4 0 5
    3 8 3 4 3 7 7 2 8 3 2 6 7 7 7 5 7 3 9 6
   5 6 7 6 3 9 7 5 2 4 7 5 1 4 6 8 1 8 6 8 2
  9 8 1 6 6 1 4 6 3 2 9 6 2 0 9 6 9 3 5 8 5 8
 " " > . / < $ ; - < . . . . . > , . . . . . .
  . . . = = . . . . . . . . . < " . . . . . .
   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .
      . . . . . . . . . $ . . < " . . . .
       " " > \ ' Q 4 ; = " / @ > . . . .
        . . . . . . . . . . . < " . . .
         . . " " > P = ' % < . > . . .
          . . . . . . . . . . < " . .
           ! ' < . \ = 6 , ' / > . .
            . . . . . . . . . . . .

Mặc dù nó không giống như mã Hexagony được chơi nhiều nhất, loại mã hóa tôi đã sử dụng được tối ưu hóa cho các lần chạy không hoạt động lâu hơn, đây là điều bạn thường tránh.

Giải trình

Điều này đánh bại câu trả lời Hexagony trước đó bằng cách mã hóa no-ops ( .) theo một cách khác. Trong khi câu trả lời đó tiết kiệm không gian bằng cách biến mọi ký tự khác thành a ., thì tôi mã hóa số lượng no-op. Điều đó cũng có nghĩa là nguồn không cần phải bị hạn chế.

Ở đây tôi sử dụng mã hóa cơ sở 80, trong đó các số dưới 16 biểu thị các lần chạy không hoạt động và các số từ 16 đến 79 đại diện cho phạm vi 32 ( !) đến 95 ( _) (Bây giờ tôi mới nhận ra rằng tôi đã chơi hết _mình mã lol). Một số mã giả Pythonic:

i = absurdly long number
print(i)
base = 80
n = i%base
while n:
    if n < 16:
        print("."*(16-n))
    else:
        print(ASCII(n+16))
    i = i//base
    n = i%base

Số được mã hóa trong nửa đầu của hình lục giác, với tất cả

" " > 
 " " > 
  ... etc

ở phía bên trái và

 > ,
< "
 >
< "
... etc

ở bên phải chuyển hướng con trỏ để mã hóa số vào một ô. Điều này được lấy từ câu trả lời của Martin Ender (cảm ơn), vì tôi không thể tìm ra cách nào hiệu quả hơn.

Sau đó, nó đi vào phần dưới cùng thông qua ->:

       " " > \ ' Q 4 ; = " / @ > . . . .
        . . . . . . . . . . . < " . . .
         . . " " > P = ' % < . > . . .
          . . . . . . . . . . < " . .
     ->    ! ' < . \ = 6 , ' / > . .

!in số và 'điều hướng đến ô nhớ bên phải trước khi bắt đầu vòng lặp. P='%sửa đổi số hiện tại bằng 80. Nếu kết quả là 0, đi đến kết thúc @, người khác đi xuống và tạo một ô bên cạnh kết quả mod với giá trị -16.

   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .
      . . . . . . . . . $ . . < " . . . .
       " " > \ ' Q 4 ; = " / @ > . . . .
                      /
                     /

Đặt ô thành (giá trị mod + -16). Nếu giá trị đó là âm, đi lên tại nhánh >+'\, nếu không đi xuống.

Nếu giá trị là dương:

 " " > . / < $ ; - < . . . . . > , . . . . . .
  . . . = = . . . . . . . . . < " . . . . . .
   . " " > ' . . . . > + ' \ . > . . . . . .

Con trỏ kết thúc tại ;-<đó đặt ô thành (giá trị mod - -16) và in nó.

Giá trị là âm:

   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .

Đi xuống > ) <phần bắt đầu vòng lặp. Ở đây nó bị cô lập:

     . . > ) < $ = < . .
      . . . . . . . . .
       \ ' Q 4 ; = " /

'Q4;="=này thực thi mã in ra .(một lần nữa cảm ơn Martin Ender, người đã viết một chương trình để tìm các tổ hợp số chữ cái cho các ký tự) và quay trở lại ô bắt đầu. Sau đó, nó tăng ( )) ô giá trị mod và lặp lại, cho đến khi giá trị mod dương.

Khi xong, nó di chuyển lên và tham gia với phần khác tại:

 " " > . / < $ ; - < . . .
            \
             \

Sau đó, con trỏ quay trở lại điểm bắt đầu của vòng lặp lớn hơn

 " " > . / <--
  . . . = =
   . " " > ' 
    . . . = = 
     . " " > :
      . . . . .
       " " > \ ' . .
        . . . . . . .
         . . " " > P = ' % < . > . . .

Điều này thực hiện ='=:'mà chia số hiện tại cho 80 và điều hướng đến ô chính xác.

Phiên bản cũ (Chiều dài bên 13)

343492224739614249922260393321622160373961419962223434213460086222642247615159528192623434203460066247203920342162343419346017616112622045226041621962343418346002622192616220391962343417346001406218603959366061583947623434"">/':=<$;'<.....>(......................<"......"">....'...>=\..>.....................<"....."">....>)<.-...>...........==......<"...."">.."...'.../>.................<"..."">\Q4;3=/.@.>...............<".."".>c)='%<..>..!'<.\1*='/.\""

Hãy thử trực tuyến!

Tôi chắc chắn có thể chơi golf ở một khía cạnh khác, nhưng tôi sẽ phải rời khỏi nó vào ngày mai vì đã muộn. Hóa ra tôi thiếu kiên nhẫn và không thể đợi đến ngày mai. Có lẽ một mặt khác có thể được chơi golf? :( ahhhhhhhhh tôi đã làm điều đó!

Tôi thậm chí đã bỏ qua một vài chữ số phụ với mã hóa cơ sở 77, nhưng nó không thực sự quan trọng, vì nó có cùng một số tiền.


13
Thật đáng kinh ngạc. Ý tưởng cho mã hóa độ dài chạy lai này thực sự gọn gàng. :) Nhắc tôi cho bạn một tiền thưởng nếu tôi quên.
Martin Ender

35

PostScript, 20 ký tự

Ngắn gọn và hợp pháp. 20 ký tự bao gồm cả dòng mới.

(dup == =)
dup == =

33

Khối , 45 byte

.....>...R$R....W..^".<R.!'.\)!'"R@>>o;?/o'u"

Bạn có thể kiểm tra mã này ở đây .

Chương trình này khá khó để theo dõi, nhưng để có cơ hội thực hiện, chúng ta cần bắt đầu bằng cách mở rộng nó thành một khối, giống như trình thông dịch của Cubix:

      . . .
      . . >
      . . .
R $ R . . . . W . . ^ "
. < R . ! ' . \ ) ! ' "
R @ > > o ; ? / o ' u "
      . . .
      . . .
      . . .

Đây là một quine kiểu Befunge, hoạt động thông qua khai thác gói để tạo ra chuỗi ký tự "bao quanh" mã thực thi (chỉ với một "dấu, mã ở cả bên trong và bên ngoài trích dẫn cùng một lúc, điều gì đó có thể xảy ra khi bạn có các chương trình là phi tuyến và phi kế hoạch). Lưu ý rằng điều này phù hợp với định nghĩa của chúng tôi về một câu hỏi thích hợp, bởi vì hai trong số các trích dẫn kép không tự mã hóa mà thay vào đó được tính toán sau khi sử dụng số học.

Tuy nhiên, không giống như Befunge, chúng tôi đang sử dụng bốn chuỗi ở đây, thay vì một chuỗi. Đây là cách họ được đẩy lên ngăn xếp;

  1. Chương trình bắt đầu ở trên cùng của cạnh trái, đi sang phải; nó rẽ phải hai lần ( R), làm cho nó đi sang trái dọc theo phần thứ ba và cuối cùng của dòng bao quanh toàn bộ khối. Báo giá kép khớp với chính nó, vì vậy chúng tôi đẩy toàn bộ dòng thứ ba lên ngăn xếp về phía sau. Sau đó thực hiện tiếp tục sau khi trích dẫn kép.

  2. Các ulệnh thực hiện một U-turn sang bên phải, do đó, điều tiếp theo chúng tôi đang chạy là từ '"trở đi trên dòng trung lưu. Điều đó đẩy một "lên ngăn xếp. Tiếp tục quấn quanh, chúng tôi đánh vào <phía bên trái của khối lập phương và bật lại. Khi tiếp cận từ hướng này, chúng ta thấy một "lệnh đơn giản , không phải '"vậy, vì vậy toàn bộ dòng thứ hai được đẩy lên ngăn xếp ngược lên trên dòng thứ ba và trích dẫn kép.

  3. Chúng tôi bắt đầu bằng cách đẩy a !lên stack ( '!) và tăng nó ( )); điều này tạo ra một trích dẫn kép mà không cần trích dẫn kép trong mã nguồn của chúng tôi (sẽ chấm dứt chuỗi). Một tấm gương ( \) phản ánh hướng thực hiện lên phía bắc; sau đó Wlệnh sidesteps sang trái. Điều này khiến chúng ta đi lên trên cột thứ bảy, bởi vì đây là một khối lập phương, kết thúc sang trái trên hàng thứ ba, sau đó đi xuống trên cột thứ ba. Chúng tôi nhấn một R, để rẽ phải và đi sang trái dọc theo hàng trên cùng; sau đó $bỏ Rqua thông qua đó chúng tôi đã nhập chương trình, do đó, thực thi kết thúc vòng đến "cuối dòng và chúng tôi bắt được dòng đầu tiên trong một chuỗi giống như cách chúng tôi đã làm cho lần thứ hai và thứ ba.

  4. Các ^lệnh sai chúng ta về phía bắc lên cột thứ mười một, đó là (cho phép khối gói) về phía nam vào thứ năm. Điều duy nhất chúng ta gặp phải là !(bỏ qua nếu khác không; đỉnh của ngăn xếp thực sự là khác không), bỏ qua olệnh, làm cho cột thứ năm hoàn toàn trống rỗng. Vì vậy, chúng tôi quay trở lại ulệnh, một lần nữa quay đầu, nhưng lần này chúng tôi rời khỏi cột cuối cùng về phía nam, nó kết thúc với cột thứ tư về phía bắc. Tuy nhiên, chúng tôi đã đạt được một trích dẫn kép trong lượt U, vì vậy chúng tôi chụp toàn bộ cột thứ tư trong một chuỗi, từ dưới lên trên. Không giống như hầu hết các trích dẫn kép trong chương trình, cái này không tự đóng; đúng hơn, nó được đóng "ở góc trên bên phải, nghĩa là chúng ta chụp chuỗi chín ký tự ...>......

Vì vậy, bố trí ngăn xếp bây giờ, từ trên xuống dưới: cột thứ tư; hàng đầu; "; hàng giữa; "; hàng dưới cùng. Mỗi trong số này được biểu diễn trên ngăn xếp với ký tự đầu tiên gần đỉnh ngăn xếp nhất (Cubix đẩy các chuỗi theo thứ tự ngược lại, giống như Befunge, nhưng mỗi lần IP di chuyển theo hướng ngược lại với hướng đọc tự nhiên, vì vậy nó có hiệu quả đã đảo ngược hai lần). Có thể lưu ý rằng nội dung ngăn xếp gần giống với chương trình ban đầu (vì cột thứ tư và mặt phía bắc / trên cùng của khối, chứa các ký tự giống nhau theo cùng một thứ tự; rõ ràng, nó được thiết kế như vậy một cách có chủ ý).

Bước tiếp theo là in nội dung của ngăn xếp. Sau tất cả các lần đẩy, IP sẽ đi về phía bắc trên cột thứ tư, do đó, nó chạm vào >đó và đi vào một vòng lặp chặt chẽ >>o;?(tức là "quay về hướng đông, quay về hướng đông, xuất ra dưới dạng ký tự, bật, rẽ phải nếu dương"). Bởi vì dòng thứ bảy chứa đầy NOP, nên ?nó sẽ quay trở lại dòng đầu tiên >, do đó, điều này sẽ đẩy toàn bộ nội dung của ngăn xếp ?một cách hiệu quả ( là một no-op trên một ngăn xếp trống). Chúng tôi gần như in toàn bộ chương trình! Thật không may, nó chưa hoàn thành chúng tôi đang thiếu trích dẫn kép ở cuối.

Khi vòng lặp kết thúc, chúng tôi phản chiếu lên đường trung tâm, di chuyển về phía tây, thông qua một cặp gương. (Chúng tôi đã sử dụng "mặt khác" của \gương trước đó; bây giờ chúng tôi đang sử dụng phía tây nam. /Gương trước đây chưa được sử dụng.) Chúng tôi gặp phải '!, vì vậy chúng tôi đẩy một dấu chấm than (ví dụ 33; chúng tôi đang sử dụng ASCII và Cubix không phân biệt giữa số nguyên và ký tự) trên ngăn xếp. (Thuận tiện, đây là cái tương tự !được sử dụng để bỏ qua olệnh trước đó.) Chúng tôi bắt gặp một cặp Rlệnh và sử dụng chúng để thực hiện quay đầu "thủ công" ( Rlệnh thứ hai ở đây đã được sử dụng trước đó để đạt được lệnh đầu tiên hàng, vì vậy có vẻ tự nhiên nhất để phù hợp với một Rlệnh khác cùng với nó.Wlệnh, để sidestep sang trái. Các sidestep đâm thẳng vào >lệnh trên dòng thứ hai, đưa thực thi trở lại chính xác vị trí của nó. Vì vậy, chúng tôi đi sang bên trái một lần nữa, nhưng lần này chúng tôi sẽ đi về phía nam, vì vậy lệnh tiếp theo để thực hiện là )(tăng dấu chấm than thành một trích dẫn kép), theo sau là o(để xuất ra nó). Cuối cùng, thực thi kết thúc dọc theo dòng thứ tám đến cột thứ hai, nơi nó tìm thấy một @để thoát khỏi chương trình.

Tôi xin lỗi vì dấu nháy đơn đi lạc trên dòng thứ ba. Nó không làm gì trong phiên bản này của chương trình; đó là một phần của một ý tưởng trước đây tôi có nhưng hóa ra không cần thiết. Tuy nhiên, một khi tôi đã có một câu hỏi hoạt động, tôi chỉ muốn gửi nó chứ không phải loay hoay với nó hơn nữa, đặc biệt là khi xóa nó sẽ không thay đổi số byte. Về chủ đề chơi gôn này, tôi sẽ không ngạc nhiên nếu điều này có thể xảy ra ở 3 × 3 chỉ bằng cách sử dụng năm dòng đầu tiên, nhưng tôi không thể thấy một cách rõ ràng để làm điều đó, và nó cần thậm chí đóng gói chặt chẽ hơn tất cả các luồng điều khiển cùng với một số cách khác để biểu diễn mặt trên của khối lập phương (hoặc cách khác là sửa đổi thuật toán để nó có thể tiếp tục sử dụng cột thứ tư mặc dù bây giờ nó dài mười hoặc mười một ký tự) .


Công việc tốt, đây là một điểm thực sự ấn tượng. Tôi thích cách bạn mã hóa khuôn mặt hàng đầu. :)
Martin Ender

Điều này thật khó tin! Nếu nó sẽ giúp bất kỳ, một cách khác để đẩy "Q.
Sản xuất ETH

1
Ồ Tôi chưa bao giờ mặc dù tôi thấy một khối vuông
FlipTack

3
Tôi đã không có thời gian để đọc lời giải thích ngày hôm qua, nhưng bây giờ tôi có ... Chỉ là ... WOW. Tôi không thể tin có bao nhiêu nhân vật được sử dụng cho hai hoặc thậm chí ba mục đích hoàn toàn khác nhau. Đây có lẽ là chương trình Cubix thú vị nhất tôi từng thấy.
Sản xuất ETH

Lời giải thích hay.
Robert Fraser

33

Python 2, 30 byte

_='_=%r;print _%%_';print _%_

Lấy từ đây


1
+1, bạn đánh bại giải pháp tương tự của tôi vì vậy tôi đã xóa nó. Cần lưu ý rằng điều này chỉ hoạt động trong Python 2.
nyuszika7h

2
Nó trông lạ với tên biến là _, nhưng đọc tốt hơn nếu bạn gán nó cho bất kỳ chữ cái nào, tức là s:s='s=%r;print s%%s';print s%s
Ehtesh Choudhury

5
Nếu giải pháp này không phải là sáng tạo của riêng bạn, bạn nên tạo Cộng đồng Wiki. Ngoài ra, liên kết là chết.
mbomb007

1
Tôi đến bữa tiệc hơi muộn, nhưng ai đó có thể giải thích cách thức hoạt động của nó không?
MadTux

9
Điều này đòi hỏi một linefeed trailing là hợp lệ. Vì nó là, mã nguồn không khớp với đầu ra.
Dennis

32

Vim, 17 , 14 tổ hợp phím

Ai đó đã ngẫu nhiên nêu lên điều này, vì vậy tôi nhớ rằng nó tồn tại. Khi tôi đọc lại, tôi đã nghĩ "Này, tôi có thể làm tốt hơn thế!", Vì vậy tôi đã đánh gôn hai byte. Nó vẫn không phải là ngắn nhất, nhưng ít nhất đó là một cải tiến.


Trong một thời gian dài, tôi đã tự hỏi nếu một vim quine là có thể. Một mặt, nó phải có thể, vì vim đã hoàn thành. Nhưng sau khi tìm kiếm một vim quine trong một thời gian thực sự dài, tôi đã không thể tìm thấy một. Tôi đã tìm thấy thử thách PPCG này , nhưng nó đã đóng và không chính xác về các nghĩa đen. Vì vậy, tôi quyết định làm một, vì tôi không thể tìm thấy một.

Tôi thực sự tự hào về câu trả lời này, vì hai lần đầu tiên :

  1. Đây là câu chuyện đầu tiên tôi từng làm, và

  2. Theo tôi biết, đây là vim-quine đầu tiên trên thế giới được xuất bản! Tôi có thể sai về điều này, vì vậy nếu bạn biết về một người, xin vui lòng cho tôi biết.

Vì vậy, sau phần giới thiệu dài đó, đây là:

qqX"qpAq@q<esc>q@q

Hãy thử trực tuyến!

Lưu ý rằng khi bạn gõ nó ra, nó sẽ hiển thị <esc>tổ hợp phím như ^[. Điều này vẫn chính xác, vì ^[đại diện 0x1B, là lối thoát trong ASCII và cách vim thể hiện bên trong <esc>khóa.

Cũng lưu ý rằng việc kiểm tra này có thể thất bại nếu bạn tải một phiên vim hiện có. Tôi đã viết một câu trả lời giải thích rằng ở đây , nếu bạn muốn biết thêm thông tin, nhưng về cơ bản, bạn cần khởi chạy vim với

vim -u NONE -N -i NONE

hoặcqqqtrước khi chạy này.

Giải trình:

qq                  " Start recording into register 'q'
  X                 " Delete one character before the cursor (Once we play this back, it will delete the '@')
   "qp              " Paste register 'q'
      Aq@q<esc>     " Append 'q@q' to this line
               q    " Stop recording
                @q  " Playback register 'q'

Bên cạnh đó, câu trả lời này có lẽ là một kỷ lục thế giới đối với hầu hết 'q trong câu trả lời PPCG, hoặc một cái gì đó.


1
2i2i<esc>rất gần Tôi cảm thấy như phải có một cái gì đó tôi có thể làm để làm cho công việc này.
Zwei

@zwei Tôi biết, nó đóng rất đau! Trên thực tế, <Esc>là ẩn trong V, vì vậy mà hoạt động . Thật không may, nó cũng thêm một dòng mới, đó là lý do tại sao tôi chưa đăng nó.
DJMcMayhem

q"iq"qbP<Esc>qbPlà 11. Sau khi bạn đặt cái này lên reddit , tôi đã điều tra vimgolfing ở đây và quyết định tạo một tài khoản. Đây là câu trả lời tôi đã đăng ở đó.
udioica

2
@udioica Bạn có thể đăng nó như một câu trả lời không?
DJMcMayhem

28

Mất , 120 116 98 96 76 70 66 byte

Chỉnh sửa: yay, dưới 100

Chỉnh sửa: Đã lưu một bó o 'byte bằng cách chuyển sang tất cả /các dòng trên dòng dưới cùng

:2+52*95*2+>::1?:[:[[[[@^%?>([ "
////////////////////////////////

Hãy thử trực tuyến! + xác minh nó mang tính quyết định cho tất cả các trạng thái có thể

Mất là một ngôn ngữ 2D trong đó vị trí và hướng bắt đầu là hoàn toàn ngẫu nhiên. Điều này có nghĩa là phải có rất nhiều kiểm tra lỗi ở mọi giai đoạn để đảm bảo bạn đã có con trỏ chỉ dẫn chính xác và đó không phải là con trỏ vừa mới đi lang thang một cách ngẫu nhiên.

Giải trình:

Tất cả các /s ở dòng dưới cùng đều ở đó để đảm bảo rằng tất cả các con trỏ sinh ra theo hướng thẳng đứng hoặc trên dòng dưới cùng được chuyển sang đúng hướng. Từ đó, họ kết thúc ở một vài nơi khác nhau, nhưng tất cả họ đều đi thẳng vào

 ^%?>
 ////

Mà xóa tất cả các số khác không trong ngăn xếp. Các ([sau đó gạt bỏ bất kỳ 0s thêm là tốt.

Ở giữa rõ ràng, nó chạm vào %, tắt 'an toàn', cho phép chương trình kết thúc khi chạm vào @(nếu không có điều này, chương trình có thể kết thúc ngay lập tức nếu một con trỏ bắt đầu tại @).

Từ đó, nó thực hiện một ngôn ngữ 2D khá đơn giản, bằng cách gói một chuỗi ký tự ( ") xung quanh dòng đầu tiên, đẩy một "ký tự bằng cách nhân một khoảng trắng ( :2+) và sau đó là một dòng mới ( 52*). Đối với dòng thứ hai, nó tạo ra một /ký tự ( 95*2+) và sao chép nó thành một bó ( >::1?:[:[[[[), trước khi cuối cùng kết thúc tại @và in ngăn xếp ngầm. Điều ?1này là để ngăn quá trình tạo quá nhiều 0 nếu con trỏ vào sớm, tiết kiệm được việc phải xóa chúng sau.

Tôi đã lưu 20 byte ở đây bằng cách tạo dòng cuối cùng tất cả cùng một ký tự, nghĩa là tôi có thể đi thẳng từ quá trình sao chép vào kết thúc @.

Giải thích về quy trình nhân đôi:

[là một nhân vật được gọi là "Cánh cửa". Nếu con trỏ chạm vào mặt phẳng của a [hoặc a ], nó phản xạ, nếu không nó sẽ đi qua nó. Mỗi lần con trỏ tương tác với Cửa, nó sẽ chuyển sang loại đối diện. Sử dụng kiến ​​thức này, chúng ta có thể xây dựng một công thức đơn giản cho số lần một lệnh sẽ thực thi trong một >:[khối.

Thêm số lượng hướng dẫn ban đầu. Đối với mỗi [, thêm 2 lần số lượng hướng dẫn ở bên trái của nó. Ví dụ >::::[:[[[, chúng tôi bắt đầu với 5 là số tiền ban đầu. Cửa thứ nhất có 4 hướng dẫn song công, vì vậy chúng tôi thêm 4 * 2 = 8 đến 5 để nhận 13. Ba Cửa còn lại có 5 bản sao ở bên trái, vì vậy chúng tôi thêm 3 * (5 * 2) = 30 đến 13 để nhận 43 hướng dẫn dupe được thực thi và có 44 >giây trên ngăn xếp. Quá trình tương tự có thể được áp dụng cho các hướng dẫn khác, chẳng hạn như (đẩy một lượng lớn vật phẩm từ ngăn xếp sang phạm vi hoặc như được sử dụng ở đây, để xóa các mục khỏi ngăn xếp.

Một mẹo tôi đã sử dụng ở đây để tránh bị lừa quá nhiều số 0 là 1?. Nếu ký tự là 0, ?thì không bỏ qua 1, có nghĩa là nó nhân đôi 1 cho phần còn lại của bản sao. Điều này làm cho nó dễ dàng hơn nhiều để xóa ngăn xếp sau này.


25

Đây là hai quẻ Ruby ngắn nhất từ SO :

_="_=%p;puts _%%_";puts _%_

puts <<2*2,2
puts <<2*2,2
2

Đừng hỏi tôi cách thứ hai hoạt động ...


8
Cái thứ hai sử dụng heredoc, <<2bắt đầu một chuỗi trên dòng tiếp theo và *2lặp lại chuỗi
Ming-Tang

Tại sao bạn cần 2?
Máy

1
@CalculatorFeline Đó là bộ kết thúc của chuỗi heredoc (phải xuất hiện trên dòng riêng của nó). Nó không thực sự phải là 2 mặc dù: tio.run/##KypNqvz/v6C0pFjBxsZAy0jHgAuFY8D1/z8A
Martin Ender

25

Phân hạch , 6 byte

Có vẻ như đây là câu hỏi "đúng" ngắn nhất trong số những câu trả lời này.

'!+OR"

Giải trình

Dòng điều khiển bắt đầu Rvới một (1,0)nguyên tử đi đúng . Nó nhấn vào "chế độ in chuyển đổi và sau đó quấn quanh dòng, in '!+ORtrước khi nhấn lại cùng một "lần nữa và thoát khỏi chế độ in.

Điều đó để lại "chính nó được in. Cách ngắn nhất là '"O(trong đó '"đặt khối lượng của nguyên tử thành mã ký tự "Oin ký tự và phá hủy nguyên tử), nhưng nếu chúng ta làm điều này thì "nó sẽ can thiệp vào chế độ in. Vì vậy, thay vào đó, chúng tôi đặt giá trị của nguyên tử thành '!(ít hơn một "), sau đó tăng dần +sau đó in kết quả bằng O.

Lựa chọn thay thế

Dưới đây là một vài lựa chọn thay thế, dài hơn, nhưng có lẽ các kỹ thuật của họ truyền cảm hứng cho ai đó để tìm một phiên bản ngắn hơn bằng cách sử dụng chúng (hoặc có thể chúng sẽ hữu ích hơn trong các câu hỏi tổng quát nhất định).

8 byte sử dụng Jgộp

' |R@JO"

Một lần nữa, mã bắt đầu lúc R. Các @hoán đổi khối lượng và năng lượng để cung cấp (0,1). Do đó, Jnguyên tử làm cho nhảy Othẳng lên ". Sau đó, như trước đây, tất cả trừ "được in ở chế độ chuỗi. Sau đó, nguyên tử đánh |để đảo ngược hướng của nó, và sau đó đi qua '"Oin ấn ". Không gian hơi khó chịu, nhưng có vẻ cần thiết, vì nếu không ', nguyên tử sẽ khiến nguyên tử coi |như một nhân vật thay vì gương.

8 byte sử dụng hai nguyên tử

"'L;R@JO

Cái này có hai nguyên tử, bắt đầu từ trái Lvà phải từ R. Nguyên tử đi bên trái được đặt giá trị của '"nó sau đó được in ngay lập tức O(và nguyên tử bị phá hủy). Đối với nguyên tử đi đúng, chúng ta trao đổi khối lượng và năng lượng một lần nữa, nhảy qua Ođể in phần còn lại của mã ở chế độ in. Sau đó, giá trị của nó được đặt bởi 'Lnhưng điều đó không thành vấn đề vì nguyên tử sau đó bị loại bỏ ;.


Về mặt kỹ thuật không hợp lệ do thiếu mã / dữ liệu tách trong nguồn.
Máy

4
@CalculatorFeline '!+mã hóa ".
Martin Ender

Tôi không quen thuộc với Phân hạch, nhưng sẽ |R@JO"'hoạt động, hoặc bạn vẫn sẽ cần không gian đó sau '?
MildlyMilquetoast

1
@MistahFiggins Tôi nghĩ vậy, nhưng quan trọng hơn là bạn sẽ in phần 'đầu tiên.
Martin Ender

24

JavaScript trình duyệt chéo (41 ký tự)

Nó hoạt động trong 5 trình duyệt web hàng đầu (IE> = 8, Mozilla Firefox, Google Chrome, Safari, Opera). Nhập nó vào bảng điều khiển của nhà phát triển trong bất kỳ một trong số đó:

eval(I="'eval(I='+JSON.stringify(I)+')'")

Đó không phải là "gian lận" - không giống như câu lệnh đơn byte của Chris Jester-Young, vì nó có thể dễ dàng được sửa đổi để sử dụng alert()hàm (tốn 14 ký tự):

alert(eval(I="'alert(eval(I='+JSON.stringify(I)+'))'"))

Hoặc được chuyển đổi thành bookmarklet (tốn 22 ký tự):

javascript:eval(I="'javascript:eval(I='+JSON.stringify(I)+')'")

24

C, 64 60 byte

main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}",34,s);}

Cho đến nay, đây là quine C được biết đến ngắn nhất. Có một tiền thưởng mở rộng nếu bạn tìm thấy một tiền thưởng ngắn hơn.

Điều này hoạt động trong GCC , ClangTCC trong môi trường POSIX . Nó gọi quá nhiều hành vi không xác định với tất cả chúng.

Để cho vui, đây là một repo chứa tất cả các câu hỏi C tôi biết. Hãy thoải mái rẽ nhánh / PR nếu bạn tìm hoặc viết một cái khác có thêm một cái gì đó mới và sáng tạo hơn những cái hiện có.

Lưu ý rằng nó chỉ hoạt động trong môi trường ASCII . Điều này hoạt động cho EBCDIC , nhưng vẫn yêu cầu POSIX . Chúc may mắn tìm được môi trường POSIX / EBCDIC: P


Làm thế nào nó hoạt động:

  1. main(s)lạm dụng maincác đối số, khai báo một biến hầu như chưa được đánh dấu s. (Lưu ý rằng sthực tế không được gỡ bỏ, nhưng vì các trình biên dịch được liệt kê tự động bỏ nó khi cần thiết, nên nó cũng có thể là *.)
  2. printf(s="..."thiết lập schuỗi được cung cấp và chuyển đối số đầu tiên tới printf.
  3. sđược đặt thành main(s){printf(s=%c%s%1$c,34,s);}.
  4. %cđược đặt thành ASCII 34, ". Điều này làm cho quine có thể. Bây giờ strông như thế này :
    main(s){printf(s="%s%1$c,34,s);}.
  5. Cái %snày được đặt thành schính nó, điều này có thể do # 2. Bây giờ strông như thế này :
    main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}%1$c,34,s);}.
  6. Các %1$cđược thiết lập để ASCII 34 ", printf's đầu tiên ** tranh cãi. Bây giờ strông như thế này:
    main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}",34,s);}
    ... điều đó thật sự là mã nguồn ban đầu.

* Ví dụ nhờ @Pavel
** đối số đầu tiên sau trình xác định định dạng - trong trường hợp này , s. Không thể tham chiếu định dạng định dạng.


Tôi nghĩ không thể có chuyện này sẽ ngắn hơn với cách tiếp cận tương tự. Nếu công printfcụ xác định định dạng có thể truy cập thông qua $, điều này sẽ hoạt động với 52 byte:

main(){printf("main(){printf(%c%0$s%1$c,34);}",34);}

Mặc dù nó chắc chắn không được tính là cạnh tranh, nhưng người chiến thắng của "Lạm dụng luật lệ tồi tệ nhất" từ Cuộc thi Mã số Obfuscated quốc tế năm 1994, 1994_smr.c , chắc chắn là ngắn hơn.
Ray

@Ray Nó không được phép. Nó không phải là một câu hỏi đúng theo bất kỳ định nghĩa nào. Các quy tắc quien đã được thay đổi vì chương trình đó: P
MD XF

Tôi hoàn toàn đồng ý, nhưng đó là một bản hack đủ thú vị mà đáng để đề cập đến bất cứ khi nào ai đó đề cập đến một câu hỏi nhỏ nhất được biết đến, nếu chỉ vì lý do lịch sử.
Ray

4
slà loại int, không phải là "biến không được đánh dấu".
frageum

2
Tất cả các trình biên dịch rõ ràng cho phép chuyển đổi ngầm định một con trỏ thành int. s=3rõ ràng sẽ không hoạt động vì bạn cần truyền chuỗi hai lần tới printf.
frageum

24

Java, 528 byte:

Một giải pháp Java với cách tiếp cận ban đầu:

import java.math.*;class a{public static void main(String[]a){BigInteger b=new BigInteger("90ygts9hiey66o0uh2kqadro71r14x0ucr5v33k1pe27jqk7mywnd5m54uypfrnt6r8aks1g5e080mua80mgw3bybkp904cxfcf4whcz9ckkecz8kr3huuui5gbr27vpsw9vc0m36tadcg7uxsl8p9hfnphqgksttq1wlolm2c3he9fdd25v0gsqfcx9vl4002dil6a00bh7kqn0301cvq3ghdu7fhwf231r43aes2a6018svioyy0lz1gpm3ma5yrspbh2j85dhwdn5sem4d9nyswvx4wmx25ulwnd3drwatvbn6a4jb000gbh8e2lshp",36);int i=0;for(byte c:b.toByteArray()){if(++i==92)System.out.print(b.toString(36));System.out.print((char)c);}}}

ở dạng có thể đọc được:

import java.math.*;
class a
{
    public static void main (String [] a)
    {
        BigInteger b=new BigInteger ("90ygts9hiey66o0uh2kqadro71r14x0ucr5v33k1pe27jqk7mywnd5m54uypfrnt6r8aks1g5e080mua80mgw3bybkp904cxfcf4whcz9ckkecz8kr3huuui5gbr27vpsw9vc0m36tadcg7uxsl8p9hfnphqgksttq1wlolm2c3he9fdd25v0gsqfcx9vl4002dil6a00bh7kqn0301cvq3ghdu7fhwf231r43aes2a6018svioyy0lz1gpm3ma5yrspbh2j85dhwdn5sem4d9nyswvx4wmx25ulwnd3drwatvbn6a4jb000gbh8e2lshp", 36); 
        int i=0; 
        for (byte c:b.toByteArray ())
        {
            if (++i==92) 
                System.out.print (b.toString (36)); 
            System.out.print ((char) c);
        }
    }
}

Làm thế nào nó hoạt động?
Loovjo

1
@Loovjo: Tương tự như các giải pháp khác cắt mã thành hai phần và chèn toàn bộ Chuỗi lặp lại mã bên trong, nhưng toàn bộ mã không chỉ là Chuỗi mà được mã hóa thành số dài trong cơ sở 36 (26 ký tự chữ cái + 10 chữ số).
người dùng không xác định

1
Điều này có thể được rút ngắn nếu bạn đặt if(++i==92),
tuskiomi

2
@tuskiomi: Cảm ơn, rút ​​ngắn hai ký tự
người dùng không xác định

1
@userunknown Thật ra, a* vì mảng không thoát trong Java, đó là C. Một số phần khác của golf : import java.math.*;class a{public static void main(String[]a){BigInteger b=new BigInteger("abc",36);int i=0;for(int c:b.toByteArray())System.out.printf("%s%c",++i==92?b.toString(36):"",c);}}, nơi abcsẽ là chuỗi số ma thuật mới được tính toán. Trong java 8+ cũng có thể thay đổi class a{public static void mainthành interface a{static void mainvà trong Java 10+ cũng có thể thay đổi import java.math.*;BigInteger b=new BigInteger(thành var b=new java.math.BigInteger(.
Kevin Cruijssen 23/03/18

23

, 7

chicken

Không, đây không phải là tiếng vang trực tiếp :)



Nó không lặp lại, đó là chuỗi chicken!
Erik the Outgolfer

Không tách mã / dữ liệu và do đó không hợp lệ.
Máy

10
@CalculatorFeline Bạn đã đọc các quy tắc?
TimTech

1
@JoKing Tôi không nghĩ rằng điều này là không hợp lệ, bởi vì các quy tắc của thử thách chỉ cấm độ dài bằng không và gian lận (đọc tệp nguồn của riêng bạn). Điều duy nhất cấm các câu hỏi không đúng là một lỗ hổng tiêu chuẩn - ngoại trừ các lỗ hổng tiêu chuẩn thường không được xem xét để áp dụng cho các câu trả lời có trước chúng.
pppery

23

Võng mạc , 20 14 9 7 byte

Trước khi chúng tôi bắt đầu, tôi muốn đề cập đến giải pháp tầm thường của một tệp chứa một tệp 0. Trong trường hợp đó, Retina sẽ cố gắng đếm 0s trong đầu vào trống, kết quả cũng là 0. Tôi sẽ không xem xét rằng một quine thích hợp mặc dù.

Vì vậy, đây là một trong những thích hợp:

>\`
>\`

Hãy thử trực tuyến!

Ngoài ra, chúng ta có thể sử dụng ; thay vì >.

Giải trình

Chương trình bao gồm một thay thế duy nhất mà chúng tôi in hai lần.

Trong dòng đầu tiên, ` phân tách cấu hình từ regex, do đó regex trống. Do đó, chuỗi rỗng (tức là đầu vào không tồn tại) được thay thế bằng dòng thứ hai, nguyên văn.

Để in kết quả hai lần, chúng tôi gói nó trong hai giai đoạn đầu ra. Cái bên trong, \in kết quả với một linefeed trailing và cái bên ngoài,> , in nó mà không có cái nào.

Nếu bạn hơi quen thuộc với Retina, bạn có thể tự hỏi điều gì đã xảy ra với đầu ra ngầm của Retina. Đầu ra ngầm của Retina hoạt động bằng cách gói giai đoạn cuối của chương trình trong giai đoạn đầu ra. Tuy nhiên, Retina không làm điều này, nếu giai đoạn cuối đã là giai đoạn đầu ra. Lý do cho điều đó là trong một chương trình bình thường, có thể thay thế giai đoạn đầu ra ẩn bằng một byte đặc biệt giống như \hoặc ;cho một byte duy nhất (thay vì phải loại bỏ cả ẩn với .cờ). Thật không may, hành vi này đã khiến chúng tôi phải trả hai byte cho quine.


20

Javascript (36 ký tự)

(function a(){alert("("+a+")()")})()

Đây là, AFAICT, quine javascript ngắn nhất được đăng cho đến nay.


1
Thật ấn tượng. Bạn nên giải thích cách nó hoạt động với tôi 8- |
TehShrike

3
@TehShrike Gợi ý: bạn có thể xem nội dung một hàm bằng cách ép nó thành một chuỗi. Ví dụ: nếu bạn có một chức năng a, bạn có thể truy cập nội dung của nó bằng cách gọi a.toString.
Peter Olson

7
Mặc dù vậy, để trở thành mô phạm, đây chỉ là một vấn đề nếu việc triển khai JavaScript của bạn thực hiện ađúng chức năng giống như cách viết ở trên. Tuy nhiên, đầu ra của mã này có thể là một điểm yếu đối với bất kỳ triển khai JavaScript nào.
Ilmari Karonen

1
Đây là cùng một câu hỏi, ngắn hơn 1 byte : !function a(){alert("!"+a+"()")}().
Ismael Miguel

1
(a=()=>alert(($ {a})))()
Dennis C

19

GolfScript, 8 byte

Tôi luôn nghĩ rằng quine GolfScript ngắn nhất (đúng) là 9 byte:

{'.~'}.~

Trường hợp nguồn cấp dữ liệu theo dõi là cần thiết bởi vì GolfScript in một nguồn cấp theo dõi theo mặc định.

Nhưng tôi chỉ tìm thấy một quine 8 byte, hoạt động chính xác xung quanh hạn chế nguồn cấp dữ liệu đó:

":n`":n`

Hãy thử trực tuyến!

Vì vậy, điều hấp dẫn là GolfScript không in một dòng cấp dữ liệu, nhưng nó in nội dung nở cuối chương trình. Nó chỉ nchứa một nguồn cấp dữ liệu để bắt đầu. Vì vậy, ý tưởng là thay thế chuỗi đó bằng chuỗi ":n`", và sau đó xâu chuỗi nó, sao cho bản sao trên ngăn xếp in bằng dấu ngoặc kép và bản sao được lưu trữ trongn bản in mà không có.

Như Thomas Kwa đã chỉ ra, quin CJam 7 byte cũng có thể được điều chỉnh theo giải pháp 8 byte:

".p"
.p

Một lần nữa, chúng ta cần linefeed trailing.


6
Golfscript là lạ.
Máy

19

Mê cung , 124 110 53 byte

Cảm ơn Sp3000 vì đã chơi golf 9 byte, cho phép tôi chơi golf thêm 7 byte.

44660535853919556129637653276602333!
1
:_98
/8 %
@9_.

Hãy thử trực tuyến!

Giải trình

Mê cung 101:

  • Labyrinth là một ngôn ngữ 2D dựa trên ngăn xếp. Ngăn xếp không có đáy và chứa đầy các số 0, do đó, xuất hiện từ một ngăn xếp trống không phải là một lỗi.
  • Thực thi bắt đầu từ ký tự hợp lệ đầu tiên (ở đây trên cùng bên trái). Tại mỗi ngã ba, nơi có hai hoặc nhiều đường dẫn có thể cho con trỏ lệnh (IP) đi, đỉnh của ngăn xếp được kiểm tra để xác định nơi tiếp theo. Tiêu cực là rẽ trái, không là đi tiếp và tích cực là rẽ phải.
  • Các chữ số trong mã nguồn không đẩy số tương ứng - thay vào đó, chúng bật đầu ngăn xếp và đẩy n*10 + <digit>. Điều này cho phép dễ dàng xây dựng số lượng lớn. Để bắt đầu một số mới, sử dụng_ , đẩy số không.
  • " là không-ops.

Đầu tiên, tôi sẽ giải thích một phiên bản đơn giản hơn một byte dài hơn, nhưng ít ma thuật hơn một chút:

395852936437949826992796242020587432!
"
:_96
/6 %
@9_.

Hãy thử trực tuyến!

Ý tưởng chính là mã hóa phần chính của nguồn theo một số duy nhất, sử dụng một số cơ sở lớn. Số đó sau đó có thể dễ dàng được in lại trước khi nó được giải mã để in phần còn lại của mã nguồn. Việc giải mã chỉ đơn giản là ứng dụng lặp đi lặp lại divmod base, trong đó in modvà tiếp tục làm việc divcho đến khi không.

Bằng cách tránh {}, mã ký tự cao nhất chúng ta cần là _(95) sao cho cơ sở 96 là đủ (bằng cách giữ mức cơ sở thấp, số ở đầu sẽ ngắn hơn). Vì vậy, những gì chúng tôi muốn mã hóa là đây:

!
"
:_96
/6 %
@9_.

Biến các ký tự đó thành các điểm mã của chúng và coi kết quả là một số cơ sở 96 (với chữ số có nghĩa ít nhất tương ứng !và là số có ý nghĩa nhất ., bởi vì đó là thứ tự chúng tôi sẽ tháo số)

234785020242697299628949734639258593

Bây giờ mã bắt đầu với một thủ thuật khá thú vị (nếu tôi có thể nói như vậy) cho phép chúng tôi in lại mã hóa và giữ một bản sao khác để giải mã với rất ít chi phí: chúng tôi đặt số vào mã ngược lại. Tôi đã tính kết quả với tập lệnh CJam này. Vì vậy, hãy chuyển sang mã thực tế. Đây là sự khởi đầu:

395852936437949826992796242020587432!
"

IP bắt đầu ở góc trên cùng bên trái, đi về phía đông. Trong khi nó chạy trên các chữ số đó, nó chỉ đơn giản là xây dựng số đó trên đầu ngăn xếp. Bản thân con số hoàn toàn vô nghĩa, bởi vì nó ngược lại với những gì chúng ta muốn. Khi IP chạm! , nó sẽ bật số này từ ngăn xếp và in nó. Đó là tất cả để tái tạo mã hóa ở đầu ra.

Nhưng bây giờ IP đã đi vào ngõ cụt. Điều đó có nghĩa là nó quay lại và bây giờ di chuyển về phía tây (mà không thực hiện !lại). Lần này, một cách thuận tiện, IP đọc số từ trước ra trước, để bây giờ số trên đầu ngăn xếp không mã hóa phần còn lại của nguồn.

Khi IP bây giờ chạm vào góc trên cùng bên trái một lần nữa, đây không phải là ngõ cụt vì IP có thể rẽ trái, vì vậy nó sẽ di chuyển về phía nam. Đây "là một no-op, mà chúng ta cần ở đây để tách số khỏi vòng lặp chính của mã. Nói về mà:

...
"
:_96
/6 %
@9_.

Miễn là đỉnh của ngăn xếp chưa bằng 0, IP sẽ chạy qua mã khá dày đặc này trong vòng lặp sau:

"
>>>v
^< v
 ^<<

Hoặc đặt ra tuyến tính:

:_96%._96/

Lý do phải mất những lượt đó là vì ngữ nghĩa dòng điều khiển của Labyrinth. Khi có ít nhất ba hàng xóm vào ô hiện tại, IP sẽ rẽ trái vào giá trị ngăn xếp âm, đi tiếp về số 0 và rẽ phải vào giá trị ngăn xếp dương. Nếu không thể chọn hướng được chọn vì có tường, IP sẽ chuyển sang hướng ngược lại (đó là lý do tại sao có hai lượt rẽ trái trong mã mặc dù đỉnh của ngăn xếp không bao giờ âm).

Bản thân mã vòng lặp thực sự khá đơn giản (nén nó không chặt chẽ và đây là nơi đóng góp chính của Sp3000):

:    # Duplicate the remaining encoding number N.
_96  # Push 96, the base.
%.   # Take modulo and print as a character.
_96  # Push 96 again.
/    # Divide N by 96 to move to the next digit.

Khi Nchạm 0, kiểm soát dòng chảy thay đổi. Bây giờ IP muốn đi thẳng về phía trước sau /(tức là phía tây), nhưng có một bức tường ở đó. Vì vậy, thay vì nếu quay lại (phía đông), thực hiện 6lại. Điều đó làm cho đỉnh của ngăn xếp dương, vì vậy IP rẽ phải (phía nam) và thực thi 9. Đỉnh của ngăn xếp bây giờ 69, nhưng tất cả những gì chúng tôi quan tâm là nó tích cực. IP rẽ phải (hướng tây) và di chuyển đến điểm @kết thúc mã.

Tất cả trong tất cả, thực sự khá đơn giản.

Được rồi, bây giờ làm thế nào để chúng ta cạo đi byte bổ sung đó. Rõ ràng, điều đó có vẻ lãng phí, nhưng chúng ta cần hàng bổ sung đó: nếu vòng lặp liền kề với số, IP sẽ chuyển đến đó ngay lập tức thay vì đi ngang qua toàn bộ số. Vì vậy, chúng ta có thể làm một cái gì đó hữu ích với no-op đó.

Về nguyên tắc, chúng ta có thể sử dụng số đó để thêm chữ số cuối vào mã hóa. Mã hóa không thực sự cần phải được tất cả trên dòng đầu tiên ... các !chỉ đảm bảo rằng bất cứ điều gì có cũng được in ở đó.

Có một nhược điểm, chúng ta không thể làm điều này:

95852936437949826992796242020587432!
3
:_96
/6 %
@9_.

Vấn đề là bây giờ chúng tôi đã thay đổi "thành a 3, cũng thay đổi số thực tế mà chúng tôi muốn có. Và chắc chắn rằng con số đó không kết thúc 3. Vì số hoàn toàn được xác định bởi mã bắt đầu từ !chúng tôi không thể làm gì nhiều về điều đó.

Nhưng có lẽ chúng ta có thể chọn một chữ số khác? Chúng tôi không thực sự quan tâm liệu có một 3vị trí nào đó miễn là chúng tôi kết thúc với một số mã hóa chính xác nguồn. Thật không may, không có chữ số nào trong số 10 chữ số mang lại một mã hóa có chữ số có ý nghĩa nhỏ nhất khớp với chữ số được chọn. May mắn thay, phần còn lại của mã còn lại để chúng ta có thể thử thêm một vài mã hóa mà không làm tăng số byte. Tôi đã tìm thấy ba tùy chọn:

  1. Chúng ta có thể thay đổi @thành /. Trong trường hợp đó, chúng tôi có thể sử dụng bất kỳ chữ số nào từ 1357và nhận được mã hóa phù hợp. Tuy nhiên, điều này có nghĩa là chương trình sau đó chấm dứt với một lỗi, được cho phép nhưng có vẻ không sạch lắm.
  2. Spaces không phải là ký tự "tường" duy nhất. Mỗi ký tự không được sử dụng, đáng chú ý là tất cả các chữ cái. Nếu chúng ta sử dụng một chữ cái viết hoa, thì chúng ta thậm chí không cần phải tăng cơ sở để chứa nó (vì các điểm mã bên dưới _). 26 lựa chọn cho rất nhiều khả năng. Ví dụ cho Abất kỳ chữ số lẻ hoạt động. Điều này đẹp hơn một chút, nhưng nó vẫn không có vẻ thanh lịch, vì bạn không bao giờ sử dụng một chữ cái trong mã thực.
  3. Chúng ta có thể sử dụng một cơ sở lớn hơn. Miễn là chúng tôi không tăng cơ sở đáng kể, số chữ số thập phân trong mã hóa sẽ giữ nguyên (cụ thể, mọi cơ sở lên tới 104 đều ổn, mặc dù các cơ sở ngoài 99 thực sự sẽ yêu cầu thêm các ký tự trong mã). May mắn thay, cơ sở 98 đưa ra một giải pháp phù hợp duy nhất: khi chúng ta sử dụng chữ số 1, mã hóa cũng kết thúc bằng 1. Đây là giải pháp duy nhất trong số các căn cứ 96, 97, 98, 99, vì vậy đây thực sự là rất may mắn. Và đó là cách chúng tôi kết thúc với mã ở đầu câu trả lời này.

19

Mất , 293 262 249 byte

>:2+52*:6*:(84*+75*):>:::::[[[[[[[:[(52*)>::::[[[[[[:[84*+@>%?!<((((((((((([[[[[[[[[[[[[[ "
\#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\

Hãy thử trực tuyến!

Giải trình

Toàn bộ dự án này đã được lên xuống. Tôi cứ nghĩ rằng điều đó là không thể và sau đó nảy ra một ý tưởng điên rồ có thể có hiệu quả.

Tại sao một Lost Quine rất khó?

Như bạn có thể biết Lost là ngôn ngữ lập trình 2D trong đó vị trí bắt đầu và hướng hoàn toàn ngẫu nhiên. Điều này làm cho việc viết bất kỳ chương trình bị mất nào cũng khó như viết mã cứng. Bạn phải xem xét mọi vị trí và hướng có thể.

Điều đó đang được nói có một số cách tiêu chuẩn để làm việc. Ví dụ ở đây là cách tiêu chuẩn để in một chuỗi.

>%?"Stringv"(@
^<<<<<<<<<<<<<

Điều này có một luồng bộ sưu tập ở phía dưới lấy hầu hết các ips và kéo chúng đến vị trí bắt đầu. Khi chúng đạt đến vị trí bắt đầu (phía trên bên trái), chúng tôi vệ sinh chúng bằng một vòng lặp loại bỏ tất cả các giá trị trên ngăn xếp sau đó chuyển sự an toàn của việc đẩy chuỗi và thoát. (an toàn là một khái niệm duy nhất đối với Mất mọi chương trình phải đạt được %trước khi thoát, điều này ngăn khả năng chương trình kết thúc khi bắt đầu). Bây giờ ý tưởng của tôi sẽ là mở rộng hình thức này thành một quine đầy đủ.

Điều đầu tiên phải làm là làm lại vòng lặp một chút, vòng lặp hiện có dành riêng cho định dạng Chuỗi.

>%?!<"Stringv"(@
^<<<<<<<<<<<<<<<
^<<<<<<<<<<<<<<<

Chúng ta cần thêm luồng thứ hai để tránh khả năng !nhảy qua luồng và tạo vòng lặp.

Bây giờ chúng tôi muốn kết hợp điều này với định dạng Quine tiêu chuẩn. Vì Lost dựa rất nhiều vào Klein, về cơ bản, tôi đã bị đánh cắp khi mượn Klien Quine cho Martin Ender .

:2+@>%?!< "
<<<<^<<<<<<
<<<<^<<<<<<

Điều này khá thuận tiện in dòng đầu tiên của quine. Bây giờ tất cả những gì chúng ta cần làm là mã hóa các luồng. Vâng, điều này nói thì dễ hơn làm. Tôi đã thử khoảng bốn phương pháp khác nhau để làm điều này. Tôi sẽ chỉ mô tả một trong những hoạt động.

Ý tưởng ở đây là sử dụng cửa để có được số mũi tên mong muốn. Cửa là một loại gương đặc biệt thay đổi mỗi khi nó bị bắn trúng. [phản ánh ips đến từ bên trái và ]bên phải. Khi chúng bị một ip từ một trong hai phía này định hướng chuyển đổi. Chúng ta có thể tạo một dòng của những cánh cửa này và một gương phản xạ tĩnh để liên tục thực hiện một thao tác.

>:[[[

Sẽ thực hiện :ba lần. Bằng cách này, nếu chúng ta đẩy một <ngăn xếp trước khi ra tay, chúng ta có thể tạo ra rất nhiều trong số chúng với ít byte hơn. Chúng tôi tạo 2 trong số này, một cho mỗi dòng và ở giữa chúng, chúng tôi đặt ra một dòng mới, tuy nhiên dòng thứ hai chỉ cần đi cho đến khi nó bao gồm !chúng tôi đã thêm nó, bất cứ điều gì khác có thể để trống cho chúng tôi một vài byte. Ok bây giờ chúng ta cần thêm các mũi tên dọc vào luồng của chúng tôi. Đây là nơi tối ưu hóa khóa đến. Thay vì chuyển hướng tất cả các ips đến "bắt đầu" của chương trình, thay vào đó chúng ta sẽ chuyển hướng chúng sang bên trái, bởi vì chúng ta đã biết rằng các ips bắt đầu ở bên trái phảicông việc (hoặc ít nhất sẽ hoạt động trong phiên bản cuối cùng) chúng ta cũng có thể chuyển hướng các ips khác. Điều này không chỉ làm cho nó rẻ hơn theo byte, tôi nghĩ rằng tối ưu hóa này là điều làm cho quine có thể.

Tuy nhiên, vẫn còn một số vấn đề, vấn đề quan trọng nhất là ips bắt đầu sau khi >đã được đẩy nhưng trước khi chúng tôi bắt đầu tạo bản sao của nó. Các ips như vậy sẽ vào máy photocopy và tạo ra một loạt các bản sao 0. Điều này thật tệ vì cơ chế dọn sạch ngăn xếp của chúng tôi sử dụng các số không để xác định đáy của ngăn xếp, để lại một loạt các số không ở dưới cùng. Chúng ta cần thêm một phương pháp vệ sinh ngăn xếp mạnh mẽ hơn. Vì không có cách nào thực sự để biết liệu ngăn xếp có trống không, chúng tôi chỉ đơn giản là sẽ phải cố gắng phá hủy càng nhiều vật phẩm trên ngăn xếp càng tốt. Ở đây chúng ta sẽ một lần nữa sử dụng phương pháp cửa được mô tả trước đó. Chúng tôi sẽ thêm ((((((((((([[[[[[[[[[[[[[vào cuối dòng đầu tiên ngay sau khi vệ sinh để thoát khỏi số không.

Bây giờ có một vấn đề nữa, vì chúng tôi đã chuyển hướng các luồng của mình sang các ips phía trên bên trái bắt đầu từ %và di chuyển xuống sẽ tắt an toàn và sẽ thoát sớm. Vì vậy, chúng ta cần phải tắt sự an toàn. Chúng tôi thực hiện điều này bằng cách thêm một #luồng, theo cách đó, các luồng thông qua luồng sẽ bị tắt nhưng các ips đã được khử trùng sẽ không được. Cũng #phải được mã hóa cứng vào dòng đầu tiên là tốt.

Đó là nó, hy vọng bạn hiểu làm thế nào điều này làm việc bây giờ.


: / rất nhiều lỗi chính tả và các liên kết bị thiếu
ASCII - chỉ

17

Yup , 1165 879 606 561 540 522 498 + 7 = 505 byte

Yêu cầu -cheatcờ cho phép định nghĩa các bí danh.

022222120211111102222122021121202222212021112202222110222212202112110222221202122212022222102222212021222120222221022222102222210222221202222110222211022222210222221022222210222212202222221022221102211110222221022221220222212202112120221111022212202211210222212022222102211120222122022111202222120212212021221202222221022111102221210222122022222102222120212212022221102211110222122022221102222120212212022112120221111022212202112120222212=%;0e-=<;0<-=>;:0~--=1;1>=2;0%{{>0<~{~>~<<}>>>]}>]}${<#}%{@}

Hãy thử trực tuyến!

Giải trình

Có hai phần này (như với hầu hết các quines). Dữ liệu:

022222120211111102222122021121202222212021112202222110222212202112110222221202122212022222102222212021222120222221022222102222210222221202222110222211022222210222221022222210222212202222221022221102211110222221022221220222212202112120221111022212202211210222212022222102211120222122022111202222120212212021221202222221022111102221210222122022222102222120212212022221102211110222122022221102222120212212022112120221111022212202112120222212

Và bộ giải mã:

=%;0e-=<;0<-=>;:0~--=1;1>=2;0%{{>0<~{~>~<<}>>>]}>]}${<#}%{@}

Dữ liệu chỉ là một mã hóa nhị phân của bộ giải mã (hay đúng hơn là ngược lại). Mỗi cái 0bắt đầu một ký tự mới và 1s và 2s lần lượt là 0- và 1-bits.

Lưu ý rằng đó 0là lệnh Yup tiêu chuẩn đẩy số 0, trong khi 12không được xác định tại thời điểm này. Tuy nhiên, chúng tôi gán toàn bộ phần dữ liệu cho lệnh %để 12có thể không xác định cho đến khi %thực sự được sử dụng.

Tiếp theo, chúng tôi xác định thêm một số lệnh:

0e-=<;
0<-=>;
:0~--=1;
1>=2;

<giảm đỉnh của ngăn xếp, >tăng nó. 1(hơi vô tình) nhân đôi đỉnh của ngăn xếp. 2nhân đôi nó và sau đó tăng nó Nhờ những định nghĩa này, một cái gì đó giống như 0221111thực sự sẽ để lại 48 (110000 ở dạng nhị phân) trên ngăn xếp.

32 byte còn lại thực hiện giải mã thực tế thành hai phần. Đầu tiên chúng ta cần xây dựng lại chuỗi dữ liệu.

0%                ` Push a zero and then the data.
{                 ` For each value...
  {               `   Until that value is zero...
    >0<~{~>~<<}>  `   divmod 2. The div is the input to the next iteration,
                  `   the mod gives us the next bit.
    >>]           `   Increment twice (gives 2 or 3) and put at the bottom
                  `   of the stack.
  }
  >]              ` Increment the 0 and put it at the bottom as well.
}
$                 ` Reverse the entire stack.
{<#}              ` Decrement and print each number.

Và cuối cùng, chúng tôi lại đẩy dữ liệu và in từng giá trị dưới dạng một ký tự:

%{@}

Để tham khảo trong tương lai, đây là một tập lệnh CJam để mã hóa dữ liệu.


17

Fueue , 423 byte

Fueue là một esolang dựa trên hàng đợi trong đó chương trình đang chạy hàng đợi.

)$$4255%%1(~):[)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]](H-):~:[)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:](106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

Giải thích này có thể có hoặc không có cách nào ra khỏi tầm tay. Mặt khác, tôi không biết làm thế nào để giải thích nó ngắn hơn nhiều theo cách tôi hy vọng mọi người có thể làm theo.

Bảng cheat Fueue

Xem bài viết wiki esolang để biết chi tiết, bao gồm một số tính năng không được sử dụng trong chương trình này.

  • Chương trình ban đầu là trạng thái ban đầu của hàng đợi, có thể chứa các thành phần sau:

    • Các chữ nguyên (chỉ không âm trong nguồn, nhưng có thể tính toán âm), thực hiện chúng in một ký tự.
    • Các khối lồng nhau được phân tách bằng khung vuông, trơ (được bảo toàn nguyên vẹn trừ khi một số chức năng tác động lên chúng).
    • Các hàm, đối số của chúng là các phần tử theo sau chúng ngay lập tức trong hàng đợi:
      • +*/-%: số học số nguyên ( -là đơn nguyên, %phủ định logic). Trơ nếu không đưa ra đối số số.
      • ()<: đặt phần tử trong ngoặc, xóa dấu ngoặc khỏi khối, thêm phần tử cuối cùng vào khối. Hai cái sau trơ trừ khi theo sau là một khối.
      • ~:: hoán đổi, nhân đôi.
      • $: sao chép (lấy số + phần tử). Trơ trước không số.
      • H: tạm dừng chương trình.

    Lưu ý rằng trong khi []lồng, ()không - cái sau đơn giản là các hàm riêng biệt.

Cú pháp theo dõi thực hiện

Khoảng trắng là tùy chọn trong Fueue, ngoại trừ giữa các chữ số. Trong các dấu vết thực hiện sau đây, nó sẽ được sử dụng để đề xuất cấu trúc chương trình, cụ thể:

  • Khi một hàm thực thi, nó và các đối số của nó sẽ được đặt ra từ các phần tử xung quanh có khoảng trắng. Nếu một số đối số phức tạp, có thể có một khoảng cách giữa chúng.
  • Nhiều dấu vết thực hiện được chia thành một "blob delay" ở bên trái, được tách từ một phần bên phải để thực hiện thao tác dữ liệu đáng kể. Xem phần tiếp theo.

Dấu ngoặc nhọn {}(không được sử dụng trong Fueue) được sử dụng trong các dấu vết để biểu thị kết quả số nguyên của các biểu thức toán học. Điều này bao gồm các số âm, vì Fueue chỉ có nghĩa đen không âm - -là hàm phủ định.

Tên biến đổi khác nhau và ...được sử dụng để biểu thị các giá trị và chữ viết tắt.

Chiến thuật trì hoãn

Theo trực giác, các chu kỳ thực hiện xung quanh hàng đợi, sửa đổi một phần những gì nó đi qua. Kết quả của một chức năng không thể được thực hiện lại cho đến chu kỳ tiếp theo. Các phần khác nhau của chương trình phát triển song song một cách hiệu quả miễn là chúng không tương tác.

Kết quả là, rất nhiều mã được dành cho đồng bộ hóa, đặc biệt là trì hoãn việc thực hiện các phần của chương trình cho đến thời điểm thích hợp. Có rất nhiều lựa chọn để chơi golf này, có xu hướng biến những phần đó thành những đốm màu không thể đọc được mà chỉ có thể hiểu được bằng cách truy tìm chu kỳ thực hiện của chúng theo chu kỳ.

Những chiến thuật này sẽ không luôn được đề cập riêng trong phần dưới đây:

  • )[A]sự chậm trễ Acho một chu kỳ. (Có lẽ là phương pháp dễ nhất và dễ đọc nhất.)
  • ~efhoán đổi các yếu tố efcũng trì hoãn việc thực hiện của chúng. (Có lẽ là ít đọc nhất, nhưng thường ngắn nhất cho sự chậm trễ nhỏ.)
  • $1etrì hoãn một yếu tố duy nhất e.
  • -%rất hữu ích cho việc trì hoãn các số (cái sau cho 01.)
  • Khi trì hoãn một số phần tử bằng nhau trong một hàng :hoặc $có thể được sử dụng để tạo chúng từ một phần tử duy nhất.
  • (nkết thúc ntrong ngoặc, mà sau này có thể được gỡ bỏ một cách thuận tiện. Điều này đặc biệt quan trọng đối với các phép tính số, vì các số quá không ổn định thậm chí không được sao chép mà không đặt chúng vào một khối.

Cấu trúc tổng thể

Phần còn lại của lời giải thích được chia thành bảy phần, mỗi phần cho một phần của chương trình đang chạy. Các chu kỳ lớn hơn mà sau đó hầu hết chúng lặp lại sẽ được gọi là "lặp" để phân biệt chúng với "chu kỳ" của các lần đi qua toàn bộ hàng đợi.

Đây là cách chương trình ban đầu được phân chia giữa chúng:

A:  )$$4255%%1(~
B:  ):[)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
C:  
D:  (H-
E:  
F:  
G:  ):~:[)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:](106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611

Chữ số lớn ở cuối chương trình mã hóa phần còn lại theo chiều ngược lại, hai chữ số cho mỗi ký tự, trừ 30 từ mỗi giá trị ASCII (ví dụ: 10mã hóa a (.)

Ở cấp độ cao hơn, bạn có thể nghĩ về dữ liệu trong chương trình này (bắt đầu bằng bignum) như chảy từ phải sang trái, nhưng điều khiển chảy từ trái sang phải. Tuy nhiên, ở cấp độ thấp hơn, Fueue làm rối loạn sự khác biệt giữa mã và dữ liệu mọi lúc.

  • Phần G giải mã bignum thành các chữ số ASCII (ví dụ chữ số 0là số nguyên 48), trước tiên tách ra các chữ số có nghĩa ít nhất. Nó tạo ra một chữ số cứ sau 15 chu kỳ.
  • Phần F chứa các giá trị ASCII chữ số được sản xuất (mỗi bên trong một khối) cho đến khi phần E có thể tiêu thụ chúng.
  • Phần E xử lý hai chữ số được sản xuất cùng một lúc, ghép chúng thành các khối của biểu mẫu [x[y]], cũng in ký tự được mã hóa của mỗi cặp.
  • Phần D bao gồm một khối được lồng sâu dần dần được xây dựng từ các [x[y]]khối theo cách mà một khi nó chứa tất cả các chữ số, nó có thể được chạy để in tất cả chúng, sau đó tạm dừng toàn bộ chương trình.
  • Phần C xử lý việc xây dựng phần D, và cũng tái tạo phần E.
  • Phần B tái tạo lại phần C cũng như chính nó sau mỗi 30 chu kỳ.
  • Phần A đếm ngược chu kỳ cho đến lần lặp cuối cùng của các phần khác. Sau đó, nó hủy bỏ phần B và chạy phần D.

Mục A

Phần A xử lý lập lịch kết thúc chương trình. Phải mất 4258 chu kỳ để giảm xuống một chức năng hoán đổi duy nhất ~, sau đó thực hiện điều chỉnh cho phần B dừng vòng lặp chính của nó và bắt đầu chạy phần D thay thế.

)$ $4255% %1 (~
)$%%%...%% %0 [~]
)$%%%...% %1 [~]
⋮
)$ %0 [~]
) $1[~]
)[~]
~
  • Một $hàm tạo ra 4255 bản sao sau đây %trong khi (kết thúc các ~dấu ngoặc.
  • Mỗi chu kỳ cuối cùng %được sử dụng để chuyển đổi số sau giữa 01.
  • Khi tất cả các %s được sử dụng hết, $1tạo 1 bản sao của [~](có hiệu quả là NOP) và trong chu kỳ tiếp theo, )loại bỏ dấu ngoặc.

Mục B

Phần B xử lý việc tự tái tạo cũng như lặp lại mới của phần C cứ sau 30 chu kỳ.

) : [)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
) [)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]            [BkB]
)$ $24%     %0  :<  [~:)~)]    ~ [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<] [BkB]
)$ %...%%% %1   < < [~:)~)] [BkB]   [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
)$ %...%% %0      < [~:)~)[BkB]] [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
)$ %...% %1         [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
⋮
) $1 [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
) [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]                    (1)
~:) ~)[BkB]                 [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
) : [BkB]                 ) [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]      (2)
) [BkB] [BkB]               $11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<
  • Một :bản sao khối lớn theo sau (một bản sao được viết tắt là [BkB]), sau đó )xóa dấu ngoặc khỏi bản sao đầu tiên.
  • $$24%%0 thiết lập một bộ đếm ngược tương tự như trong phần A.
  • Trong khi điều này đếm ngược, :<biến thành <<~hoán đổi hai trong số các khối, đặt mã cho phần C mới.
  • Hai <hàm đóng gói hai khối cuối cùng vào khối đầu tiên - điều này là không cần thiết trong các lần lặp thông thường, nhưng sẽ cho phép ~phần A thực hiện công việc của nó ở cuối.
  • (1) Khi đếm ngược kết thúc, )loại bỏ các dấu ngoặc ngoài. Tiếp theo ~:)biến thành ):~)hoán đổi a )đến đầu mã C.
  • (2) Phần B hiện đang quay trở lại chu kỳ ban đầu của nó, trong khi phần A )sắp xóa dấu ngoặc để bắt đầu chạy một bước lặp mới của phần C.

Trong lần lặp lại cuối cùng, ~từ phần A xuất hiện tại điểm (1) ở trên:

~ ) [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]                  (1)
[~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]              )

Việc ~hoán đổi )trên toàn khối và vào phần C, ngăn không cho phần B được chạy lại.

Mục C

Phần C xử lý hợp nhất các cặp ký tự chữ số mới vào khối của phần D và cũng tạo ra các lần lặp mới của phần E.

Dưới đây cho thấy một lần lặp điển hình với xyđại diện cho mã ASCII của các chữ số. Trong lần lặp đầu tiên, các phần tử "D" và "E" đến là ban đầu [H]-thay vào đó, vì không có phần E nào trước đó đã chạy để tạo ra bất kỳ cặp ký tự chữ số nào.

C                                               D             E
$11~ )  ~<[[+$4--498+*-:~-10)):])<~]  [)))~]  < [)))~[...]]   [x[y]]
~~~ ~~~ ~~~ ~~) [[+$4--498+*-:~-10)):])<~]  < [)))~] [)))~[...][x[y]]]
~~~ ~~~     )  ~ [[+$4--498+*-:~-10)):])<~] [)))~[)))~[...][x[y]]]]
~~~       ~ )   [)))~[....]]                                  [[+$4--498+*-:~-10)):])<~]
                                              ~~[)))~[....]] )[[+$4--498+*-:~-10)):])<~]
                                                [)))~[....]]  ~[+$4--498+*-:~-10)):])<~
  • Điều này sử dụng một phương pháp đồng bộ hóa khác mà tôi phát hiện ra cho câu trả lời này. Khi bạn có một số chức năng hoán đổi ~liên tiếp, hàng sẽ co lại khoảng 2/3 mỗi chu kỳ (vì một lần ~hoán đổi hai lần sau), nhưng đôi khi với một phần còn lại ~sẽ tàn phá những thao tác cẩn thận.
  • $11~sản xuất một hàng như vậy. Tiếp theo ~hoán đổi một <khối trên khối sau. Một cái khác <ở cuối sẽ nối một khối cặp chữ số mới (chữ số x và y dưới dạng mã ASCII) vào khối D của phần.
  • Chu kỳ tiếp theo, ~hàng có ~~phần còn lại, trong đó hoán đổi một ~phần sau ). Phần khác <nối phần D vào một [)))~]khối.
  • Tiếp theo, hoán đổi ~chính nó hoán đổi khối sau với mã E phần mới trên khối D phần. Sau đó, một phần còn lại mới ~hoán đổi một đường )ngang, và cuối cùng, hàng cuối cùng ~~trong ~hàng đổi một trong số chúng sang phần E giống như )đã loại bỏ dấu ngoặc của nó.

Trong lần lặp lại cuối cùng, phần A ~đã hoán đổi một )phần B và sang phần C. Tuy nhiên, phần C ngắn ngủi đến nỗi nó đã biến mất, và )kết thúc ở đầu phần D.

Mục D

Phần D xử lý in số lớn cuối cùng và tạm dừng chương trình. Trong phần lớn thời gian chạy chương trình, đó là một khối trơ mà các phần B thẩm G hợp tác xây dựng.

    (H -
    [H]-
    ⋮
    [)))~[H-]]                  After one iteration of section C
    ⋮
    [)))~[)))~[H-][49[49]]]]    Second iteration, after E has also run
    ⋮
)   [)))~[...]]     [49[48]]    Final printing starts as ) is swapped in
    ))) ~[...][49[48]]
    )) )[49[48]] [...]
    )) 49 [48][...]             Print first 1
    ) )[48] [...]
    ) 48 [...]                  Print 0
    )[...]                      Recurse to inner block
    ...
    ⋮
    )[H-]                       Innermost block reached
    H -                         Program halts
  • Trong chu kỳ đầu tiên của chương trình, hàm (kết thúc chức năng tạm dừng Htrong ngoặc. Sau -đây, nó sẽ được sử dụng như một phần tử giả cho lần lặp đầu tiên thay vì một cặp chữ số.
  • Cặp chữ số thực đầu tiên được kết hợp là [49[49]], tương ứng với số cuối cùng 11trong chữ số.
  • Cặp chữ số cuối cùng [49[48]](tương ứng với phần 10đầu của chữ số) không thực sự được tích hợp vào khối, nhưng điều này không tạo ra sự khác biệt nào )[A[B]])[A][B]tương đương, cả hai đều biến thành A[B].

Sau lần lặp cuối cùng, phần )hoán đổi ngay từ phần B đến và khối D được gỡ rối. Ở )))~đầu mỗi khối phụ đảm bảo rằng tất cả các phần được thực hiện theo đúng thứ tự. Cuối cùng, khối trong cùng chứa một Hchương trình tạm dừng.

Mục E

Phần E xử lý kết hợp các cặp chữ số ASCII được tạo bởi phần G và cả hai đều in ký tự được mã hóa tương ứng và gửi một khối với cặp kết hợp sang trái sang các phần C và D.

Một lần nữa dưới đây cho thấy một lần lặp điển hình với xyđại diện cho mã ASCII của các chữ số.

E                                                   F
~ [+$4--498+*-:~-10)):] )              <  ~         [y] [x]
) [+$4--498+*-:~-10)):]                   < [x] [y]
+ $4-  - 498  +*- :~ -10 ) )              : [x[y]]
+---  -{-498} +*- ~~{-10} )       ) [x[y]]  [x[y]]
+--    - 498  +*   -{-10}       ~ ) x  [y]  [x[y]]
+-    -{-498} +               * 10 x  )[y]  [x[y]]
+      - 498                    + {10*x} y  [x[y]]
                         + {-498} {10*x+y}  [x[y]]
{10*x+y-498}  [x[y]]
[x[y]]
  • Các khối chữ số đến được hoán đổi, sau đó khối y được gắn vào khối x và toàn bộ khối cặp được sao chép. Một bản sao sẽ được để lại cho đến hết phần C và D.
  • Bản sao khác được gỡ rối một lần nữa, sau đó một chuỗi các hàm số học được áp dụng để tính toán 10*x+y-498, giá trị ASCII của ký tự được mã hóa. 498 = 10*48+48-30, 48s hoàn tác mã hóa ASCII xytrong khi 30chuyển mã hóa từ 00–99sang 30–129, bao gồm tất cả ASCII có thể in được.
  • Số kết quả sau đó được để lại để thực thi, in ký tự của nó.

Mục F

Phần F bao gồm các khối trơ chứa mã số ASCII. Đối với hầu hết các chương trình chạy, sẽ có nhiều nhất là hai ở đây, vì phần E tiêu thụ chúng với cùng tốc độ mà G tạo ra chúng. Tuy nhiên, trong giai đoạn in cuối cùng, một 0số chữ số dự phòng sẽ được thu thập ở đây.

[y] [x] ...

Mục G

Phần G xử lý tách số lớn ở cuối chương trình, trước tiên là các chữ số có nghĩa ít nhất và gửi các khối có mã ASCII của chúng sang trái cho các phần khác.

Vì nó không có kiểm tra tạm dừng, nó thực sự sẽ tiếp tục tạo ra các 0chữ số khi số đã giảm xuống 0, cho đến khi phần D tạm dừng toàn bộ chương trình với Hhàm.

[BkG] viết tắt một bản sao của khối mã bắt đầu lớn, được sử dụng để tự sao chép để bắt đầu các lần lặp mới.

Khởi tạo trong các chu kỳ đầu tiên:

) :~  : [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]  ( 106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611
)  ~ ~ [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]  [BkG] [10...11]
) [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]     ~ [BkG] [10...11]
) [):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]       ~ : [10...11]  [BkG]

Lặp lại điển hình, Nbiểu thị số cần chia:

) [):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]        ~ : [N]  [BkG]
) :~ [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+ :5 )         : [N]  : [BkG]
)  ~ ~ [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]  +5 5     ) [N]  [N] [BkG] [BkG]
) [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]               ~ 10 N  [N] [BkG] [BkG]
) ~:~  ~ ( [:~)*[):~[$1(+48]):~+]-:~~)10)~~]               / N 10  [N] [BkG] [BkG]
)  ~ : [:~)*[):~[$1(+48]):~+]-:~~)10)~~]                 ( {N/10}  [N] [BkG] [BkG]
) [:~)*[):~[$1(+48]):~+]-:~~)10)~~]                    : [{N/10}]  [N] [BkG] [BkG]
:~ )*[):~[$1(+48]):~+]- :~ ~)10 )           ~ ~ [{N/10}]  [{N/10}] [N] [BkG] [BkG]
~~) *[):~[$1(+48]):~+]- ~~10 )             ) [{N/10}]  ~ [{N/10}] [N]  [BkG] [BkG]
)  ~ * [):~[$1(+48]):~+]  -10            ~ ) {N/10}  [N] [{N/10}] [BkG] [BkG]
) [):~[$1(+48]):~+]               * {-10} {N/10}  ) [N]  [{N/10}] [BkG] [BkG]
) :~ [$1(+48]) :~                 + {-10*(N/10)} N  [{N/10}] [BkG] [BkG]
)  ~ ~ [$1(+48]  )                 ~ ~ {N%10}  [{N/10}] [BkG] [BkG]
) [$1(+48]                 ~ ) {N%10}  ~ [{N/10}] [BkG]  [BkG]
$1(                     + 48 {N%10}    ) [BkG]  [{N/10}] [BkG]
                        ( {48+N%10}   BkG [{N/10}] [BkG]            New iteration starts
                        [{48+N%10}]   ....
  • Các blob chậm trễ ở đây là đặc biệt lông. Tuy nhiên, thủ thuật trì hoãn mới duy nhất là sử dụng +:5thay vì --10trì hoãn 10hai chu kỳ. Than ôi chỉ có một trong những người 10trong chương trình được giúp đỡ bởi điều này.
  • Các khối [N][BkG]được nhân đôi, sau đó một bản sao Nđược chia cho 10.
  • [{N/10}]được nhân đôi, sau đó nhiều hàm số học được sử dụng để tính mã ASCII của chữ số cuối cùng Nlà as 48+((-10)*(N/10)+N). Khối có mã ASCII này được để lại cho phần F.
  • Các bản sao khác của [{N/10}]được hoán đổi giữa các [BkG]khối để thiết lập bắt đầu một lần lặp mới.

Tiền thưởng (540 byte)

)$$3371%%1[~!~~!)!]):[)$$20%%0[):]~)~~[)$$12%%0[<$$7%~~0):~[+----48+*-~~10))]<]<~!:~)~~[40~[:~))~:~[)~(~~/[+--48):]~10]+30])):]]][)[H]](11(06(06(21(21(25(19(07(07(19(61(96(03(96(96(03(11(03(63(11(28(61(11(06(06(20(18(07(07(18(61(11(28(63(96(11(96(96(61(11(06(06(19(20(07(07(18(61(30(06(06(25(07(96(96(18(11(28(96(61(13(15(15(15(15(22(26(13(12(15(96(96(19(18(11(11(63(30(63(30(96(03(28(96(11(96(96(61(22(18(96(61(28(96(11(11(96(28(96(61(11(96(10(96(96(17(61(13(15(15(22(26(11(28(63(96(19(18(63(13(21(18(63(11(11(28(63(63(63(61(11(61(42(63(63

Hãy thử trực tuyến!

Vì tôi không chắc phương thức nào sẽ ngắn nhất, trước tiên tôi đã thử mã hóa các ký tự dưới dạng các số có hai chữ số cách nhau bởi (s. Mã lõi ngắn hơn một chút, nhưng biểu diễn dữ liệu lớn hơn 50% bù cho nó. Không chơi gôn như người khác, khi tôi dừng lại khi nhận ra nó sẽ không đánh bại nó. Nó có một lợi thế: Nó không yêu cầu triển khai với sự hỗ trợ của bignum.

Cấu trúc tổng thể của nó là hơi giống với cấu trúc chính. Phần G bị thiếu do biểu diễn dữ liệu điền trực tiếp vào phần F. Tuy nhiên, phần E phải thực hiện phép tính divmod tương tự để xây dựng lại các chữ số của các số có hai chữ số.


1
Bạn nên đánh golf lời giải thích XD
VFDan

1
)$n[)](là một byte ngắn hơn cho bộ đếm độ trễ.
jimmy23013

15

Thạch, 3 byte

”ṘṘ

Hãy thử trực tuyến!

xác minh

$ echo $LANG
en_US
$ xxd -g 1 quine.jelly
0000000: ff cc cc                                         ...
$ ./jelly f quine.jelly | xxd -g 1
0000000: ff cc cc                                         ...

Làm thế nào nó hoạt động

”ṘṘ    Main link. No input.

”Ṙ     Set the return value to the character 'Ṙ'.
  Ṙ    Print a string representation of the return value.
       This prints: ”Ṙ
       (implicit) Print the return value.
       This prints: Ṙ

Phiên bản nào của trình thông dịch này sử dụng? Khi tôi kiểm tra nó, nó xuất ra UTF-8 mặc dù đầu vào nằm trong bảng mã của Jelly (và sự thay đổi trong mã hóa sẽ khiến nó không phải là một vấn đề).

1
Mã hóa của đầu ra phụ thuộc vào cài đặt của thiết bị đầu cuối của bạn: nếu được đặt thành UTF-x, nó sẽ sử dụng mã đó; nếu nó được đặt thành bất cứ thứ gì khác, nó sẽ sử dụng trang mã của Jelly. Trên Linux, LANG=en_USđạt được điều đó. tio.run/nexus/bash#@@/
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.