Pythonの2.6+ - 334の 322 316文字
397 368366文字非圧縮
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')
改行は1行必要で、1文字として数えています。
ブラウザのコードページの巨大なジャンボは、このコードのコピーアンドペーストの成功を妨げる可能性があるため、オプションで次のコードからファイルを生成できます。
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()))
テスト
インテトリス
[]
[]
[]
[]
[###]
[## ######]
[==========]
T2 Z6 I0 T7
改行はUnixスタイルである必要があります(改行のみ)。最後の行の末尾の改行はオプションです。
テストする:
> python Golftris.py <intetris
[]
[]
[]
[####]
[####]
[##### ####]
[==========]
10
このコードは元のコードを解凍し、で実行しexec
ます。この解凍されたコードの重量は366文字で、次のようになります。
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
改行は必須であり、それぞれ1文字です。
このコードを読もうとしないでください。変数名は、最高の圧縮を求めて文字通りランダムに選択されます(変数名が異なると、圧縮後に342文字も表示されました)。より理解しやすいバージョンは次のとおりです。
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
重要なのは、私が説明すると言った3つの不可解な行にあります。
テトロミノの形は16進数でエンコードされています。各テトロミノは、セルの3x4グリッドを占めると見なされ、各セルは空白(スペース)または完全(番号記号)のいずれかです。次に、各部分は3つの16進数でエンコードされ、各桁は1つの4セル列を表します。最下位桁は左端の列を表し、各桁の最下位ビットは各列の最上部のセルを表します。ビットが0の場合、そのセルは空白です。それ以外の場合は、「#」です。たとえば、I tetronimoはとしてエンコードされ00F
、最下位桁の4ビットがオンに設定されて左端の列の4つの番号記号がエンコードされます。Tは131
、上部のビットが左右に設定され、上部の2ビットが中央に設定されています。
次に、16進数全体が1ビット左にシフトされます(2が掛けられます)。これにより、最下位ビットを無視できます。その理由をすぐに説明します。
したがって、入力からの現在のピースが与えられると、その形状を表す12ビットが始まるこの16進数へのインデックスを見つけ、bits
変数のビット1〜12(ビット0をスキップ)が現在のピースを表すようにそれを下にシフトします。
drop
グリッドの上部からピースが他のピースフラグメントに着地する前にいくつの行になるかを決定するための割り当て。最初の行は、競技場の各列の上部にある空のセルの数を見つけ、2番目の行は、ピースの各列で最も低い占有セルを見つけます。このzip
関数はタプルのリストを返します。各タプルは、入力リストの各項目のn番目のセルで構成されます。したがって、サンプル入力ボードを使用すると、次のzip(board[:6] + [full])
ようになります。
[
('[', '[', '[', '[', '[', '[', '['),
(' ', ' ', ' ', ' ', ' ', ' ', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', ' ', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', ' ', '#', '#'),
(' ', ' ', ' ', ' ', '#', '#', '#'),
(']', ']', ']', ']', ']', ']', ']')
]
このリストから適切な列に対応するタプルを選択'#'
し、列の最初のインデックスを見つけます。これは、私たちが呼び出す前に、「フル」の行を追加する理由であるzip
ので、それはindex
列がそうでない場合は空白の場合(代わりに例外をスローする)賢明なリターンを持っています。
次に'#'
、ピースの各列の最低値を見つけるために、その列を表す4ビットをシフトしてマスクし、bin
関数を使用してそれを1と0の文字列に変換します。このbin
関数は有効ビットのみを返すため、この文字列の長さを計算するだけで、最下位のセル(最上位のセットビット)を見つけることができます。bin
機能も付加します'0b'
、我々はそれを減算する必要がありますので、。最下位ビットも無視します。これが、16進数が1ビット左にシフトする理由です。これは、空の列を考慮に入れるためです。空の列の文字列表現は、上部のセルのみがいっぱいの列(Tピースなど)と同じ長さになります。
例えば、列Iのテトロミノ、前述したようであり、F
、0
、および0
。 bin(0xF)
です'0b1111'
。を無視する'0b'
と、長さは4になります。これは正しいです。しかしbin(0x0)
です0b0
。を無視した後で'0b'
も、長さは '1であり、これは正しくありません。これを説明するために、この重要でないビットを無視できるように、最後にビットを追加しました。したがって、+3
コード内のinは'0b'
、最初にが占める余分な長さ、および最後にある重要でないビットを説明するためにあります。
これらはすべて、3つの列((0,1,2)
)のジェネレーター式内で発生し、min
その結果を取得して、3つの列のいずれかに接触する前にピースがドロップできる最大行数を見つけます。
残りはコードを読むことでかなり理解しやすいはずですが、for
これらの割り当てに続くループは、ボードにピースを追加します。この後、while
ループは完全な行を削除し、上部の空白行に置き換えて、スコアを集計します。最後に、ボードとスコアが出力に出力されます。