Python 2.6+ - 334 322 316 ký tự
397 368 366 ký tự không nén
exec'xÚEPMO!½ï¯ i,P*Ýlš%ì‰=‰Ö–*†þz©‰:‡—Lò¾fÜ”bžAù,MVi™.ÐlǃwÁ„eQL&•uÏÔ‹¿1O6ǘ.€LSLÓ’¼›î”3òšL¸tŠv[ѵl»h;ÁºŽñÝ0Àë»Ç‡ÛûH.ª€¼âBNjr}¹„V5¾3Dë@¼¡•gO. ¾ô6 çÊsÃЮürÃ1&›ßVˆùZ`Ü€ÿžcx±ˆ‹sCàŽ êüRô{U¯ZÕDüE+³ŽFA÷{CjùYö„÷¦¯Î[0þøõ…(Îd®_›â»E#–Y%’›”ëýÒ·X‹d¼.ß9‡kD'.decode('zip')
Một dòng mới là bắt buộc và tôi đã tính nó là một ký tự.
Mumbo jumbo trên trang mã của trình duyệt có thể ngăn sao chép và dán thành công mã này, vì vậy bạn có thể tùy chọn tạo tệp từ mã này:
s = """
23 63 6F 64 69 6E 67 3A 6C 31 0A 65 78 65 63 27 78 DA 45 50 4D 4F 03 21
10 BD EF AF 20 69 2C 50 2A 02 DD 6C 9A 25 EC AD 07 8D 89 07 3D 89 1C D6
96 2A 86 05 02 1B AD FE 7A A9 89 3A 87 97 4C F2 BE 66 DC 94 62 9E 41 F9
2C 4D 56 15 69 99 0F 2E D0 6C C7 83 77 C1 16 84 65 51 4C 26 95 75 CF 8D
1C 15 D4 8B BF 31 4F 01 36 C7 98 81 07 2E 80 4C 53 4C 08 D3 92 BC 9B 11
EE 1B 10 94 0B 33 F2 9A 1B 4C B8 74 8A 9D 76 5B D1 B5 6C BB 13 9D 68 3B
C1 BA 8E F1 DD 30 C0 EB BB C7 87 DB FB 1B 48 8F 2E 1C AA 80 19 BC E2 42
4E 6A 72 01 7D B9 84 56 35 BE 33 44 8F 06 EB 40 BC A1 95 67 4F 08 2E 20
BE F4 36 A0 E7 CA 73 C3 D0 AE FC 72 C3 31 26 9B DF 56 88 AD F9 5A 60 DC
80 FF 9E 63 78 B1 88 8B 73 43 E0 8E A0 EA FC 52 F4 7B 55 8D AF 5A 19 D5
44 FC 45 2B B3 8E 46 9D 41 F7 7B 43 6A 12 F9 59 F6 84 F7 A6 01 1F AF CE
5B 30 FE F8 F5 85 28 CE 64 AE 5F 9B E2 BB 45 23 96 59 25 92 9B 94 EB FD
10 D2 B7 58 8B 64 BC 2E DF 39 87 6B 44 27 2E 64 65 63 6F 64 65 28 27 7A
69 70 27 29
"""
with open('golftris.py', 'wb') as f:
f.write(''.join(chr(int(i, 16)) for i in s.split()))
Thử nghiệm
intetris
[]
[]
[]
[]
[# # #]
[## ######]
[==========]
T2 Z6 I0 T7
Dòng mới phải là kiểu Unix (chỉ dành cho dòng). Một dòng mới ở cuối dòng cuối cùng là tùy chọn.
Để kiểm tra:
> python golftris.py <intetris
[]
[]
[]
[# ###]
[# ###]
[##### ####]
[==========]
10
Mã này giải nén mã gốc và thực thi nó với exec
. Mã được giải nén này nặng 366 ký tự và trông giống như sau:
import sys
r=sys.stdin.readlines();s=0;p=r[:1];a='[##########]\n'
for l in r.pop().split():
n=int(l[1])+1;i=0xE826408E26246206601E>>'IOZTLSJ'.find(l[0])*12;m=min(zip(*r[:6]+[a])[n+l].index('#')-len(bin(i>>4*l&31))+3for l in(0,1,2))
for l in range(12):
if i>>l&2:c=n+l/4;o=m+l%4;r[o]=r[o][:c]+'#'+r[o][c+1:]
while a in r:s+=10;r.remove(a);r=p+r
print''.join(r),s
Dòng mới là bắt buộc và mỗi dòng là một ký tự.
Đừng cố đọc mã này. Các tên biến được chọn ngẫu nhiên theo nghĩa đen để tìm kiếm độ nén cao nhất (với các tên biến khác nhau, tôi thấy có tới 342 ký tự sau khi nén). Một phiên bản dễ hiểu hơn sau:
import sys
board = sys.stdin.readlines()
score = 0
blank = board[:1]
full = '[##########]\n'
for piece in board.pop().split():
column = int(piece[1]) + 1
bits = 0xE826408E26246206601E >> 'IOZTLSJ'.find(piece[0]) * 12
drop = min(zip(*board[:6]+[full])[column + x].index('#') -
len(bin(bits >> 4 * x & 31)) + 3 for x in (0, 1, 2))
for i in range(12):
if bits >> i & 2:
x = column + i / 4
y = drop + i % 4
board[y] = board[y][:x] + '#' + board[y][x + 1:]
while full in board:
score += 10
board.remove(full)
board = blank + board
print ''.join(board), score
Điểm mấu chốt nằm ở ba dòng khó hiểu mà tôi đã nói là tôi sẽ giải thích.
Hình dạng của các tetrominoes được mã hóa bằng số thập lục phân ở đó. Mỗi tetronimo được coi là chiếm một lưới ô 3x4, trong đó mỗi ô trống (dấu cách) hoặc đầy (dấu số). Mỗi phần sau đó được mã hóa bằng 3 chữ số thập lục phân, mỗi chữ số mô tả một cột 4 ô. Các chữ số có nghĩa nhỏ nhất mô tả các cột ngoài cùng bên trái và bit có nghĩa nhỏ nhất trong mỗi chữ số mô tả ô trên cùng trong mỗi cột. Nếu một bit là 0, thì ô đó trống, nếu không thì đó là '#'. Ví dụ: I tetronimo được mã hóa 00F
, với bốn bit của chữ số có nghĩa nhỏ nhất được thiết lập để mã hóa bốn dấu hiệu số ở cột ngoài cùng bên trái và chữ T là131
, với bit trên cùng được đặt ở bên trái và bên phải, và hai bit trên cùng được đặt ở giữa.
Toàn bộ số thập lục phân sau đó được dịch chuyển một bit sang trái (nhân với hai). Điều này sẽ cho phép chúng tôi bỏ qua bit dưới cùng. Tôi sẽ giải thích lý do tại sao trong một phút.
Vì vậy, với phần hiện tại từ đầu vào, chúng tôi tìm chỉ mục trong số thập lục phân này, nơi 12 bit mô tả hình dạng của nó bắt đầu, sau đó chuyển nó xuống để các bit 1–12 (bỏ qua bit 0) của bits
biến mô tả phần hiện tại.
Nhiệm vụ drop
xác định có bao nhiêu hàng từ trên cùng của lưới mà mảnh sẽ rơi xuống trước khi hạ cánh trên các mảnh mảnh khác. Dòng đầu tiên cho biết có bao nhiêu ô trống ở đầu mỗi cột của sân chơi, trong khi dòng thứ hai tìm ô bị chiếm thấp nhất trong mỗi cột của quân cờ. Các zip
chức năng trả về một danh sách các hàng, trong đó mỗi tuple bao gồm các n th tế bào từ mỗi mục trong danh sách đầu vào. Vì vậy, sử dụng bảng nhập liệu mẫu, zip(board[:6] + [full])
sẽ trả về:
[
('[', '[', '[', '[', '[', '[', '['),
(' ', ' ', ' ', ' ', ' ', ' ', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', ' ', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(']', ']', ']', ']', ']', ']', ']')
]
Chúng tôi chọn bộ từ danh sách này tương ứng với cột thích hợp và tìm chỉ mục của bộ đầu tiên '#'
trong cột. Đây là lý do tại sao chúng tôi đã thêm một hàng "đầy đủ" trước khi gọi zip
, để hàng đó index
sẽ có giá trị trả về hợp lý (thay vì đưa ra một ngoại lệ) khi cột này trống.
Sau đó, để tìm giá trị thấp nhất '#'
trong mỗi cột của mảnh, chúng ta dịch chuyển và che dấu bốn bit mô tả cột đó, sau đó sử dụng bin
hàm để biến nó thành một chuỗi đơn vị và số không. Các bin
chức năng chỉ trả về bit có ý nghĩa, vì vậy chúng ta chỉ cần tính toán chiều dài của chuỗi này để tìm các tế bào bị chiếm đóng thấp nhất (hầu hết có ý nghĩa thiết lập bit). Các bin
chức năng cũng prepends '0b'
, vì vậy chúng ta phải trừ đó. Chúng tôi cũng bỏ qua bit ít quan trọng nhất. Đây là lý do tại sao số thập lục phân bị dịch chuyển sang trái một bit. Điều này là để giải thích cho các cột trống, mà các biểu diễn chuỗi sẽ có cùng độ dài với một cột chỉ có ô trên cùng đầy (chẳng hạn như phần T ).
Ví dụ, các cột của tôi tetromino, như đã đề cập trước đó, là F
, 0
, và 0
. bin(0xF)
là '0b1111'
. Sau khi bỏ qua '0b'
, chúng ta có độ dài là 4, đúng. Nhưng bin(0x0)
là 0b0
. Sau khi bỏ qua '0b'
, chúng ta vẫn có độ dài là '1, điều này không chính xác. Để giải thích cho điều này, chúng tôi đã thêm một bit bổ sung vào cuối, để chúng tôi có thể bỏ qua bit không quan trọng này. Do đó, +3
đoạn mã có trong đó để tính độ dài thừa được chiếm bởi '0b'
phần đầu và bit không đáng kể ở phần cuối.
Tất cả điều này xảy ra trong một biểu thức trình tạo cho ba cột ( (0,1,2)
) và chúng tôi lấy min
kết quả để tìm số hàng tối đa mà mảnh có thể thả xuống trước khi nó chạm vào bất kỳ cột nào trong ba cột.
Phần còn lại sẽ khá dễ hiểu bằng cách đọc mã, nhưng for
vòng lặp sau các nhiệm vụ này sẽ thêm phần vào bảng. Sau đó, while
vòng lặp loại bỏ các hàng đầy đủ, thay thế chúng bằng các hàng trống ở trên cùng và tính điểm. Vào cuối, bảng và điểm số được in ra đầu ra.