Python 2.6+ - 334 322 316 znaków
397 368 366 nieskompresowanych znaków
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')
Wymagany jest pojedynczy znak nowej linii, a policzyłem go jako jeden znak.
Mumbo jumbo strony kodowej przeglądarki może uniemożliwić pomyślne skopiowanie i wklejenie tego kodu, więc możesz opcjonalnie wygenerować plik z tego kodu:
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()))
Testowanie
intetris
[]
[]
[]
[]
[# # #]
[## ######]
[==========]
T2 Z6 I0 T7
Znaki nowej linii muszą być w stylu uniksowym (tylko znaki nowej linii). Końcowy znak nowej linii w ostatniej linii jest opcjonalny.
Testować:
> python golftris.py <intetris
[]
[]
[]
[# ###]
[# ###]
[##### ####]
[==========]
10
Ten kod rozpakowuje oryginalny kod i wykonuje go za pomocą exec
. Ten zdekompresowany kod waży 366 znaków i wygląda następująco:
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
Nowe linie są wymagane, a każda z nich ma jeden znak.
Nie próbuj czytać tego kodu. Nazwy zmiennych są dosłownie wybierane losowo w poszukiwaniu największej kompresji (przy różnych nazwach zmiennych widziałem aż 342 znaki po kompresji). Bardziej zrozumiała wersja jest następująca:
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
Sedno tkwi w trzech zagadkowych liniach, które powiedziałem, że wyjaśnię.
Kształt tetromino jest tam zakodowany w liczbie szesnastkowej. Uważa się, że każde tetronimo zajmuje siatkę komórek 3x4, gdzie każda komórka jest pusta (spacja) lub pełna (znak liczby). Każdy element jest następnie kodowany za pomocą 3 cyfr szesnastkowych, przy czym każda cyfra opisuje jedną kolumnę 4-komórkową. Najmniej znaczące cyfry opisują skrajne lewe kolumny, a najmniej znaczący bit w każdej cyfrze opisuje najwyższą komórkę w każdej kolumnie. Jeśli bit jest równy 0, to ta komórka jest pusta, w przeciwnym razie jest to „#”. Na przykład I tetronimo jest zakodowane jako 00F
, z czterema bitami najmniej znaczącej cyfry ustawionymi do kodowania czterech znaków liczbowych w skrajnej lewej kolumnie, a T jest131
, z górnym bitem ustawionym po lewej i prawej stronie, a dwa górne bity ustawione w środku.
Cała liczba szesnastkowa jest następnie przesuwana o jeden bit w lewo (pomnożona przez dwa). To pozwoli nam zignorować najniższy bit. Za minutę wyjaśnię dlaczego.
Więc biorąc pod uwagę bieżący fragment z wejścia, znajdujemy indeks w tej liczbie szesnastkowej, w której zaczyna się 12 bitów opisujących jego kształt, a następnie przesuwamy go w dół, tak aby bity 1–12 (przeskakując bit 0) bits
zmiennej opisywały bieżący kawałek.
Zadanie drop
określa, ile rzędów od góry siatki kawałek spadnie przed wylądowaniem na innych fragmentach kawałka. W pierwszym wierszu znajduje się liczba pustych komórek na górze każdej kolumny pola gry, a w drugim najniżej zajętej komórce w każdej kolumnie elementu. zip
Zwraca listę krotki, gdzie każdy krotkę składającą się z n -tego komórki z każdej pozycji z listy wejściowego. Tak więc, używając przykładowej karty wejściowej, zip(board[:6] + [full])
zwróci:
[
('[', '[', '[', '[', '[', '[', '['),
(' ', ' ', ' ', ' ', ' ', ' ', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', ' ', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(']', ']', ']', ']', ']', ']', ']')
]
Z tej listy wybieramy krotkę odpowiadającą odpowiedniej kolumnie i znajdujemy indeks pierwszej '#'
w kolumnie. Dlatego przed wywołaniem dodaliśmy „pełny” wiersz zip
, aby index
uzyskać sensowny zwrot (zamiast rzucać wyjątek), gdy kolumna jest pusta.
Następnie, aby znaleźć najniższą '#'
w każdej kolumnie elementu, przesuwamy i maskujemy cztery bity opisujące tę kolumnę, a następnie używamy bin
funkcji, aby przekształcić to w ciąg jedynek i zer. bin
Funkcja zwraca tylko znaczących bitów, więc potrzebujemy tylko obliczyć długość tego łańcucha, aby znaleźć najniższe zajętej komórki (najbardziej znaczący bit set). bin
Funkcja poprzedza również '0b'
, więc musimy odjąć to. Ignorujemy również najmniej znaczący fragment. Dlatego liczba szesnastkowa jest przesuwana o jeden bit w lewo. Ma to na celu uwzględnienie pustych kolumn, których reprezentacje łańcuchowe miałyby taką samą długość jak kolumna z pełną tylko górną komórką (na przykład element T ).
Na przykład, kolumny I Tetromino, jak wspomniano wcześniej, są F
, 0
i 0
. bin(0xF)
jest '0b1111'
. Po zignorowaniu '0b'
mamy długość 4, co jest poprawne. Ale bin(0x0)
jest 0b0
. Po zignorowaniu '0b'
nadal mamy długość '1, co jest niepoprawne. Aby to uwzględnić, dodaliśmy na końcu dodatkowy fragment, abyśmy mogli zignorować ten nieznaczący fragment. Stąd +3
w kodzie jest tam, aby uwzględnić dodatkową długość zajmowaną przez '0b'
początek i nieznaczny bit na końcu.
Wszystko to dzieje się w wyrażeniu generatora dla trzech kolumn ( (0,1,2)
), a my bierzemy min
wynik, aby znaleźć maksymalną liczbę wierszy, które może upuścić element, zanim dotknie dowolnej z trzech kolumn.
Reszta powinna być dość łatwa do zrozumienia, czytając kod, ale for
pętla następująca po tych przypisaniach dodaje element do tablicy. Następnie while
pętla usuwa pełne wiersze, zastępując je pustymi wierszami u góry i podlicza wynik. Na koniec plansza i punktacja są drukowane na wyjściu.