Bu hangi tetromino?


54

İmzasız bir 16 bit tam sayı N verildiğinde , sizin göreviniz, bir 4x4 matris içinde eşlenmiş olan ikili gösteriminin bir tetromino şekliyle eşleşip eşleşmediğini ve eğer öyleyse, onun şeklini belirlemek.

Matris

Her bir N biti bir 4x4 matris içinde, soldan sağa ve yukarıdan aşağıya, en kayda değerinden başlayarak eşlenir.

Örnek :

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

Tetromino şekilleri

Temel şekiller

O , I , S , Z , L , J ve T harfleriyle tanımlanan 7 tetromino şekli vardır :

tetrominoes

Rotasyonlar ve çeviriler

Bir şekil 4x4 matrisinde çevrilir ve / veya döndürülürse, yine de aynı tetromino için geçerli bir varyasyon olarak kabul edilir. Örneğin, 17600, 1136, 2272 ve 1604'ün tümü J tetromino olarak tanımlanmalıdır :

geçerli J örnekleri

Kaydırma!

Bununla birlikte, şekiller etrafa sarılamaz veya matrisin herhangi bir sınırının ötesine kaydırılamaz. Örneğin, ne 568 ne de 688, J tetromino olarak tanımlanmamalıdır (başka herhangi bir şekilde bırakılmamalıdır):

geçersiz J örnekleri

Açıklamalar ve kurallar

  • Girdiyi bir tam sayı olarak veya 2B dizi, düz bir dizi veya sınırlandırılmış bir dize gibi herhangi bir makul biçimde doğrudan 16 ikili basamak olarak alabilirsiniz.
  • Girişin imzasız bir 16 bit tam sayı (veya bunun bir dizi veya dize olarak eşdeğer gösterimi) olması garanti edilir.
  • Geçerli bir şekil tanımlandığında, şekli tanımlayan harfi küçük veya büyük harfle yazdırmanız veya iade etmeniz gerekir .
  • Şekil tanımlanmadıysa, herhangi bir tetromino harfiyle eşleşmeyen bir değer yazdırmanız veya döndürmeniz gerekir. Ayrıca hiçbir şey döndürmemeyi de seçebilirsiniz.
  • Geçerli sayılabilmesi için, matris, ilave hücre olmadan tam tetromino şeklini içermelidir (test durumlarında 1911 ve 34953'e bakınız).
  • Bu , yani bayt cinsinden en kısa cevap kazanır!

Test durumları

Test vakalarını 2D dizileri olarak almak için bu bağlantıyı takip edebilirsiniz .

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'

İlginç bir şekilde, geçen gün func1 . func2 . func3JS'de fonksiyon zincirleri kullanmak için bir teknik yaratırken
dikkatimi

Dört satır ile katıldı gibi ben giriş alabilir 0, yani 1111011110111101111için 65535?
ETHproductions

@ETHproductions Bu iyi görünüyor. Mücadeleyi biraz rahat bir giriş formatıyla düzenledim.
Arnauld,

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
Mühendis Tost,

^ Lynn'in Python 3 cevabı kullanılarak üretildi, çünkü uygun giriş / çıkış formatları vardı.
Mühendis Toast,

Yanıtlar:


6

Jöle ,  54 43 42  41 bayt

Outgolfer Erik sayesinde -1 bayt (tekrarlanan zincir içinde devrik geçiş)

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

2B tamsayı dizisi ( 1ler ve 0ler) alan ve oiszljtilgili tetromino için küçük bir harf döndüren veya wgeçersizse monadik bir bağlantı .

Çevrimiçi Deneyin! veya test odasına bakın .

Ayrıca , bu çıktılara göre sıralanmış olarak, çıktıları ile birlikte tam olarak dört bit bulunan 1820 olası 2B ikili dizilerin tümünü listeleyen bu programa bakın .

Nasıl?

Bu önce girişin dört dönüşünün tümünü alır. Sonra her birinin set bitlerini sağa, sonra da tabana mümkün olduğunca kaydırır ve sonuçları ikili sayılara dönüştürür. Daha sonra, her bir geçerli tetromino için bu tür minimal temsillerin bir listesindeki minimum sonucu arar ve azalmış sonucu , eşleşme bulunmadığında elde edilen iki birleştirilmiş sözlük kelimesine zoist+ indekslemek için kullanır .jowlw

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', ...)

Önceki yöntem (54 bayt)

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

2B tamsayı dizisi ( 1ler ve 0ler) alan ve oiszljtilgili tetromino için küçük bir harf döndüren veya wgeçersizse monadik bir bağlantı .

Çevrimiçi deneyin!

Bu, en az üç boş satır (satır + sütun) olduğunu ve belirli bit kalıplarının herhangi bir satırda bulunmadığını (özellikle 5,9,10,11 ve 13 sayıları) kontrol eder, bunlar birlikte bir sonraki adımı vermeyecektir yanlış-pozitif. Daha sonra düzleşir ve daha sonra dört dönüşün her birinin ikili sayısını (dönüşümden önce sondaki sıfırları sıyırarak) kaydırır ve birleştirilmiş iki sözlüğe dizine dönüştürmek için azaltılmış sonucu kullanarak sayılar listesinde minimum sonucu arar. zoist+ jowl, weşleşme bulunamadığında sonuç veriyor .



btw Bu kodun bir tesadüfe bağlı olduğunu düşünüyorum (çünkü zoistjowlnormalde başka bir dizgeye uymayacaktı: p)
Outgolfer Erik

"Tesadüflere bağlı" derken ne demek istiyorsun? (Sözlük araması ...Ṁị“LZOISTJWyine de yalnızca bir bayt kazandırır )
Jonathan Allan

Hmm ... evet, bunun uzun sürmeyeceğini biliyordum ... btw Sanırım çaldı ZU$3С: p
Outgolfer Erik

Önceki yöntemi gönderdikten sonra dün aynı yöntemi yapmaya çalışıyordum ama biraz yorgundum.
Jonathan Allan,

28

Python 3 , 124 bayt

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]

Çevrimiçi deneyin!

4 × 4'lük bir ikili matrisi temsil eden bir tamsayı n bekler . Tetromino bulunmazsa fırlatır.

Satır 2, 1 en sağ sütunda olana kadar şekli sağa kaydırır. (4369 0001 0001 0001 0001ikilidir.) Satır 3, 1 alt satırda olana kadar şeklini düşürür. Birlikte bu, örneğin döner:

    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

Sonra nbu listenin dizinini ararız:

 [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

Herbir indüktif modulo 7 indeks sütunu bir tetromino şekline karşılık gelir. 64 ( @), nkodun bu noktasında 64 olamayacağı için bir dolgu değeri olarak kullanılır .

NB. Giriş yapmak yerine 0hesaplama yaparak bir istisna atılır .n/n1


İkili dizginiz neden çalışıyor? Python 3'te bununla ilgili sorunum vardı, yorumlara bakın codegolf.stackexchange.com/a/85201/53667
Karl Napf

Python, kaynak kodu ve metin çıktısı için varsayılan kodlama olarak UTF-8'i kullanır. Ancak PPM dosyaları UTF-8'de okunmuyor . Çalıştırdığınızda print("ÿ"), yazılan bayt c3 bf 0adeğil ff 0a, PPM görüntüsü çöpe dönüşüyor.
Lynn,

8

APL (Dyalog) , 95 94 93 89 87 bayt

-2, Zacharý'ya teşekkürler

⎕IO←0Birçok sistemde varsayılan olanı gerektirir . Boolean matrisini (herhangi bir şekilde!) Argüman olarak alır. Belirtilen bit sayısı dört değilse ve verilen dört bit bir tetromino oluşturmazsa boş satır döndürür.

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

Çevrimiçi deneyin!

Girişin dört dönüşünün tümünü oluşturarak çalışır, ardından her dönüşte her tetrominoyu arar.

{} Argümanın aşağıdakilerle temsil edildiği anonim işlev :

,⍵ argümanı bozmak (düzleştirmek)

+/ topla

4= dört buna eşit mi?

: öyleyse, o zaman (başka hiçbir şey döndürmez):

  ⍳4 ilk dört ɩ ndices; [0,1,2,3]

  ⍵∘{ Girişi, soldaki değişken olarak sabit kullanarak, her birine aşağıdaki işlevi uygulayın

    sol argüman yani giriş

   ⊢⍺ verim ki (ayırır gelen )

   ⌽∘⍉⍣⍵ Ayna ve devrik (yani, 90 ° döndürmek) defa

  ()∘.⍷ Dış "ürün", ancak aşağıdaki listenin ve rotasyonların Bul * ile kullanılması:

   3↑1 birinden üç eleman al, sıfırlarla doldur; [1,0,0]

   K← bunu sakla K

    tablo (sütun vektörü haline getirin); [[1],[0],[0]]

   1, bir tane hazırlamak; [[1,1],[1,0],[1,0]]( "J")

   J← olarak sakla J

   ()⊖¨⊂ J'nin tamamını aşağıdaki adım sayısının her biri için dikey olarak döndürün:

    ⍳3 İlk üç ɩ ntegers;[0,1,2]

   biz var [[[1,1],[1,0],[1,0]],[[1,0],[1,0],[1,1]],[[1,0],[1,1],[1,0]]]("J", "L," T ")

   (), Aşağıdaki listeyi hazırla:

    2⊖JJdikey olarak iki adımı  döndürün ; [[1,0],[1,1],[1,0]]( "T")

    K⌽ satırlarını sırasıyla 1, 0 ve 0 adım döndürerek; [[0,1],[1,1],[1,0]]( "Z")

    0 1⌽¨⊂ dizinin tamamını, hiçbir zaman ve bir defa değil, dikey olarak döndürün; [[[0,1],[1,1],[1,0]],[[1,0],[1,1],[0,1]]] ("Z", "S")

    (), Aşağıdaki listeyi hazırla:

     (2 2)4⍴¨1 2 × 2 matris ve 4 elementli listenin bir tanesini yeniden şekillendirin; [[[1,1],[1,1]],[1,1,1,1]]("O", "Ben")

  1∊¨ her biri için bir üye mi?

  ∨/ yatay VEYA azaltma (yani rotasyonlar boyunca; her şekil için bir Boole)

  'OIZSLJT'/⍨ dizeyi filtrelemek için kullanın

* Bul, sol argümanla aynı tüm alt dizilerin sol üst köşesini belirtenlerle, sağ argümanıyla aynı şekilde bir Boolean dizisi döndürür.


Bu işe yarar mı? {4=+/,⍵:'OIZSJLT'/⍨∨/1∊¨(((2 2)4⍴¨1),(0 1⌽¨⊂K⌽2⊖J),(⍳3)⊖¨⊂J←1,⍪K←3↑1)∘.⍷⍵∘{⌽∘⍉⍣⍵⊢⍺}¨⍳4}
Zacharý,

@ Zacharý Evet, teşekkürler.
Adám

7

JavaScript (ES6), 242 212 172 164 bayt

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*$`))

Sadece topu yuvarlamak için olması gerekiyordu, ama bunun için biraz geç kaldım ¯ \ _ (ツ) _ / ¯

Sıralar 0s ile ayrılan ( '0001000110001000000'temsil eden 0001 0011 0010 0000) bir bit dizisini alır ve tetrominoyu temsil eden karakteri içeren bir dizi veya hiçbir şey içeren bir dizi döndürür.

Bu, herhangi bir noktadaki girişin, her iki taraftaki de tamamen sıfırlarla çevrili olan tetromino içerip içermediğini görmek için her tetromino dönüşünü kontrol ederek çalışır. Her tetromino bir veya daha fazla ikili sayı ile temsil edilir:

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

Girişin S Tetromino içeriyorsa Yani biz sadece o da ikili gösterimini içerip içermediğini kontrol kontrol etmek 51veya 2145yalnızca, 0iki tarafında s.

Tetrominoların birkaçı 4 yönelime sahiptir. Bunların ikili gösterimlerine bakarsanız, her biri diğer ikisinin aynası olan 2 gösterime sahiptir. Yerden tasarruf etmek için, ikili gösterim özyinelemeli Cişlevle aynı anda ileri ve geriye doğru kurulur ;


Charcodes ile alternatif yaklaşım:

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

Retina , 125 bayt

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#$^`

Çevrimiçi deneyin! Link, test durumları artı tamsayılardan 4 × 4'lük bir matrise dönüştürmek için bir başlık içerir. Açıklama:

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

5 1sn içeriyorsa girişi silin .

{s`.*1111.*
I

Girişin tüm dönüşlerini kontrol edin (aşağıya bakın). Giriş dört ardışık 1s içeriyorsa , bu birdir I.

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

Üç ardışık 1s artı üçü 1birinin altındaki bir sonraki satırda a içeriyorsa , ara karakterlerin sayısını uygun sonuç harfiyle eşleyin.

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

Benzer şekilde bir sonraki satırda iki bitişik 1s bitişiğindeki iki bitişik 1s.

T`2-90`S\OZ4-9

Ancak, aksi takdirde kullanılmayanları kullanarak dönüş sayısını sayın 0.

s`.*4.*

Çok fazla dönme gerçekleştirildiyse pes edin.

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

Diziyi çevir ve ters çevir, böylece döndür.


3

MATL , 60 bayt

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

Giriş, ;satır ayırıcı olarak kullanılan bir ikili 4 × 4 dizisidir (matris) . Çıkış, tetromino içermeyen bir harf veya boş.

Çevrimiçi deneyin! Veya tüm test durumlarını doğrulayın (çıktıda boş bir sonuç tanımlanmasına izin vermek için eklenmiş bir nokta var).

açıklama

Kod, giriş 4 × 4 dizisinin 4 dönüşünü 90 derecelik adımlarla oluşturur. Her döndürülmüş dizi, 2 × 8 yukarı ve aşağı doğru dizilir ve 8 × 4 dizisine dönüştürülür. 4 dizi dikey olarak 32 × 4 dizisine birleştirilir. Bu birleştirilmiş dizi içindeki dört döndürülmüş dizi, sıfır dolgusu sayesinde "izole edilmiştir".

7 olası örüntüden her biri, 32 × 4 dizisinde olup olmadığını görmek için test edilir. Bunun için bir döngü kullanılır. Her desen, ikili olarak ifade edilen ve 0/1 maskesini veren iki sayıyla tanımlanır. Örneğin, sayılar 3, 6"S" şeklini tanımlar.

7 sayıdan oluşan 2 küme, ilmekin her sütunu sırayla seçeceği 2x7 bir matris halinde düzenlenir. Matris, tüm sayıları yığına iterek, onları bir vektörde kontamine ederek ve 2 sıralı bir matriste yeniden şekillendirerek tanımlanır. "I" şekli 15 numara ve onu takip eden 0 ile tanımlandığından, sonuna koyarak 0'ın yeniden şekillendirme işlevi tarafından örtük olarak doldurulmasına izin verir.

Maske daha sonra dört yönde 3 sıfırla doldurulur. Girişteki istenmeyen değerleri tespit etmek için bu gereklidir.

Maskenin 32 × 4 dizisinde olup olmadığını görmek için, ikincisi bipolar forma dönüştürülür (yani, 0/1 yerine −1/1) ve maske ile kıvrılır. Maske 4'üne sahip olduğundan, evrişim sonucundaki bir girdi 4'e eşitse eşleşme gerçekleşir.

Döngünün sonunda, çoğu doğru olan 7 yanlış / doğru sonuç elde edildi. Bu, olası çıkış harflerini içeren bir dizgeye indekslemek için kullanılır.


3

Jöle , 53 bayt

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

Çevrimiçi deneyin!

Tam program 4x4 alır. Baskılar mdeğilse tetromino, aksi küçük harf yazdırır.


Bir dizi bit dizisini yasal olarak alıyor mu? Bu beni 40 bayt gibi kurtaracaktı
ETHproductions

@ETHproductions Girdileri bir tamsayı olarak veya doğrudan 2B 4x4 ikili rakam dizisi veya 16 ikili rakamdan oluşan düz bir dizi olarak alabilirsiniz.
Outgolfer Erik

Huh, şu soruyu cevaplamam için bana hizmet ediyor ...
ETHproductions

1

Perl 5 , 197 + 1 (-p) = 198 bayt

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".$_)}

Çevrimiçi deneyin!

Giriş olarak 16 bitlik bir dizge alır. Giriş tek bir tetromino değilse hiçbir şey çıkarmaz.

Nasıl?

İki sübstitüsyon giriş şeklini sağ alt köşeye "taşır". Sonuçta elde edilen bit dizgisi bir tamsayıya dönüştürülür, ardından geçerli bir tamsayılar karesinde kontrol edilir.


1

APL (Dyalog) , 66 bayt

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

Çevrimiçi deneyin!

Argü bir boolean vektörüdür.

Noktaların işaretli mesafelerini ağırlık merkezlerine kadar karmaşık sayılar (gerçek ve hayali kısım ∆x, ∆y) olarak hesaplar ve karmaşık sayıları bir araya getirir. Bu, tetrominoları ayırt etmek için yeterince iyi bir değişmez olduğu ortaya çıkıyor.


İlginç bir yöntem.
Arnauld,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.