Який це тетроміно?


54

Враховуючи неподписане 16-бітове ціле число N , ваше завдання - визначити, чи відповідає його бінарне представлення, відображене у матриці 4x4, тетроміно форми , і якщо так, то яка форма.

Матриця

Кожен біт N відображається всередині матриці 4x4, зліва направо і зверху вниз, починаючи з найбільш значущої.

Приклад :

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

Форми тетроміно

Основні форми

Існує 7 тетроміно фігур, ідентифікованих літерами O , I , S , Z , L , J і T :

тетроміно

Обертання та переклади

Якщо форма перекладається та / або обертається в межах матриці 4x4, вона все ще вважається дійсною варіацією того ж тетроміно. Наприклад, 17600, 1136, 2272 і 1604 усі повинні бути ідентифіковані як J тетроміно:

дійсні приклади J

Не загортайте!

Однак фігури не можуть обернутися або зміститися за межі будь-якої межі матриці. Наприклад, ні 568, ні 688 не повинні бути ідентифіковані як J тетроміно (не кажучи вже про будь-яку іншу форму):

недійсні приклади J

Роз'яснення та правила

  • Ви можете приймати введення як ціле число, або безпосередньо як 16 двійкових цифр у будь-якому розумному форматі, наприклад, 2D масив, плоский масив або обмежений рядок.
  • Гарантоване введення буде 16-бітним цілим числом без підпису (або його еквівалентним поданням у вигляді масиву чи рядка).
  • Коли ідентифікована правильна форма, ви повинні надрукувати або повернути лист, що ідентифікує форму, в нижньому або верхньому регістрі.
  • Якщо жодна форма не визначена, ви повинні надрукувати або повернути значення, яке не відповідає жодній літрі тетроміно. Ви також можете взагалі нічого не повернути.
  • Щоб вважати дійсним, матриця повинна містити точну форму тетроміно без додаткових комірок (див. 1911 та 34953 у тестових випадках).
  • Це , тому найкоротша відповідь у байтах виграє!

Тестові кейси

Ви можете перейти за цим посиланням, щоб отримати тестові випадки у вигляді двовимірних масивів.

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 . func3у JS: P
ETHproductions

Чи можу я взяти введення як з'єднані чотири рядки 0, тобто 1111011110111101111для 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 байт

-1 байт завдяки Еріку Поверху (рух переміщуємо всередину повторного ланцюга)

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

Монадічне посилання, що приймає 2D масив цілих чисел ( 1s і 0s) і повертає малі літери oiszljtдля відповідного тетроміно або wякщо недійсне.

Спробуйте в Інтернеті! або побачити тестовий набір .

Також дивіться цю програму, в якій перераховані всі 1820 можливих двовимірних двійкових масивів з рівно чотирма бітами, встановленими разом з їхніми виходами, відсортованими за тими виходами.

Як?

При цьому спочатку проводяться всі чотири обертання вводу. Потім він зміщує встановлені біти кожного праворуч, а потім якомога далі донизу і перетворює результати у двійкові числа. Потім він шукає мінімальний результат у списку мінімальних таких представлень кожного дійсного тетроміно та використовує зменшений результат для індексації у два об'єднаних словника слова 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для відповідного тетроміно або wякщо недійсне.

Спробуйте в Інтернеті!

Ці перевірки є принаймні трьома порожніми рядками (рядки + стовпці) і що певні шаблони бітів відсутні в жодному рядку (конкретно числа 5,9,10,11 та 13), вони разом забезпечують наступний крок прибутковості хибнопозитивні. Потім він згладжується, а потім зміщує двійкове число (шляхом виведення нульових знаків перед перетворенням) кожного з чотирьох обертів і шукає мінімальний результат у списку чисел, використовуючи зменшений результат, щоб індексувати два слова зв'язаних словника. zoist+ jowl, поступаючись, wколи не знайдено відповідності.


І я знав, що є кращий спосіб, ніж жорстке кодування ...
Ерік Вихідний,

btw Я думаю, що цей код залежить від збігу випадків (тому що, ну, zoistjowlяк правило, не підходить для рядка: p)
Erik the Outgolfer

Що ви маєте на увазі "залежить від збігу"? (пошук словника в ...Ṁị“LZOISTJWбудь-якому випадку зберігає лише один байт )
Джонатан Аллан

Хм ... так, я знав, що це не триватиме довго ... Доречі, я думаю, ти вкрав мою ZU$3С: p
Ерік Вигнавець

Я намагався зробити той же метод вчора після подання попереднього, але думаю, що я трохи втомився.
Джонатан Аллан

28

Пітон 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]

Спробуйте в Інтернеті!

Очікує ціле число n, що представляє двійкову матрицю 4 × 4. Кидає, якщо тетроміно не знайдено.

Рядок 2 ковзає фігуру праворуч, поки 1 не знаходиться в крайньому правому стовпчику. (4369 є 0001 0001 0001 0001двійковим.) Рядок 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/nзамість 1.


Чому працює ваш двійковий рядок? У мене виникли проблеми з 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 (Діалог) , 95 94 93 89 87 байт

-2 завдяки Захарі

Потрібно, ⎕IO←0що для багатьох систем за замовчуванням. В якості аргументу береться булева матриця (будь-якої форми!) Повертає нічого, якщо задана кількість біт не чотири, і порожній рядок, якщо чотири задані біти не утворюють тетроміно.

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

Спробуйте в Інтернеті!

Працює, створюючи всі чотири обертання вводу, потім шукаючи кожне тетроміно в кожному обертанні.

{} Анонімна функція, де аргумент представлений :

,⍵ згорнути (згладити) аргумент

+/ підсумуйте

4= чотири дорівнює цьому?

: якщо так, то (інакше нічого не повертайте):

  ⍳4 Перші чотири ɩ ndices; [0,1,2,3]

  ⍵∘{ Застосувати наступну функцію до кожного, використовуючи введення як фіксований лівий аргумент

    лівий аргумент, тобто вхід

   ⊢⍺ урожай, який (відокремлюється від )

   ⌽∘⍉⍣⍵ віддзеркалити та перемістити (тобто повернути на 90 °) разів

  ()∘.⍷ Зовнішній "продукт", але з використанням Find *, з наступного списку та обертання:

   3↑1 візьміть три елементи з одного, набивши нулями; [1,0,0]

   K← зберігати, що як K

    таблиця (внести у векторний стовпчик); [[1],[0],[0]]

   1, додати один; [[1,1],[1,0],[1,0]]("J")

   J← зберігати як J

   ()⊖¨⊂ Обертати весь J вертикально, кожен з наступних кроків:

    ⍳3 Перші три ɩ ntegers;[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⊖J обертати Jдва кроки вертикально; [[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 переформатуйте один у кожну матрицю 2 × 2 та список із 4 елементами; [[[1,1],[1,1]],[1,1,1,1]]("О", "Я")

  1∊¨ для кожного, чи є один член?

  ∨/ горизонтальне АБО зменшення (тобто поперечні обертання; по одному булевому типу для кожної форми)

  'OIZSLJT'/⍨ використовуйте це для фільтрування рядка

* Знайти повертає булевий масив такої ж форми, як і його правий аргумент, причому ті, що вказують верхній лівий кут усіх підматривок, ідентичний лівому аргументу.


Це би спрацювало? {4=+/,⍵:'OIZSJLT'/⍨∨/1∊¨(((2 2)4⍴¨1),(0 1⌽¨⊂K⌽2⊖J),(⍳3)⊖¨⊂J←1,⍪K←3↑1)∘.⍷⍵∘{⌽∘⍉⍣⍵⊢⍺}¨⍳4}
Zacharý

@ Zacharý Так, спасибі, зробили.
Adám

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), і повертає масив, що містить символ, що представляє тетроміно, або масив, що не містить нічого.

Це працює, перевіряючи кожне обертання тетроміно, щоб побачити, чи містить вхід в будь-якій точці тетроміно, оточений повністю нулями з обох боків. Кожне тетроміно представлено одним або декількома двійковими числами:

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 тетроміно, ми просто перевіряємо, чи містить він бінарне представлення будь-якого 51або 2145, з лише 0s з обох боків.

Кілька тетромінів мають 4 орієнтації. Якщо ви подивитесь на бінарні уявлення про них, у кожного є 2 уявлення, які є просто дзеркалом двох інших. Щоб заощадити простір, бінарне подання будується вперед і назад одночасно з рекурсивною Cфункцією, що дозволяє нам лише помістити дві орієнтації і мати на увазі інші дві.


Альтернативний підхід із штрихкодами:

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

Перевірте всі обертання вводу (див. Нижче). Якщо вхід містить чотири поспіль 1s, це ан I.

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

Якщо він містить три послідовних 1s плюс a 1у наступному рядку під одним із трьох, то зіставіть кількість проміжних символів на відповідну літеру результату.

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

Аналогічно для двох сусідніх 1s сусідніх до двох сусідніх 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 - це лист або порожній лист без тетроміно.

Спробуйте в Інтернеті! Або перевірити всі тестові випадки (у висновку додана крапка, яка дозволяє ідентифікувати порожній результат).

Пояснення

Код будує 4 обертання вхідного масиву 4 × 4 з кроком 90 градусів. Кожен обертовий масив обкладений двома нулями вгору та вниз, що перетворює його на 8 × 4 масив. 4 масиви вертикально з'єднані в масив 32 × 4. Чотири обертаються масиви всередині цього з'єднаного масиву "ізолюються" завдяки нульовому накладенню.

Кожен із 7 можливих шаблонів тестується на предмет наявності в масиві 32 × 4. Для цього використовується петля. Кожен шаблон визначається двома числами, які виражені у двійковій формі дають відповідну маску 0/1. Наприклад, числа 3, 6визначте форму "S".

7 наборів з 2 чисел розташовані в матриці розміром 2 × 7, з якої цикл буде вибирати кожен стовпчик послідовно. Матриця визначається шляхом натискання всіх чисел на стек, контактування їх у вектор і перетворення в 2-рядну матрицю. Оскільки форма "Я" визначена цифрою 15, а потім 0, то її розміщення в кінці дозволяє імпліцитно заповнити функцію перестановки.

Потім маска прокладена 3 нулями в чотирьох напрямках. Це необхідно для виявлення небажаних значень у вхідних даних.

Щоб побачити, чи є маска в масиві 32 × 4, остання перетворюється на біполярну форму (тобто −1/1 замість 0/1) і згортається з маскою. Оскільки маска має 4 одиниці, збіг відбувається, якщо деякий запис результату згортки дорівнює 4.

В кінці циклу отримано 7 помилкових / правдивих результатів, щонайбільше один з них є правдивим. Це використовується для індексації в рядку, що містить можливі вихідні літери.


3

Желе , 53 байти

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

Спробуйте в Інтернеті!

Повна програма. Бере 4x4. Друкує, mякщо не тетроміно, інакше друкує малі літери.


Чи ... прийняття масиву бітів законним? Це врятувало б мене, як 40 байт
ETHproductions

@ETHproductions Ви можете приймати введення як ціле число, або безпосередньо як двовимірний масив 4x4 двійкових цифр або плоский масив з 16 двійкових цифр.
Erik the Outgolfer

Гм, слугує мені правильно для того, щоб
скумуватися

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-бітний рядок. Виводить нічого, якщо вхід не є одним тетроміно.

Як?

Дві заміни "переміщують" форму введення до правого нижнього кута. Отриманий бітовий рядок перетворюється на ціле число, потім перевіряється на хеш дійсних цілих чисел.


1

APL (Діалог) , 66 байт

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

Спробуйте в Інтернеті!

Арг - булевий вектор.

Обчислює підписані відстані точок до центру ваги у вигляді складних чисел (реальна і уявна частина - ∆x, ∆y) і множує складні числа разом. Це виявляється досить хорошим інваріантом, щоб розрізняти тетроміно.


Цікавий метод.
Арнольд
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.