Haskell , 3 quines, 1119 byte
Câu 1, 51 byte
Một IOhành động ẩn danh in trực tiếp đến thiết bị xuất chuẩn.
putStr`mappend`print`id`"putStr`mappend`print`id`"
Hãy thử trực tuyến!
Quine 2, 265 byte
Hàm flấy một đối số giả và trả về một chuỗi.
f c=[b=<<g]!!0++show g;b c=[[[show 9!!0,show 1!!0..]!!6..]!!c];g=[93,0,90,52,82,89,52,51,51,94,84,24,24,39,34,34,106,95,102,110,0,94,50,89,0,90,52,82,82,82,106,95,102,110,0,48,24,24,39,35,106,95,102,110,0,40,24,24,39,37,37,84,24,24,45,37,37,84,24,24,90,84,50,94,52]
Hãy thử trực tuyến!
Quine 3, 803 byte
Tất cả mọi thứ sau LANGUAGEpragma là một hàm bất thường lấy một đối số giả và trả về một chuỗi.
{-#LANGUAGE CPP#-}(\q(_:_:_:_:_:_:_:_:z)y(#)_->(y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x)$y(:)#y(:)$ \x->x)z)'\''__TIME__(\(?)v k x->v$k?x)$ \(&)(%)v->v&'{'&'-'&'#'&'L'&'A'&'N'&'G'&'U'&'A'&'G'&'E'&' '&'C'&'P'&'P'&'#'&'-'&'}'&'('%'\\'&'q'&'('&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'_'&':'&'z'&')'&'y'&'('&'#'&')'&'_'&'-'&'>'&'('&'y'&'('%'\\'&'k'&' '&'x'&'-'&'>'%'\''&'&'%'\''&':'&'q'&':'&'k'&':'&'q'&':'&'x'&')'&'#'&'y'&'('%'\\'&'k'&' '&'x'&'-'&'>'%'\''&'%'%'\''&':'&'q'&':'%'\''%'\\'%'\\'%'\''&':'&'k'&':'&'q'&':'&'x'&')'&'$'&'y'&'('&':'&')'&'#'&'y'&'('&':'&')'&'$'&' '%'\\'&'x'&'-'&'>'&'x'&')'&'z'&')'%'\''%'\\'%'\''%'\''&'_'&'_'&'T'&'I'&'M'&'E'&'_'&'_'&'('%'\\'&'('&'?'&')'&'v'&' '&'k'&' '&'x'&'-'&'>'&'v'&'$'&'k'&'?'&'x'&')'&'$'&' '%'\\'&'('&'&'&')'&'('&'%'&')'&'v'&'-'&'>'&'v'
Hãy thử trực tuyến!
Nhân vật
Câu 1:
"S`adeimnprtu
Câu 2:
!+,.0123456789;<=[]bcfghosw
Câu 3:
#$%&'()-:>?ACEGILMNPTU\_kqvxyz{}
Làm thế nào nó hoạt động
Câu 1
putStr`mappend`print`id`"putStr`mappend`print`id`"
Quine 1 là phiên bản sửa đổi của Golf gần đây của tôi , bạn trả lời câu hỏi (với những cải tiến của H.PWiz):
- Vì các chương trình đầy đủ là không cần thiết,
main= đã được gỡ bỏ.
<>và $đã được thay thế bởi các từ đồng nghĩa gần mappendvà id.
Điều này giải phóng các nhân vật quan trọng =<>và toán tử hữu ích $cho các nhiệm vụ khác.
Câu 2
f c=[b=<<g]!!0++show g;b c=[[[show 9!!0,show 1!!0..]!!6..]!!c];g=[93,0,......]
Quine 2 sử dụng các phương thức hơi giống với chương trình 2 trong câu trả lời Quines độc quyền gần đây của tôi , nhưng được điều chỉnh theo cách trực tiếp và đặc biệt là để tránh sử dụng các ký tự, cần thiết cho quine 3. Cả hai đều đạt được với sự trợ giúp của showhàm, mà may mắn là chưa có nhân vật nào được sử dụng.
Câu hỏi này sử dụng các tab thay vì khoảng trắng, nhưng tôi đã sử dụng khoảng trắng bên dưới để dễ đọc.
glà dữ liệu quine, như một danh sách các số nguyên ở cuối mã. Mỗi số đại diện cho một ký tự từ phần còn lại của mã.
- Các số được dịch chuyển theo
9, vì vậy đó là tab 0. Điều này làm cho mã hóa ngắn hơn một chút bằng cách cho phép các chữ cái viết thường cho hàm và tên biến phù hợp với 2 chữ số.
b c=[[[show 9!!0,show 1!!0..]!!6..]!!c] là một hàm để chuyển đổi một số thành một ký tự (thực ra là một chuỗi một ký tự).
[[show 9!!0,show 1!!0..]!!6..]là một phạm vi ký tự bắt đầu bằng một ký tự tab, được lập chỉ mục với !!c.
- Các ký tự tab riêng của mình được sản xuất bởi lập chỉ mục vào phạm vi khác
[show 9!!0,show 1!!0..], bắt đầu với ký tự chữ số '9'và '1'và nhảy xuống trong bước 8.
- Các ký tự chữ số được tạo ra bằng cách lập chỉ mục vào
showchuỗi của chữ số tương ứng.
f c=[b=<<g]!!0++show glà chức năng chính. clà một đối số giả.
b=<<gsử dụng =<<để chuyển đổi từng số gthành ký tự của nó. (Việc sử dụng =<<chứ không phải là ví dụ maplà tại sao bcần phải bọc ký tự trả về của nó trong danh sách.)
show gđưa ra biểu diễn chuỗi của gdanh sách và ++nối các chuỗi.
- Bởi vì
=<<có quyền ưu tiên thấp hơn ++, một số dấu ngoặc là cần thiết. Để tránh sử dụng ()(dành riêng cho quine 3), hãy [...]!!0lập chỉ mục vào một danh sách với một thành phần.
Câu 3
Theo thiết kế của các quine khác, quine 3 vẫn có quyền truy cập vào dấu ngoặc đơn, biểu thức lambda, ký tự ký tự và hàm tạo chuỗi / danh sách :. Đây sẽ là đủ để xây dựng một hàm prepends mã của Quine thành một chuỗi.
Thật không may, tất cả các nguyên âm chữ thường (trừ đôi khi y) đã được sử dụng, không để lại các hàm dựng sẵn chữ và số hữu ích. Cũng []""đã biến mất. Điều này không có cách bình thường để xây dựng một chuỗi trống để bắt đầu giả vờ mã.
Tuy nhiên, gần như tất cả các chữ cái viết hoa vẫn có sẵn, do đó, một LANGUAGEpragma để có được một phần mở rộng ngôn ngữ là có thể. Một lần nữa bởi may mắn, CPP(kích hoạt bộ tiền xử lý C) là phần mở rộng ngôn ngữ duy nhất được đặt tên chỉ bằng chữ in hoa. Và các macro CPP thường có tên viết hoa.
Vì vậy, để có được chuỗi rỗng thiết yếu, quine cho phép CPP, sử dụng __TIME__macro để lấy hằng số chuỗi có dạng "??:??:??"(được đảm bảo thuận tiện để luôn có cùng độ dài) và mẫu khớp với nó.
{-#LANGUAGE CPP#-}(\q(_:_:_:_:_:_:_:_:z)y(#)_->(y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x)$y(:)#y(:)$ \x->x)z)'\''__TIME__(\(?)v k x->v$k?x)$ \(&)(%)v->v&'{'&'-'&......
Sau pragma ngôn ngữ, quine bao gồm một biểu thức lambda ràng buộc các tham số của nó với bốn đối số này (để lại một tham số giả cuối cùng _sẽ được áp dụng sau):
qràng buộc '\'', đưa ra một nhân vật trích dẫn duy nhất;
_:_:_:_:_:_:_:_:zbị ràng buộc __TIME__, hay còn gọi là một chuỗi như "??:??:??"vậy, do đó tạo ra zmột chuỗi rỗng;
ybị ràng buộc với (\(?)v k x->v$k?x), một bộ kết hợp lambda được sử dụng để giúp chuyển đổi dữ liệu quine từ dạng liên kết trái ("Foldl") sang dạng liên kết phải ("Foldr");
- Toán tử
(#)ràng buộc với\(&)(%)v->v&'{'&'-'&... , dữ liệu quine chính nó.
Dữ liệu quine được đưa ra dưới dạng mã hóa Church, biểu thức lambda với các tham số (&)(%)v .
- Bằng cách áp dụng biểu thức cho các giá trị cụ thể để khởi tạo
(&),(%) và v, mã hóa này có thể được sử dụng một trong hai để xây dựng mã cốt lõi của Quine hoặc để xây dựng lại biểu diễn dữ liệu Quine riêng của mình.
- Theo quy tắc sửa lỗi mặc định của Haskell
&và% trở thành các nhà khai thác liên kết bên trong lambda. Do đó, các tham số ký tự được kết hợp với vbắt đầu từ bên trái.
- Đối với hầu hết các nhân vật
k, có một tương ứng&'k' .
- Khi
klà 'hay \, mà cần phải được thoát bên literals nhân vật, mã hóa là thay %'\k'.
Vì mã hóa dữ liệu là liên kết trái, nhưng các chuỗi được xây dựng theo cách kết hợp phải, nên bộ kết hợp y = (\(?)v k x->v$k?x)được giới thiệu để làm cầu nối không khớp.
y(...)được dự định để xây dựng các chức năng phù hợp để sử dụng như các toán tử (&)và (%)toán tử quine .
vlà một hàm từ chuỗi đến chuỗi ( vví dụ dự định của dữ liệu quine ).
klà một ký tự, xmột chuỗi và ?một toán tử kết hợp chúng thành một chuỗi mới. (Đối với mã lõi,(?)=(:) . Để thực sự tái cấu trúc biểu diễn dữ liệu quine, nó phức tạp hơn.)
- Vì vậy,
y(?)v k = \x->v$k?xlà một chức năng khác từ chuỗi đến chuỗi.
Như một ví dụ về cách điều này thay đổi tính kết hợp, nếu (&)=y(:):
(v&k1&k2&k3) x
= (((v&k1)&k2)&k3) x
= y(:)(y(:)(y(:)v k1)k2)k3 x
= y(:)(y(:)v k1)k2 (k3:x)
= y(:)v k1 (k2:(k3:x))
= v (k1:(k2:(k3:x)))
= v (k1:k2:k3:x)
Tổng quát hơn, khi nào (#)là hàm dữ liệu quine và f1,f2là các hàm kết hợp các ký tự với chuỗi:
(y(f1)#y(f2)$v) x
= (...(y(f1)(y(f1)v '{') '-')...) x
= v(f1 '{' (f1 '-' (... x)))
áp dụng hàm dữ liệu quine với (&)=y(f1)và (%)=y(f2), và điều này sử dụng quy định f1và f2để kết hợp các ký tự của dữ liệu quine với x, và sau đó chuyển chuỗi kết quả tớiv .
Phần thân của biểu thức lambda chính đặt tất cả lại với nhau:
(y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:x)$y(:)#y(:)$ \x->x)z
'&':q:k:q:xcho một nhân vật kprepends &'k'vào chuỗi x, trong khi '%':q:'\\':k:q:xprepends %'\k', đó là hình thức dữ liệu Quine ban đầu của họ.
- Do đó,
y(\k x->'&':q:k:q:x)#y(\k x->'%':q:'\\':k:q:xlà các tham số phù hợp để xây dựng lại biểu diễn dữ liệu quine, được thêm vào cuối cùng z(chuỗi trống), và sau đó được chuyển sang hàm sau.
y(:)#y(:) là các tham số phù hợp để thêm mã lõi của quine vào chuỗi, mà không cần sửa đổi khác.
- Cuối cùng, không
\x->xđược làm gì với quine được xây dựng, được trả lại.