ブロック、スラブ、階段でその形状を作成できますか?


13

各セルを空(.)または完全(0)にすることができる長方形の2次元グリッドを考えます。

例えば

..00....
0000....
.00000..
000...00
..000000
000.00..

グリッドは無限と見なされ、描かれた領域外のすべてのセルは空です。

目標は、塗りつぶされたスペースをカバーし、それぞれがグリッドの4セル(2×2)を占める明確に形作られた7つのレンガのセットを使用して、空いているスペースを開いたままにすることです。

これらは7つのブリックです。

  • ブロック-1種類

    11
    11
    
  • スラブ-2種類

    ..
    22
    33
    ..
  • 階段-4種類

    .4
    44
    5.
    55
    66
    .6
    77
    7.

これらのブリックは常に、入力グリッドのセルの2倍の幅と高さのセルを持つグリッドに揃える必要があります。各ブリックはこの大きなグリッドの1つのセルしか占有できませんが、小さなグリッドを大きなグリッドの下に移動(上下、左、右に移動)して、カバーを見つけるためのオプションを増やすことができます。グリッドも個別のブリックも回転できません。

したがって、上記の例をカバーする(解決する)方法の1つは次のようになります。

..11....
2211....
.47733..
447...22
..771133
227.11..

(同一の隣接するレンガはまだあいまいさを引き起こす可能性がありますが、より大きなグリッドを注意深く識別することで解決します。)

無効なソリューション

000000
000000

566774
556744

レンガはすべて大きなグリッドに合わせて整列しているわけでも、1つのセルだけを占めているわけでもないからです。

ここでの有効な解決策は、3ブロック連続です:

111111
111111

また、別の有効なソリューションには6つのスラブが含まれます。

......
222222
333333
......

入力グリッドには複数のソリューションがあることに注意してください

無効なソリューション

00.00
00...

11.33
11...

レンガが大きなグリッドに整列しないためです。スラブは左または右に1つずつ移動する必要がありますが、もちろんカバーは不完全になります。この入力グリッドには解決策がありません

チャレンジ

対象となるグリッドを表す.のと0のテキストの長方形ブロックを(stdin /コマンドライン経由で)取り込むプログラムを作成します。

有効なカバーソリューションがある場合、上記と同じ方法でいずれかのソリューションを(stdoutを介して)印刷し、すべて0のを適切な1スルー7ブリックに置き換えます。

解決策がない場合、プログラムは何も出力せず、静かに正常に終了します。

ノート

  • 入力と出力は同じ長方形の寸法を持つ必要はありません。出力には、すべて.のの無関係な行や列を含めることができます(ソリューションを無効にしない限り)。

  • また.、塗りつぶされたスペースに影響しない場合は、すべての'の行と列をトリムしても問題ありません。例えば

    222222
    333333
    

    に有効なソリューションです

    000000
    000000
    

    逆に、2つの空の列を00..00削除することはできません。それは、埋められたスペースを乱すからです。

  • オプションで、入力の末尾に改行が1つあると想定することもできます。解決策がない場合でも、出力の単一の末尾の改行でも問題ありません。

  • 完全に空(すべて.)のグリッドと些細な0x0グリッドは、心配する必要がある入力ケースではありません。ただし、1×1 0グリッドは、少なくとも1つを含む他のすべてのグリッドと同様0です。(入力グリッドの幅または高さが均等であるとは思わないかもしれません!)

  • プログラムの代わりに、入力を文字列引数として受け取り、通常どおり出力を出力するか、文字列として返す関数を作成できます。どれfalsy値は解が存在しない場合に返すことができます。

  • の代わりに任意の9個の印刷可能なASCII文字を使用でき. 0 1 2 3 4 5 6 7ます。置換が何であるかを必ず言ってください!改行はそのままにしておく必要があります。

得点

バイト単位の最短コードが優先されます。Tiebreakerは、最も投票数の多い投稿です。

この課題は、Minecraftのブロックスラブ、および階段に触発されたもので、ここで説明したのと同じルールに従います。PPCGとMinecraft を楽しんでいるなら、PPCG Minecraft Serverをチェックアウトすることをお勧めします


3
Minecraftサーバーはゴルフスクリプトに実装されていないようです-退屈:
トーマスウェラー

5
@ThomasWeller数バイトを節約するためにCJamで再実装されました。
アレックスA.

回答:


6

Python- 525 491 478 430バイト

r=range
def t(s):
 m=s.find("\n")+1
 for q in r(4):
  try:
   for i in r(-q%2,m-1,2):
    for j in r(-q/2,len(s)/m,2):
     k,g=j*m+i,""
     b=[k,k+1,k+m,k+m+1]
     for z in b:g+=a(s,z)
     for z in b:
      if a(s,z)!="d":s=s[:z]+`dict(dddd=0,zzdd=3,ddzz=2,zzzd=7,zzdz=6,zdzz=5,dzzz=4,zzzz=1)[g]`+s[z+1:]
   return s
  except:d
def a(v,i):
 try:
  if v[i]!="\n":return v[i]
  return "d"
 except:return "d"

説明:これは私の最初のコードゴルフですので、最適ではないかもしれませんが、ここでそれがどのように機能するかを示します。関数t(s)は、渡された文字列の結果を提供します。まず、列の数を見つけてから、1(なし、左、上、左上)の4つの可能な個別の翻訳を通過し、解決を試みます。それぞれについて。各2x2ブロックを見て、辞書で指定された有効なブロック番号にマップし、ゼロをその番号に変更します。

辞書にないものが見つかると、その特定のオフセットを破棄し、次のオフセットからやり直します。有効なソリューションが見つからずに4つのオフセットすべてを通過すると、何も出力せずに終了します。a(v、i)は、文字列の外側のデフォルト値を許可し、改行文字を無視します。実行中に部分的な解決策になる可能性がありますが、最終的な正しい解決策が存在する場合は常にそれらを上書きします。

編集:文字の異なるマッピングが使用されます:。-> d、0-> z、他のすべての数字は自分自身に行きます。これは、入力と出力の両方に適用されます。


1
PPCGへようこそ!Pythonゴルフをするためのヒントがあります。これにより、いくつかのバイトを節約できると思います。
リルトシアスト
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.