テトリスタングラム


13

前書き

タングラムは、ブロックをさまざまな形に配置/適合させる古典的なパズルです。中国の七巧板から-文字通り「7つのスキルボード」を意味します。このアイデアを活用して、7つのテトロミノスのピースを使用してグリッドを埋めましょう。

チャレンジ

入力としてグリッド座標の配列を受け取り、指定された座標を除き、テトリスの破片で満たされた10 x 20の完成したグリッドを出力する関数またはプログラムを作成します。

ピースの分布を均一に保つようにして、スコアを最適化します。

基準

この座標のペーストビンを使用し、タスクを完了します。5組の座標があります。座標を書き込む形式は自由に変更できますが、値は変更しないでください。

データセット#2は解決できません-この場合、入力セルが埋められた状態でグリッドを出力するだけです(つまり、X穴のある場所)。

入力

グリッド座標は、グリッドの「穴」を表します。これらはテトロミノの部分を含むことができないセルです。

グリッド座標:

(0,0), (1,0), (2,0), ... (9,0)
(0,1), (1,1), (2,1), ... (9,1)
.
.
.
(0,19), (1,19), (2,19), ... (9,19)
  • プログラミング言語の配列スタイルを使用して、座標を入力します。

  • Xまたはその他の印刷可能なASCIIでグリッドの穴を表します。

出力

幅10セル高さ20セルの標準テトリスグリッドサイズを使用して、Tetrominoピースを使用してグリッドを完全かつ完全に埋めることができる場合にのみ、ソリューショングリッドを印刷します。

手紙で構成小品IOLJTZSとして、次のとおりです。

I          
I          L      J
I    OO    L      J     T     ZZ      SS
I    OO    LL    JJ    TTT     ZZ    SS

入力座標のない出力ソリューションの例:

ZZIIIILLLI
JZZTTTLLLI
JJJSTLOOLI
SZZSSLOOLI
SSZZSLLJJI
TSOOSLLJII
TTOOSSLJII
TZOOSSLZII
ZZOOSSZZII
ZJJJJSZLLI
TTTJJOOILI
ITZJJOOILI
IZZTTTLIII
IZOOTZLIII
IJOOZZLLII
LJJJZSSTII
LLLTSSTTTI
LLLTTSSZJI
OOLTSSZZJI
OOIIIIZJJI

次のように配布します。

I          
I          L      J
I    OO    L      J     T     ZZ      SS
I    OO    LL    JJ    TTT     ZZ    SS

11   6     8     6      6     7      6

ノート

座標は、単一の表現XYグリッド上の位置を。グリッドは0ベースです。つまり、座標(0,0)は作成者が選択した左上または左下のいずれかのセルでなければなりません。

レンガができること:

  • 著者の裁量で選択されます。
  • 著者が適切だと思うように回転します。
  • 著者の裁量でグリッドのどこにでも配置できます(別名:テトリス重力なし)

レンガはできません:

  • グリッドの境界の外側に配置されます。
  • グリッド内の既存のレンガまたは穴に重なります。
  • 非標準のテトリステトロミノピースであること。

得点

スコアの形式は次のとおりです。

(1000-[コード内のバイト])*(M / 10 + 1)

Mは、ソリューションセットで使用されるピースの分布の乗数です。

3月のIdesによる最高得点。

Mを計算するには、各セットの最小の個々のテトロミノ分布値を追加し、平均を切り捨ててMを計算します。

例えば:

Set 1: 5
Set 2: 4
Set 3: 5
Set 4: 6
Set 5: 3

6 + 4 + 5 + 4 + 4 = 21/5 = 4.6

したがって4M値として使用します。

注:セットに解がない場合は、そのセットをMの計算に入れないでください。テトロミノ分布がないためです。


4
投稿後に質問を改善することは一般に困難です。変更が大きくなると、すでに問題に取り組んでいる(または、さらに悪いことに、結果を投稿する)人の作業が無効になるためです。チャレンジのアイデアをサンドボックスに投稿することをお勧めします。それは、フィードバックを求め、仕様がメインになる前に仕様を磨く場所です。そうは言っても、簡単なスキミングの後、あなたの挑戦に大きな問題は見られませんでした。
マーティンエンダー

@MartinBüttnerDulyは、フィードバックに感謝します。
CzarMatt

2
3月のID = 3月15日。私はそれを調べなければなりませんでした。
レベルリバーセント

タスクの説明をフロントロードするためにいくつかの小さな変更を加えました。そうしないと、最初の読み取りで何をするように求められているのか理解できないからです。どの入力ケースを解決できないかを指定すると、スコアリングデータセットに加えてテストケースとして機能するように改善されると思います。
ピーターテイラー

@PeterTaylorまあ、解決できないソリューションセットを追加しました。フィードバックをお寄せいただきありがとうございます。
CzarMatt

回答:


2

Python 3、819バイト、M = 0、スコア= 181

これはブルートフォースDFSプログラムです。numpy配列を構築し、入力されたすべての穴を挿入します。次に、最上位の行の左端の未充填タイルを取得し、テトロミノを配置します。再帰的に、私たちは再びそれを行います-解決策を見つけることができないか、最初の機会に戻って別の部分を試してみてください。

これは、決定された順序でピースを使用しようとするため、Mが0になり、ほとんどの場合、リストの最後のソリューションがないソリューションを見つけます。サイクルごとにランダムに順序付けされたリストを使用して、より均等な分布を作成しようとしましたが、Mが2 しかなかったため、random.shuffleをインポートするために必要なバイトの価値がありませんでした

私のゴルフでは、何ができるかを長い間忘れていたので、以下のコードはコメントできません。一般的な考え方:

  • numpyおよびitertools製品を1文字の名前でインポートします
  • 一部の組み込み関数の名前を1文字の関数に変更し、ラムダを定義してバイトを節約します
  • 可能なtetrominosの配列をnumpy nd-arrayとして構築します。すべての回転が含まれます
  • 再帰関数で:
    • 希望する塗りつぶされていないタイルの位置を取得し、ピースリストを循環します
    • 各ピースについて、その翻訳を循環します(上下に移動)
    • 何かがうまくいかない場合(ピースがボードから外れたり、別のピースにぶつかったり、穴にぶつかったりするなど)、次の翻訳または次のピース全体を試してください
    • それがうまくいけば、素晴らしい。それを試してから、関数を再帰的に呼び出します。
    • そのパスが機能しなかった場合、 'a'が返されるため、もう一度やり直します。うまくいった場合は、ボードを返し、ラインに渡します。
  • 最後に、プログラム。10x20ボードを1のnumpy配列として構築します。
  • 入力の形式は(x1、y1);(x2、y2); ...です。各穴に9を設定し、関数を実行した結果を取得します。
  • 次に、printステートメントは、成功した結果または空の元のボードを1行ずつ表示し、数字を適切な文字または記号に置き換えます。
import numpy as n
from itertools import product as e
m,s=range,len
p=[n.rot90(a,k)for a,r in[([[2,2]]*2,1),([[3]*3,[1,3,1]],4),([[0]*4],2),([[1,1,6],[6]*3],4),([[7,1,1],[7]*3],4),([[4,4,1],[1,4,4]],2),([[1,5,5],[5,5,1]],2)]for k in m(r)]
o=lambda a:e(m(s(a)),m(s(a[0])))
def t(l,d=0):
	g=list(zip(*n.where(l==1)))[0]
	for a in p:
		for u,v in o(a):
			w,x=l.copy(),0
			for r,c in o(a):
				if a[r,c]!=1:
					i,j=g[0]+r-u,g[1]+c-v
					if any([i<0,i>19,j<0,j>9])or l[i,j]!=1:
						x=1
						break
					w[i,j]=a[r,c]
			if x==0:
				if len(w[w==1]):
					f=t(w,d+1)
					if type(f)==str:continue
					return f
				return w
	return'a'
b=n.ones((20,10))
b[list(zip(*[eval(k)[::-1]for k in input().split(';')]))]=9
a=t(b)
for r in(a,b)[type(a)==str]:
	print(''.join(map(dict(zip([0,2,3,4,5,6,7,9,1],'IOTZSLJX-')).get,r)))

オンラインでお試しください!

サンプルテスト:

In: (1,1);(8,1);(4,4);(5,8);(4,11);(5,15);(1,18);(8,18)
Out: 
IIIIOOOOLL
TXOOOOOOXL
TTOOOOOOTL
TOOIOOOOTT
TOOIXOOTTI
TTTITOOTTI
TTTITTTTII
OOTTTTTTII
OOTTTXOOII
TTTTOOOOII
TTTTOOOOII
TTTTXTOOII
ITTTTTTTII
ITTTTTTTII
IITTTLLTTI
IITOOXLTTI
IITOOTLTTI
IITTLTTTTI
IXTLLTJTXI
ILLLLLJJJI

1
ああ、これはすごい。すばらしい記事と素晴らしい仕事をありがとう!
CzarMatt
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.