Python 2.6+ - 334 322 316 Zeichen
397 368 366 Zeichen unkomprimiert
#coding:l1
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')
Der einzelne Zeilenumbruch ist erforderlich, und ich habe ihn als ein Zeichen gezählt.
Mumbo-Jumbo auf der Browser-Codepage verhindert möglicherweise das erfolgreiche Kopieren und Einfügen dieses Codes, sodass Sie die Datei optional aus diesem Code generieren können:
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()))
Testen
intetris
[]
[]
[]
[]
[# # #]
[## ######]
[==========]
T2 Z6 I0 T7
Zeilenumbrüche müssen im Unix-Stil erfolgen (nur Zeilenvorschub). Ein nachfolgender Zeilenumbruch in der letzten Zeile ist optional.
Zu testen:
> python golftris.py <intetris
[]
[]
[]
[# ###]
[# ###]
[##### ####]
[==========]
10
Dieser Code entpackt den Originalcode und führt ihn mit aus exec
. Dieser dekomprimierte Code wiegt 366 Zeichen und sieht folgendermaßen aus:
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
Zeilenumbrüche sind erforderlich und bestehen jeweils aus einem Zeichen.
Versuchen Sie nicht, diesen Code zu lesen. Die Variablennamen werden auf der Suche nach der höchsten Komprimierung buchstäblich zufällig ausgewählt (bei verschiedenen Variablennamen habe ich nach der Komprimierung bis zu 342 Zeichen gesehen). Eine verständlichere Version folgt:
import sys
board = sys.stdin.readlines()
score = 0
blank = board[:1] # notice that I rely on the first line being blank
full = '[##########]\n'
for piece in board.pop().split():
column = int(piece[1]) + 1 # "+ 1" to skip the '[' at the start of the line
# explanation of these three lines after the code
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: # if the current cell should be a '#'
x = column + i / 4
y = drop + i % 4
board[y] = board[y][:x] + '#' + board[y][x + 1:]
while full in board: # if there is a full line,
score += 10 # score it,
board.remove(full) # remove it,
board = blank + board # and replace it with a blank line at top
print ''.join(board), score
Der Kern liegt in den drei kryptischen Zeilen, von denen ich sagte, dass ich sie erklären würde.
Die Form der Tetrominoes ist dort in der Hexadezimalzahl kodiert. Es wird angenommen, dass jedes Tetronimo ein 3x4-Gitter von Zellen einnimmt, wobei jede Zelle entweder leer (ein Leerzeichen) oder voll (ein Zahlenzeichen) ist. Jedes Stück wird dann mit 3 hexadezimalen Ziffern codiert, wobei jede Ziffer eine 4-Zellen-Spalte beschreibt. Die niedrigstwertigen Ziffern beschreiben die am weitesten links stehenden Spalten, und das niedrigstwertige Bit in jeder Ziffer beschreibt die oberste Zelle in jeder Spalte. Wenn ein Bit 0 ist, ist diese Zelle leer, andernfalls ist es ein '#'. Zum Beispiel wird das I- Tetronimo so codiert 00F
, dass die vier Bits der niedrigstwertigen Ziffer aktiviert sind , um die vier Zahlenzeichen in der Spalte ganz links zu codieren, und das T ist131
mit dem oberen Bit links und rechts und den beiden oberen Bits in der Mitte.
Die gesamte Hexadezimalzahl wird dann um ein Bit nach links verschoben (multipliziert mit zwei). Dadurch können wir das unterste Bit ignorieren. Ich werde gleich erklären, warum.
Wenn wir also das aktuelle Stück aus der Eingabe erhalten, finden wir den Index in dieser Hexadezimalzahl, in der die 12 Bits beginnen, die seine Form beschreiben, und verschieben ihn dann nach unten, sodass die Bits 1–12 (Überspringen von Bit 0) der bits
Variablen das aktuelle Stück beschreiben.
Die Zuordnung zu drop
bestimmt, wie viele Zeilen vom oberen Rand des Gitters das Stück fallen wird, bevor es auf anderen Stückfragmenten landet. In der ersten Zeile wird angegeben, wie viele leere Zellen sich oben in jeder Spalte des Spielfelds befinden, während in der zweiten Zeile die niedrigste belegte Zelle in jeder Spalte des Stücks angegeben wird. Die zip
Funktion gibt eine Liste von Tupeln zurück, wobei jedes Tupel aus der n- ten Zelle jedes Elements in der Eingabeliste besteht. Wenn Sie also die Sample-Eingangskarte verwenden, zip(board[:6] + [full])
wird Folgendes zurückgegeben:
[
('[', '[', '[', '[', '[', '[', '['),
(' ', ' ', ' ', ' ', ' ', ' ', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', ' ', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(']', ']', ']', ']', ']', ']', ']')
]
Wir wählen das Tupel aus dieser Liste aus, das der entsprechenden Spalte entspricht, und finden den Index des ersten '#'
in der Spalte. Aus diesem Grund haben wir vor dem Aufruf eine "vollständige" Zeile angehängt zip
, damit index
eine sinnvolle Rückgabe (anstatt eine Ausnahme auszulösen) erfolgt, wenn die Spalte ansonsten leer ist.
Um dann das niedrigste '#'
in jeder Spalte des Stücks zu finden, verschieben und maskieren wir die vier Bits, die diese Spalte beschreiben, und verwenden dann die bin
Funktion, um daraus eine Folge von Einsen und Nullen zu machen. Die bin
Funktion gibt nur signifikante Bits zurück, daher müssen wir nur die Länge dieser Zeichenfolge berechnen, um die niedrigste belegte Zelle (höchstwertiges gesetztes Bit) zu finden. Die bin
Funktion steht auch vor '0b'
, also müssen wir das subtrahieren. Wir ignorieren auch das niedrigstwertige Bit. Aus diesem Grund wird die Hexadezimalzahl um ein Bit nach links verschoben. Dies dient dazu, leere Spalten zu berücksichtigen, deren Zeichenfolgendarstellungen dieselbe Länge wie eine Spalte haben würden, in der nur die oberste Zelle voll ist (z. B. das T- Stück).
Zum Beispiel werden die Spalten der ich erwähnt tetromino, wie früher, sind F
, 0
und 0
. bin(0xF)
ist '0b1111'
. Nachdem '0b'
wir das ignoriert haben , haben wir eine Länge von 4, was richtig ist. Ist bin(0x0)
aber 0b0
. Nachdem '0b'
wir das ignoriert haben , haben wir immer noch eine Länge von '1, was falsch ist. Um dies zu berücksichtigen, haben wir am Ende ein zusätzliches Bit hinzugefügt, damit wir dieses unbedeutende Bit ignorieren können. Daher ist das +3
im Code dazu da, die zusätzliche Länge zu berücksichtigen, die '0b'
am Anfang und das unbedeutende Bit am Ende benötigt wird.
All dies geschieht innerhalb eines Generatorausdrucks für drei Spalten ( (0,1,2)
), und wir ermitteln min
anhand des Ergebnisses die maximale Anzahl von Zeilen, die das Stück ablegen kann, bevor es in einer der drei Spalten berührt wird.
Der Rest sollte durch Lesen des Codes ziemlich leicht zu verstehen sein, aber die for
Schleife, die diesen Zuweisungen folgt, fügt das Stück der Tafel hinzu. Danach while
entfernt die Schleife volle Zeilen, ersetzt sie durch leere Zeilen oben und zählt die Punktzahl. Am Ende werden die Tafel und die Partitur auf die Ausgabe gedruckt.