Không thể đọc được , 1830 1796 1791 1771 1762 1745 1736 1727 1626 1606 1577 byte
Đầu ra theo thứ tự chữ cái ngược ( z
to a
) nhưng theo quy tắc của bạn có vẻ được cho phép.
"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "
Giải trình
Đầu tiên, để có ấn tượng về những gì Unreadable có thể làm, đây là thao tác cơ bản của nó:
- Bạn có một băng vô hạn gồm các ô nguyên có kích thước tùy ý
- Bạn không có con trỏ bộ nhớ như trong Brainfuck; thay vào đó, bạn chọn các ô theo vị trí của chúng trên băng. Điều này có nghĩa là bạn có thể đọc giá trị # 4 giá trị hoặc đọc giá trị # 4 (giá trị đọc số 4).
- Bạn chỉ có thể đọc hoặc ghi các ô nhớ (không tăng / giảm trực tiếp như trong Brainfuck).
- Bạn có thể tăng / giảm giá trị trong một biểu thức. Do đó, để tăng một ô nhớ bạn phải đọc , tăng , ghi hoặc đặt khác nhau :
write(x, inc(read(x)))
.
- Có những vòng lặp và điều kiện ternary chỉ có thể kiểm tra 0 so với khác không.
Chương trình này sử dụng băng như sau. Tên biến sẽ được sử dụng trong mã giả sau bên dưới. Ngoài ra, tài liệu này là phiên bản đầu tiên (là 1830 byte); xem các chỉnh sửa ở phía dưới để biết những gì đã thay đổi kể từ đó.
- Ô 0: biến
q
- Tế bào 1: biến
a
, p
,ch
- Ô 2: biến
hash
,v
- Ô 3: biến
b
,r
- Ô 4: biến
aa
,l
- Ô 5: vẫn là 0 để đánh dấu đầu cuối của các chuỗi chữ số thập phân
- Các ô 6 Mã 95: lưu trữ chuỗi các chữ số thập phân ngược
- Các ô
a
96 Kết luận z
121 : lưu trữ số phiếu được trừ từ người dùng (96) đến (121) (mã ASCII của chữ cái trừ đi một).
- Các tế bào 4657 Ném7380: hãy nhớ những kết hợp cử tri / cử tri đã gặp phải bao nhiêu lần. Các ô này chỉ có 4 giá trị có thể:
0
= chưa thấy, -1
= nhìn thấy một lần, -2
= nhìn thấy hai lần, -3
= thấy bất kỳ số lần nào nhiều hơn 2.
Thuật toán về cơ bản tiến hành như sau:
- Tiếp tục đọc các cặp ký tự
a
và b
. Tính giá trị băm (a-2)*(a-1)+b-1
, là giá trị duy nhất cho mọi tổ hợp chữ cái a z.
- Kiểm tra ô nhớ tại giá trị băm đó (
*hash
). Nếu đó -3
, người dùng đã đủ điều kiện để bỏ phiếu, vì vậy hãy tăng dần *(b-1)
. Nếu không, giảm dần *hash
. Nếu đó là hiện nay -3
, người dùng vừa trở thành đủ điều kiện để loại bỏ phiếu sau ba lần xuất hiện, do đó tăng *(b-1)
do 3
.
- Sau đó, đi qua các ký tự theo thứ tự ngược (
z
đến a
) và xuất ra những ký tự cần bỏ phiếu. Điều này đòi hỏi phải chia số nguyên thủ công cho 10 để dịch số thành chữ số thập phân.
Với tất cả những gì đã làm rõ, đây là những gì chương trình trông giống như mã giả:
// Read pairs of characters
while (a = read) + 1 {
b = read
// Calculate hash = (a-1)*(a-2)/2 + b-1
// This also sets a = b-1
hash = 0
while --a {
aa = a
while --aa {
++hash
}
}
while --b {
++a
++hash
}
// If this combination has just been seen for the third time,
// increment *a by 3; if more than third time, increment *a by 1
*a = (*hash + 3) ? ((--*hash) + 3 ? *a : (*a+3)) : (*a+1)
}
// Loop through the characters z to a
l = 27
while --l { // l loops from 26 to 1 (not 0)
(v = *(ch = l + 95)) ? { // 'a' is ASCII 97, but cell 96
print (ch+1) // print the votee
// Now we need to turn the number v into decimal.
// p points to where we are storing decimal digits.
p = 5
while v {
// Integer division by 10 (q=quotient, r=remainder)
r = (q = 0)
while v {
--v
(++r - 10) ? 1 : {
r = 0
++q
}
}
// Store digit ASCII character
*(++p) = r + 48 // 48 = '0'
v = q
}
// Now output all the digit ASCII characters in reverse order
while *p {
print *(--p + 1)
}
} : 1
}
Chỉnh sửa 1, 1830 → 1796: Nhận ra rằng tôi có thể sử dụng lại giá trị trả về của một vòng lặp while ở một nơi.
Chỉnh sửa 2, 1796 → 1791: Hóa ra chương trình nhỏ hơn một chút nếu, thay vì sử dụng các ô 6 Tắt95, tôi lưu các chữ số thập phân trong các ô có số âm (từ1 trở đi). Là một phần thưởng bổ sung, chương trình không còn giới hạn ở 10⁹⁰ phiếu bầu!
Chỉnh sửa 3, 1791 → 1771: Thay vì gán kết quả *(ch = l + 95)
cho v
, bây giờ tôi gán nó cho q
và sau đó di chuyển phép gán v = q
vào điều kiện while, lấy mã thành 1777 byte. Sau đó trao đổi vị trí của q
và v
trên băng bởi vì q
bây giờ là 1 phổ biến hơn v
.
Chỉnh sửa 4, 1771 → 1762: Duh. Khởi tạo hash
thành 1 thay vì 0 ngắn hơn 9 byte. Mã băm bây giờ là 1, điều đó không quan trọng.
Chỉnh sửa 5, 1762 → 1745: Nếu tôi khởi tạo q
và r
thành 1 thay vì 0, tôi phải rắc một số -1
vị trí để làm cho đúng, và tất cả dường như hủy bỏ - ngoại trừ việc while v { --v; [...] }
vòng lặp bây giờ cần thực hiện một lần lặp ít hơn, mà tôi có thể làm bằng cách nói while --v { [...] }
, ngắn hơn 26 ký tự.
Chỉnh sửa 6, 1745 → 1736: Thay vì { r = 1; ++q }
, chúng ta có thể viết q = *((r = 1)+1)+1
. Điều này phụ thuộc vào thực tế q
là trong khe số 2. Nếu nó ở vị trí số 1 thì điều này thậm chí còn ngắn hơn, nhưng sau đó toàn bộ chương trình sẽ dài hơn.
Chỉnh sửa 7, 1745 → 1727: Hoàn nguyên Chỉnh sửa 6 và thay vào đó đạt được sự tiết kiệm bằng cách đặt nội tuyến trong khi lặp vào biểu thức tính mã ASCII chữ số, cũng kết thúc ở 1736 byte ... nhưng sau đó đã lưu một lệnh giảm (9 byte ) bằng cách thay đổi ((++r) - 11) ? r :
thành (r - 10) ? ++r :
.
Chỉnh sửa 8, 1727 → 1626: Làm lại phép tính băm. Bây giờ nó sử dụng một vòng lặp while ít hơn. Các vị trí ô hiện đang ở mã ASCII thực tế của chúng (không phải là 1 nữa). Chia sẻ lại các biến đến các vị trí khác nhau trên băng bởi vì chúng hiện xảy ra với tần suất khác nhau.
Chỉnh sửa 9, 1626 → 1606: Nội tuyến điên rồ hơn. Phần thân của vòng lặp while đầu tiên trông giống như thế này:
// b = next char
*(b = (hash = read)) = {
// hash = b + (a-1)*(a-2)/2
while (a2 = --a) {
while --a2 {
++hash
}
}
// If this combination has just been seen for the third time,
// increment *b by 3; if more than third time, increment *b by 1
(*hash + 3) ? ((--*hash) + 3 ? *b : (*b+3)) : (*b+1)
}
và việc gán biến đã thay đổi gần như hoàn toàn.
Sửa 10, 1606 → 1577: Tôi quan sát thấy rằng a
và a2
đều giảm đi tới 0 trong vòng lặp while, do đó nếu tôi có thể ghép p
với một trong những người, nhưng không có ch
, tôi sẽ không cần phải khởi tạo p
để 0
(mà chi phí 29 byte). Hóa ra tôi có thể làm điều đó bằng cách hoán đổi p
và r
. Các giả định biến mới nhất (và tần suất xuất hiện của chúng trong mã) hiện là:
0 = v (3) (total 3)
1 = hash (6), r (5), ch (2) (total 13)
2 = b (4), q (5) (total 9)
3 = a (3), p (5) (total 8)
4 = a2 (3), l (4) (total 7)
nanananananananabatman
trường hợp thử nghiệm.