1. ホーム
  2. language-agnostic

[解決済み] コードゴルフ:テトリスで遊ぶ

2023-06-13 02:23:13

質問

基本的なことです。

次のようなテトロミノと空の競技場を考えてみましょう。

                                            0123456789
    I O Z T L S J [ ](英語
                                           [ ]
    # ## ## ### # ## # [ ]
    # ## ## # # ## # [ ]
    # ## ## [ ]
    # [ ]
                                           [==========]

競技場の寸法は決まっています。上部にある数字は、列番号を示すためにここ は、列番号を示すためのものです(入力も参照)。

入力です。

1 . 特定の競技場(上記に基づく)が与えられ、それはすでにテトロミノで部分的に埋められる。 テトロミノで部分的に埋めることができます (これは別のファイルでも、標準入力で提供することもできます)。

サンプル入力。

[ ]
[ ]
[ ]
[ ]
[ # # #]
[ ## ######]


2 . どのテトロミノをどの列に挿入(ドロップダウン)するかを(スペースで区切って)記述した文字列が与えられます。 ドロップダウンさせるかを記述する文字列が与えられる。テトロミノは回転させる必要はない。入力は標準入力から読み込むことができる。

入力の例です。

T2 Z6 I0 T7

入力が「整形式」であると仮定することができます(そうでない場合は未定義の挙動を生成します)。

出力

結果のフィールドをレンダリングし(「完全な」行は消えなければなりません)、スコアカウントを表示します。 (消えた行は10点分)。

上記のサンプル入力に基づく出力例です。

[ ]
[ ]
[ ]
[# ###]
[# ### ]
[##### ####]

10

優勝者です。

最も短い解決策(コード文字数で)。使用例も良いですね。楽しいゴルフを!

Edit を大量に追加しました。 +500 の評価を追加し、回答者がすでに行った素晴らしい努力(そしておそらくこの質問に対する新しい解決策)にもう少し注意を払うようにしました...。

どのように解決するのですか?

ゴルフスクリプト - 181文字

改行は必要ありません。出力は標準出力ですが、一部のエラーは標準エラー出力に存在します。

\10 は、プログラムが181文字になるように、対応するASCII文字に置き換える必要があります。

{):X!-{2B{" #"=}%X" ":f*+-1%}%:P;:>.{\!:F;>P{\(@{3&\(@.2$&F|:F;|}%\+}%\+F![f]P+:P
;}do;{"= "&},.,7^.R+:R;[>0="#"/f*]*\+}0"R@1(XBc_""~\10"{base}:B/3/~4*"nIOZTLSJR "
";:"*~;n%)n*~ 10R*+n*

サンプルI/Oです。

$ cat inp
[          ]
[          ]
[          ]
[          ]
[ #    #  #]
[ ## ######]
[==========]
T2 Z6 I0 T7
$ cat inp|golfscript tetris.gs 2>/dev/null
[          ]
[          ]
[          ]
[#      ###]
[#     ### ]
[##### ####]
[==========]
10

テトロミノの圧縮。

ピースは3つのベース8桁として保存されます。これは単純なバイナリ表現で、例えば T=[7,2,0], S=[6,3,0], J=[2,2,3] . [1] が使われるのは I の部分が圧縮されますが、これは明示的に [1,1,1,1] に設定されます (つまり 4* というコードになります)。これらの配列はすべて1つの配列に連結され、整数に変換された後、文字列(印刷不可能な文字や長さを最小限に抑え、utf8に遭遇しないように126ベース)に変換されます。この文字列は非常に短い。 "R@1(XBc_" .

解凍は簡単です。まず 126 進数の変換を行い、次に 8 進数の変換を行います ( "~\10"{base}/ つまり "~\10" を繰り返し,各要素に対して基底変換を行います)。出来上がった配列は3つのグループに分けられます。 I は固定されます ( 3/~4* ). 次に、各要素を基底 2 に変換し、(ゼロを取り除いた後) 各 2 進数の数字を文字列中のそのインデックスの文字に置き換えます。 " #" ( 2base{" #"=}%...-1% - 配列を反転させる必要があることに注意してください。 2"# " ではなく " #" ).

ボード/ピース形式、ピースのドロップ

盤面は単純に文字列の配列で、1行に1つずつあります。これには初期状態では何の作業も行われないので、これを生成するために n/( を入力します。ピースも文字列の配列であり、X位置の左側にスペースを入れ、末尾にスペースを入れない。ピースは配列の先頭に追加され、衝突があるかどうか継続的にテストすることでドロップされます。

衝突テストは、ピース内のすべての文字を繰り返し、ボード上の同じ位置の文字と比較することによって行われます。私たちは # + = そして # + # を衝突として扱うので、((piecechar&3)&boardchar)が非ゼロかどうかをテストします。この繰り返しを行っている間、我々はまた、((piecechar&3)|boardchar)でボード(のコピー)を更新し、ペアのための値を正しく設定します。 # + , + # , + [ . 駒をもう一列下に移動させた後に衝突があった場合、この更新された盤面を使用します。

埋められた行を削除するのは非常に簡単です。すべての行を削除し、その中で "= "& が false を返す行を全て削除します。塗りつぶされた行には = または というように、接続詞は空白文字列となり、これは偽と等しくなります。次に、削除された行の数を数え、その数をスコアに加算して、その数の先頭に "[ ... ]" s. これをコンパクトにするために、グリッドの最初の行をとって # .

ボーナス

駒が落ちるときに、それぞれの位置で盤面がどのように見えるかを計算しているので、これらを削除する代わりにスタックに残しておくことができます! あと合計3文字でこれらの位置をすべて出力できます(ボード状態をシングルスペースにした場合は2文字です)。

{):X!-{2B{" #"=}%X" ":f*+-1%}%:P;:>.{>[f]P+:P(!:F;{\(@{3&\(@.2$&F|:F;|}%\+}%\+F!}
do;{"= "&},.,7^.R+:R;[>0="#"/f*]*\+}0"R@1(XBc_""~\10"{base}:B/3/~4*"nIOZTLSJR "
";:"*~;n%)n*~ ]{n*n.}/10R*