Haskell , 306 + 624 = 930 byte
Chương trình 1: Một hàm ẩn danh lấy một đối số giả và trả về một chuỗi.
(\b c()->foldr(\a->map pred)b(show()>>c)`mappend`show(map(map fromEnum)$tail(show c):pure b))"İĴİóđđđÝöÝâÝæÝääē××êääē××İēÀħđĮâħēĕóİóòòĮááħááđéêâéêēááĮÀħ""(\b c()->foldr(\a->map pred)b(show()>>c)`mappend`show(map(map fromEnum)$tail(show c):pure b))"
Hãy thử trực tuyến!
Chương trình 2: q[[40,...]]
ở cuối là một hàm ẩn danh lấy một đối số giả và trả về một chuỗi.
z~z=[[['@','0'..]!!4..]!!z]
q[x,q]_=z=<<x++q++[34,34]++x
q[[40,92,98,32,99,40,41,45,62,102,111,108,100,114,40,92,97,45,62,109,97,112,32,112,114,101,100,41,98,40,115,104,111,119,40,41,62,62,99,41,96,109,97,112,112,101,110,100,96,115,104,111,119,40,109,97,112,40,109,97,112,32,102,114,111,109,69,110,117,109,41,36,116,97,105,108,40,115,104,111,119,32,99,41,58,112,117,114,101,32,98,41,41,34],[304,308,304,243,273,273,273,221,246,221,226,221,230,221,228,228,275,215,215,234,228,228,275,215,215,304,275,192,295,273,302,226,295,275,277,243,304,243,242,242,302,225,225,295,225,225,273,233,234,226,233,234,275,225,225,302,192,295]]
Hãy thử trực tuyến!
Bộ ký tự 1 (bao gồm không gian):
"$()-:>E\`abcdefhilmnoprstuw×ÝáâäæéêñòóöđēĕħĮİĴ
Bộ ký tự 2 (bao gồm dòng mới):
!'+,.0123456789<=@[]_qxz~
Vì chỉ có tập 1 chứa các ký tự không phải ASCII, nên các byte UTF-8 của chúng cũng rời rạc.
Làm thế nào nó hoạt động
Chương trình 1 thường được viết với các biểu thức lambda, dấu cách và dấu ngoặc đơn, sử dụng miễn phí các hàm chữ và số dựng sẵn và với dữ liệu quine dưới dạng chuỗi ký tự ở cuối.
- Mã lõi của Chương trình 1 được chuyển thành chuỗi dữ liệu bằng chữ đơn giản bằng cách bao quanh nó bằng dấu ngoặc kép.
- Để hỗ trợ điều này, mọi dấu gạch chéo ngược được theo sau bởi
a
hoặc b
, tạo thành chuỗi thoát hợp lệ mà làm tròn qua show
.
- Một lợi ích nhỏ khác là
a
, b
và c
là các chữ cái viết thường duy nhất có mã ASCII nhỏ hơn 100, lưu một chữ số trong mã hóa số được sử dụng bởi chương trình 2.
- Mã hóa chuỗi ký tự của mã lõi của chương trình 2 bị xáo trộn nhiều hơn bằng cách sử dụng Unicode không ASCII: Mỗi ký tự có 182 điểm được thêm vào điểm mã của nó để đảm bảo không có sự trùng lặp với các ký tự gốc.
- 182 từng là 128, cho đến khi tôi nhận ra rằng tôi có thể lạm dụng thực tế là 182 có độ dài gấp đôi chuỗi ký tự cho mã chương trình 1 để rút ngắn quá trình giải mã. (Như một phần thưởng, chương trình 2 có thể sử dụng các dòng mới.)
Chương trình 2 thường được viết với các phương trình hàm cấp cao nhất (ngoại trừ ẩn danh cuối cùng), ký tự và số thập phân, cú pháp danh sách / phạm vi và toán tử, và với dữ liệu quine là danh sách các danh sách Int
s ở cuối.
- Mã lõi của Chương trình 1 được mã hóa dưới dạng danh sách các điểm mã của nó, với trích dẫn kép cuối cùng.
- Mã lõi của Chương trình 2 được mã hóa dưới dạng danh sách các điểm mã của chuỗi ký tự được sử dụng trong chương trình 1, vẫn được dịch chuyển lên trên 182.
Hướng dẫn, chương trình 1
b
và c
là các giá trị của chuỗi ký tự chuỗi cho chương trình 2 và 1, tương ứng, được đưa ra làm đối số cuối cùng cho biểu thức lambda. ()
là một đối số giả chỉ để đáp ứng quy tắc của PPCG rằng chương trình sẽ xác định hàm.
foldr(\a->map pred)b(show()>>c)
giải mã chuỗi b
thành mã lõi của chương trình 2 bằng cách áp dụng map pred
cho nó một số lần bằng độ dài của show()>>c == c++c
, hoặc 182
.
tail(show c)
chuyển đổi chuỗi c
thành mã lõi của chương trình 1, với một trích dẫn kép cuối cùng được nối thêm.
:pure b
kết hợp điều này trong một danh sách với chuỗi b
.
map(map fromEnum)$
chuyển đổi các chuỗi thành danh sách các điểm mã.
`mappend`show(...)
tuần tự hóa danh sách kết quả của danh sách và cuối cùng nối nó vào mã lõi của chương trình 2.
Hướng dẫn, chương trình 2
- Toplevel
z~z=[[['@','0'..]!!4..]!!z]
là một chức năng chuyển đổi mã trỏ lại thành các ký tự (cần thiết để viết vì không phải tất cả các ký tự toEnum
có sẵn.)
- Đối số điểm mã của nó cũng được gọi
z
. Điểm đánh dấu sự lười biếng ~
không có tác dụng ở vị trí này nhưng tránh một nhân vật không gian.
['@','0'..]
là một phạm vi danh sách bước lùi bắt đầu từ mã ASCII 64, sau đó nhảy xuống 16 bước mỗi bước.
- Áp dụng
!!4
cho điều này cho một \NUL
nhân vật.
- Bao bọc trong một
[ ..]
phạm vi cho một danh sách tất cả các ký tự, !!z
chỉ mục.
- Nhân vật cuối cùng được bọc trong một danh sách đơn. Điều này cho phép ánh xạ chức năng
z
qua các danh sách bằng cách sử dụng =<<
thay vì không có sẵn map
và <$>
.
- Toplevel
q[x,q]_=z=<<x++q++[34,34]++x
là một hàm xây dựng chương trình 1 từ danh sách dữ liệu quine.
x
là dữ liệu cho lõi của chương trình 1 (bao gồm cả trích dẫn kép cuối cùng) và bên trong q
là dữ liệu bị che _
giấu cho lõi của chương trình 2. là một đối số giả khác chỉ để biến hàm ẩn danh cuối cùng thành hàm thay vì chỉ là một chuỗi.
x++q++[34,34]++x
ghép các mảnh, bao gồm hai dấu ngoặc kép với mã ASCII 34.
z=<<
xây dựng chương trình 1 bằng cách ánh xạ z
qua phần nối để chuyển đổi từ điểm mã thành ký tự.
- Cuối cùng
q[[40,...]]
là một chức năng ẩn danh kết hợp q
với dữ liệu quine.