これはどのテトロミノですか?


54

符号なし16ビット整数Nが与えられた場合、タスクは、4x4行列内にマッピングされたバイナリ表現がtetromino形状と一致するかどうかを判断し、一致する場合は、その形状を判断することです。

マトリックス

Nの各ビットは、左から右、上から下に4x4マトリックス内でマッピングされ、最上位のものから始まります。

N = 17600
binary representation: 0100010011000000
matrix: [ [ 0, 1, 0, 0 ],
          [ 0, 1, 0, 0 ],
          [ 1, 1, 0, 0 ],
          [ 0, 0, 0, 0 ] ]

テトロミノの形

ベース形状

文字OISZLJ、およびTで識別される7つのテトロミノ形状があります。

テトロミノ

ローテーションと翻訳

形状が4x4マトリックス内で平行移動および/または回転した場合でも、同じテトロミノの有効なバリエーションと見なされます。たとえば、17600、1136、2272、および1604はすべてJ tetrominoes として識別される必要があります。

有効なJの例

ラップしないでください!

ただし、形状は、マトリックスの境界をラップしたり、マトリックスの境界を超えてシフトしたりすることはできません。例えば、どちらも 568 688として識別されなければならないJの tetrominoes(ましてや他の任意の形状):

無効なJの例

明確化と規則

  • 入力は整数として、または2D配列、フラット配列、区切り文字列などの適切な形式の16桁の2進数として直接受け取ることができます。
  • 入力は、符号なし16ビット整数(または配列または文字列としての同等の表現)であることが保証されています。
  • 有効な形状が識別されたら、形状を識別する文字を大文字または小文字で印刷または返送する必要があります。
  • 形状が識別されない場合は、テトロミノ文字と一致しない値を印刷または返す必要があります。また、何も返さないことも選択できます。
  • 有効と見なされるには、マトリックスに追加のセルを含まない正確なテトロミノ形状が含まれている必要があります(テストケースの1911および34953を参照)。
  • これはなので、バイト単位の最短回答が勝ちです!

テストケース

このリンクたどって、テストケースを2D配列として取得できます。

0      -> false
50     -> false
51     -> 'O'
1911   -> false
15     -> 'I'
34952  -> 'I'
34953  -> false
1122   -> 'S'
3168   -> 'Z'
785    -> 'L'
1136   -> 'J'
568    -> false
688    -> false
35968  -> 'T'
19520  -> 'T'

興味深いことに、func1 . func2 . func3JSで関数チェーンを使用するためのテクニックを作成する気が散る前に、先日、非常に似た問題に取り組んでいました:P
ETHproductions

で結合された4つの行0、つまり1111011110111101111for として入力を取得できます65535か?
-ETHproductions

@ETHproductionsそれは素晴らしいようです。少しリラックスした入力形式でチャレンジを編集しました。
アーナルド

3
I:15,240,3840,4369,8738,17476,34952,61440J:71,113,142,226,275,550,802,1100,1136,1604,1808,2272,3208,3616,4400,8800,12832,17600,18176,25664,28928,36352,51328,57856L:23,46,116,232,368,547,736,785,1094,1570,1856,2188,3140,3712,5888,8752,11776,12560,17504,25120,29696,35008,50240,59392O:51,102,204,816,1632,3264,13056,26112,52224S:54,108,561,864,1122,1728,2244,8976,13824,17952,27648,35904T:39,78,114,228,305,562,610,624,1124,1220,1248,1824,2248,3648,4880,8992,9760,9984,17984,19520,19968,29184,35968,58368Z:99,198,306,612,1224,1584,3168,4896,9792,19584,25344,50688
エンジニアトースト

^ LynnのPython 3回答を使用して生成されました。これは、便利な入力/出力形式があるためです。
エンジニアトースト

回答:


6

ゼリー 54 43 42  41 バイト

Erik the Outgolferのおかげで-1バイト(転置を繰り返しチェーン内に移動)

T€FṀ⁸ṙ€Zµ⁺F
ZU$3СǀḄṂ“çc3Ð6'G‘i’ị“¥Çıƭ⁵»

整数の2D配列(1sおよび0s)をoiszljt受け取り、それぞれのtetrominoまたはw無効な場合に小文字を返すモナドリンク。

オンラインでお試しください!またはテストスイートをご覧ください。

また、これらの出力でソートされた出力とともに正確に4ビットが設定された1820のすべての2Dバイナリ配列をリストするこのプログラムを参照してください。

どうやって?

これは最初に入力の4つの回転すべてを取ります。次に、各ビットの設定ビットを右に、次に下に可能な限りシフトし、結果を2進数に変換します。これは、各有効テトロミノの最小このような表現のリストで最小の結果を検索二連結辞書単語にインデックスデクリメント結果を用いzoist+ jowl得、w一致するものが見つからなかった場合。

T€FṀ⁸ṙ€Zµ⁺F - Link 1, shift set bits right & then down : list of lists of bits          
        µ⁺  - perform the following twice, 1st with x=input, then with x=result of that):
T€          -   truthy indexes of €ach
  F         -   flatten into a single list
   Ṁ        -   maximum (the index of the right-most bit)
    ⁸       -   chain's left argument, x
     ṙ€     -   rotate €ach left by that amount
       Z    -   transpose the result
          F - flatten (avoids an € in the main link moving this into here)

ZU$3СǀḄṂ“çc3Ð6'G‘i’ị“¥Çıƭ⁵» - Main link: list of lists of bits (the integers 0 or 1)
   3С                        - repeat this 3 times collecting the 4 results:
  $                           -   last two links as a monad:
Z                             -     transpose
 U                            -     upend (reverse each) -- net effect rotate 90° CW
      Ç€                      - call the last link as a monad for €ach
        Ḅ                     - convert from binary (vectorises)
         Ṃ                    - minimum (of the four results)
          “çc3Ð6'G‘           - code-page indexes = [23,99,51,15,54,39,71]
                              -   ...the minimal such results for l,z,o,i,s,t,j shapes
                   i          - 1-based index of minimum in there or 0 if not found
                    ’         - decrement
                      “¥Çıƭ⁵» - compressed words: "zoist"+"jowl" = "zoistjowl"
                     ị        - index into (1 indexed & modular, so -1 yields 'w',
                              -             0 yields 'l', 1 yields 'z', ...)

以前の方法(54バイト)

Fœr0Ḅ“çc3Ðñ'G‘i
;Z$Ḅ©f“¦µ½¿Æ‘ȯ®¬S>2ȧZU$3СǀṀ’ị“¥Çıƭ⁵»

整数の2D配列(1sおよび0s)をoiszljt受け取り、それぞれのtetrominoまたはw無効な場合に小文字を返すモナドリンク。

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

これは、少なくとも3つの空行(行+列)があり、特定のビットパターンがどの行にも存在しないこと(具体的には番号5、9、10、11、および13)をチェックします。偽陽性。次に、4つの各回転の2進数を(変換前に末尾のゼロをストライピングすることによって)フラット化してからフロアシフトし、デクリメントされた結果を使用して2つの連結された辞書ワードにインデックスを付けて、数値のリストで最小の結果を検索しますzoist+ jowlw一致が見つからなかった場合の結果。


そして、ハードコーディングよりも良い方法があることを知っていました...
エリックアウトゴルファー

ところで、このコードは偶然の一致に依存すると思います(zoistjowlそうでなければ、そうでなければ通常は文字列に収まらないからです:p)
Erik the Outgolfer

「偶然に依存する」とはどういう意味ですか?(...Ṁị“LZOISTJWとにかく辞書検索は1バイトしか保存しません)
ジョナサンアラン

うーん...ええ、私は、これは長くは続かないだろう知っていた...ところで、私はあなたが私を盗んだと思うZU$3С:P
エリックOutgolfer

昨日同じ方法を試しましたが、前の方法を送信した後、少し疲れていたと思います。
ジョナサンアラン

28

Python 3、124バイト

def f(n):
 while n&4369<n/n:n>>=1
 while n&15<1:n>>=4
 return'TJLZSIO'["rēȣc63ıGtIJȱᄑ@'̢̑@@@@Ȳq".index(chr(n))%7]

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

4×4のバイナリマトリックスを表す整数nが必要です。テトロミノが見つからない場合にスローされます。

行2は、右端の列に1が表示されるまで、図形を右にスライドさせます。(4369は0001 0001 0001 00012進数です。)行3は、1が一番下の行になるまで形状を下げます。一緒にこれは例えば次のようになります:

    0 1 0 0        0 0 0 0
    1 1 1 0  into  0 0 0 0
    0 0 0 0        0 0 1 0
    0 0 0 0        0 1 1 1

次にn、このリストでのインデックスを探します:

 [114  275  547   99   54   15   51
  305   71  116  306  561 4369   64
   39  802  785   64   64   64   64
  562  113   23]
#   T    J    L    Z    S    I    O

7を法とするインデックスの各列は、テトロミノ形状に対応します。64(@)はn、コードのこの時点では64にできないため、パディング値として使用されます。

NB。の代わりに0コンピューティングによって入力に対して例外がスローされます。n/n1


バイナリ文字列が機能するのはなぜですか?Python 3で問題が発生しました。コメントを参照してくださいcodegolf.stackexchange.com/a/85201/53667
Karl Napf

Pythonは、ソースコードおよびテキスト出力のデフォルトエンコーディングとしてUTF-8を使用します。ただし、PPMファイルはUTF-8で読み取られません。を実行するprint("ÿ")と、書き込まれるバイトはc3 bf 0aでなくff 0a、PPMイメージがゴミになります。
リン

8

APL(Dyalog)95 94 93 89 87バイト

-2 ザカリーのおかげ

⎕IO←0多くのシステムでデフォルトである必要があります。(任意の形状の)ブール行列を引数として取ります。指定されたビット数が4でない場合は何も返しません。指定された4ビットがテトロミノを形成しない場合は空行を返します。

{4=+/,⍵:'OIZSJLT'/⍨∨/1∊¨(((2 2)4⍴¨1),(0 1⌽¨⊂K2J),(⍳3)⊖¨⊂J1,⍪K31)∘.⍷⍵∘{⌽∘⍉⍣⍵⊢⍺}¨⍳4}

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

入力の4つの回転すべてを作成し、各回転で各テトロミノを検索することにより機能します。

{... } 引数が表され無名関数

,⍵ 引数を解く(平坦化)

+/ それを合計する

4= 4はそれに等しいですか?

: もしそうなら、(そうでなければ何も返さない):

  ⍳4 最初の4つのɩndices ; [0,1,2,3]

  ⍵∘{ 入力を固定左引数として使用して、それぞれに次の関数を適用します

    左の引数、つまり入力

   ⊢⍺ その結果(から分離

   ⌽∘⍉⍣⍵ ミラーリングおよび転置(90°回転)

  ()∘.⍷ 外側の「製品」ですが、次のリストとローテーションのFind *を使用します。

   3↑1 1つから3つの要素を取得し、ゼロでパディングします。 [1,0,0]

   K← として保存する K

    テーブル(列ベクトルにする); [[1],[0],[0]]

   1, 1つ追加します。[[1,1],[1,0],[1,0]](「J」)

   J← として保存 J

   ()⊖¨⊂ J全体を垂直に回転させます。各ステップは次のステップ数です。

    ⍳3 最初の3つのɩ整数。[0,1,2]

   あります[[[1,1],[1,0],[1,0]],[[1,0],[1,0],[1,1]],[[1,0],[1,1],[1,0]]](「J」、「L、「T」)

   (), 次のリストを追加します。

    2⊖JJ垂直方向に2ステップ 回転します。[[1,0],[1,1],[1,0]](「T」)

    K⌽ その行をそれぞれ1、0、および0ステップ回転します。[[0,1],[1,1],[1,0]](「Z」)

    0 1⌽¨⊂ 配列全体を垂直に回転させます。[[[0,1],[1,1],[1,0]],[[1,0],[1,1],[0,1]]] (「Z」、「S」)

    (), 次のリストを追加します。

     (2 2)4⍴¨1 1を2×2行列と4要素リストのそれぞれに変形します。[[[1,1],[1,1]],[1,1,1,1]](「O」、「I」)

  1∊¨ それぞれについて、1つはメンバーですか?

  ∨/ 水平方向のOR削減(つまり、回転間、形状ごとに1つのブール値)

  'OIZSLJT'/⍨ それを使用して文字列をフィルタリングします

* Findは、右引数と同じ形状のブール配列を返します。1つは、左引数と同一のすべてのサブ配列の左上隅を示します。


これは機能しますか?{4=+/,⍵:'OIZSJLT'/⍨∨/1∊¨(((2 2)4⍴¨1),(0 1⌽¨⊂K⌽2⊖J),(⍳3)⊖¨⊂J←1,⍪K←3↑1)∘.⍷⍵∘{⌽∘⍉⍣⍵⊢⍺}¨⍳4}
ザカリー

@Zacharýはい、ありがとう、できました。
アダム

7

JavaScript(ES6)、242 212 172 164バイト

x=>[...'OISZLJT'].filter((z,y)=>x.match(`^0*(${'99,33825|15,51|2145,195|561,2115|57,1059|135,71|1073'.split`,`[y].replace(/\d+/g,C=x=>x?x%2+C(x>>1)+x%2:'|')})0*$`))

ボールを転がすだけのはずだったのですが、そのために少し遅れました¯\ _(ツ)_ /¯

行が0s(を'0001000110001000000'表す0001 0011 0010 0000)で区切られたビットの文字列を取り、tetrominoを表す文字を含む配列、または何も含まない配列を返します。

これは、tetrominoの各回転をチェックして、いずれかのポイントの入力に、両側がゼロで完全に囲まれたtetrominoが含まれているかどうかを確認することで機能します。各テトロミノは、1つ以上の2進数で表されます。

0 0 0 0   -> 0000 0110 1100 0000
0 1 1 0   -> 0000001100110000000
1 1 0 0   -> 110011
0 0 0 0   -> 51

0 1 0 0   -> 0100 0110 0010 0000
0 1 1 0   -> 0100001100001000000
0 0 1 0   -> 100001100001
0 0 0 0   -> 2145

したがって、入力にS tetrominoが含まれているかどうかを確認するには、どちらかの側にs のみが含まれる、51またはのバイナリ表現が含まれているかどうかを確認する2145だけ0です。

いくつかのテトロミノには4つの方向があります。これらのバイナリ表現を見ると、それぞれに2つの表現があり、これらは単に他の2つの表現のミラーです。スペースを節約するために、2進表現は再帰C関数と同時に前方および後方に構築され、2つの方向のみを入れて、他の2つの方向を暗示することができます。


文字コードを使用した代替アプローチ:

x=>[...'OISZLJT'].filter((z,y)=>x.match(`^0*(${[...'÷,êÿ,óî,ûÝ,ëúüÏ,çöïþ,ßýíÞ'.split`,`[y]].map(c=>(C=n=>n?'1e'+(n%4+2)%5-0+C(n>>2):'')(c.charCodeAt())).join`|`})0*$`))

3

網膜、125バイト

s`(.*1){5}.*

{s`.*1111.*
I
s`.*111(.{2,4})1.*
$.1
T`234`\LTJ
s`.*11(.{2,4})11.*
$.1
T`2-90`S\OZ4-9
s`.*4.*

O#$`.
$.%`
O#$^`

オンラインでお試しください!リンクには、テストケースに加えて、整数から4×4マトリックスに変換するヘッダーが含まれています。説明:

s`(.*1){5}.*

5が含まれている場合は入力を削除します1

{s`.*1111.*
I

入力のすべての回転を確認します(以下を参照)。入力に4つの連続したが含まれる場合1、それはIです。

s`.*111(.{2,4})1.*
$.1
T`234`\LTJ

3つの連続した1sと3 1つのうちの1つの下の次の行にa が含まれている場合、中間文字の数を適切な結果文字にマップします。

s`.*11(.{2,4})11.*
$.1

同様に、次の行の2つの隣接する1sに隣接する2つの隣接する1sについても同様です。

T`2-90`S\OZ4-9

ただし、そうでない場合は0s を使用して、回転数のカウントを保持します。

s`.*4.*

あまりにも多くの回転が実行された場合、あきらめます。

O#$`.
$.%`
O#$^`

配列を転置および反転して、回転させます。


3

MATL、60バイト

Itt6tIl7tl7H15vHe"4:"G@X!HYa]4$v@BIthYaEqY+4=aa]v'OSZLJTI'w)

入力は、;行セパレーターとして使用するバイナリ4×4配列(マトリックス)です。Ouputは、テトロミノがない場合は文字または空です。

オンラインでお試しください!または、すべてのテストケースを検証します(空の結果を識別するために、出力にドットが追加されます)。

説明

コードは、90度単位で入力4×4配列の4回転を構築します。回転した各配列には、上下に2つのゼロが埋め込まれ、8 x 4配列に変換されます。4つの配列は、垂直に連結されて32×4配列になります。この連結配列内の4つの回転配列は、ゼロパディングのおかげで「分離」されます。

7つの可能なパターンのそれぞれをテストして、32×4配列に存在するかどうかを確認します。これにはループが使用されます。各パターンは2つの数値で定義され、2進数で表されて適切な0/1マスクを与えます。例えば、数字は36「S」形状を画定します。

2つの数字の7つのセットは2×7のマトリックスに配置され、そこからループが各列を順番に選択します。マトリックスは、すべての数値をスタックにプッシュし、それらをベクトルに汚染し、2行のマトリックスに再形成することによって定義されます。「I」シェイプは15の後に0が続くので定義されるので、最後に配置すると、0が再形成関数によって暗黙的に満たされます。

次に、マスクに4つの方向に3つのゼロが埋め込まれます。これは、入力内の不要な値を検出するために必要です。

32×4配列にマスクが存在するかどうかを確認するために、後者は双極型(つまり0/1ではなく-1/1)に変換され、マスクと畳み込まれます。マスクには4つの1があるため、畳み込み結果の一部のエントリが4に等しい場合に一致が発生します。

ループの終わりに、7つのfalse / trueの結果が得られましたが、そのうちの1つだけがtrueです。これは、可能な出力文字を含む文字列にインデックスを付けるために使用されます。


3

ゼリー、53バ​​イト

ZL0ẋW⁸tZµ⁺ZU$3С“©©“œ“Ç¿“¦©¦“ƽ‘;Uḃ2$’¤iЀṀị“÷¶Ė¡µỵỤ»

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

完全なプログラム。4x4を取ります。プリントmでない場合テトロミノは、そうでない場合は小文字を出力します。


...は、ビットの配列の配列を使用できますか?それで40バイト
くらい

@ETHproductions 入力は整数として、または4x4の2進数の2D配列または16進数のフラット配列として直接
エリックアウトゴルファー


1

Perl 5、197 + 1(-p)= 198バイト

s/(0000)*$//;1while s/(...)0(...)0(...)0(...)0/0${1}0${2}0${3}0${4}/;$_={51,O,15,I,4369,I,54,S,561,S,99,Z,306,Z,547,L,23,L,785,L,116,L,275,J,113,J,802,J,71,J,114,T,562,T,39,T,609,T}->{oct("0b".$_)}

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

入力として16ビット文字列を受け取ります。入力が単一のtetrominoでない場合は何も出力しません。

どうやって?

2つの置換は、入力図形を右下隅に「移動」します。結果のビット文字列は整数に変換され、有効な整数のハッシュでチェックされます。


1

APL(Dyalog)、66バイト

{'TIOJSLZ-'[(¯51 144 64,,∘+⍨12J96 ¯48J64)⍳×/(+/-4×⊢)⍵/,0j1⊥¨⍳4 4]}

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

argはブールベクトルです。

ドットの重心までの符号付き距離を複素数(実数部と虚数部は∆x、∆y)として計算し、複素数を乗算します。これは、テトロミノを区別するのに十分な不変量であることがわかりました。


興味深い方法。
アーナルド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.