Розв’язуйте головоломки Хіторі


21

Вступ

Напишіть розгадувач для загадок Хіторі, використовуючи найменші байти.

Виклик

Ваше завдання - написати розв'язувач для хіторів (ひ と り, японське слово «один»; значення назви гри - «Залиште мене в спокої») логічні пазли. Правила такі:

  • Вам представлена ​​сітка n-на-n комірок, кожна комірка містить ціле число від 1 до n (включно).
  • Ваша мета - переконатися, що жодне число не з’являється більше одного разу в кожному рядку та кожному стовпці сітки, видаляючи номери з даної сітки, за умови обмеження, зазначеного у наступних двох правилах,
  • Не можна видалити два числа з двох сусідніх (по горизонталі чи вертикалі) комірок.
  • Решта пронумеровані комірки повинні бути з'єднані між собою. Це означає, що будь-які дві нумеровані осередки, що залишилися, можуть бути з'єднані з кривою, яка складається виключно з відрізків, що з'єднують суміжні залишкові числа (горизонтально або вертикально). (Дякуємо @ user202729 за те, що він вказав, що цього немає)

Я сподіваюся, що правила до цього часу зрозумілі. Якщо в правилах є щось незрозуміле, перевірте сторінку Вікіпедії .

Випробування

Осередки, з яких вилучаються числа, представлені 0.

Input  ->  Output

4
2 2 2 4      0 2 0 4
1 4 2 3  ->  1 4 2 3
2 3 2 1      2 3 0 1
3 4 1 2      3 0 1 2

4
4 2 4 3      0 2 4 3
4 1 1 2  ->  4 1 0 2
3 1 2 1      3 0 2 1
4 3 1 3      0 3 1 0

5
1 5 3 1 2      1 5 3 0 2
5 4 1 3 4      5 0 1 3 4
3 4 3 1 5  ->  3 4 0 1 5
4 4 2 3 3      4 0 2 0 3
2 1 5 4 4      2 1 5 4 0

8
4 8 1 6 3 2 5 7      0 8 0 6 3 2 0 7
3 6 7 2 1 6 5 4      3 6 7 2 1 0 5 4
2 3 4 8 2 8 6 1      0 3 4 0 2 8 6 1
4 1 6 5 7 7 3 5  ->  4 1 0 5 7 0 3 0
7 2 3 1 8 5 1 2      7 0 3 0 8 5 1 2
3 5 6 7 3 1 8 4      0 5 6 7 0 1 8 0
6 4 2 3 5 4 7 8      6 0 2 3 5 4 7 8
8 7 1 4 2 3 5 6      8 7 1 4 0 3 0 6

9
8 6 5 6 8 1 2 2 9      8 0 5 6 0 1 2 0 9
5 6 2 4 1 7 9 8 3      5 6 2 4 1 7 9 8 3
5 8 2 5 9 9 8 2 6      0 8 0 5 0 9 0 2 0
9 5 6 6 4 3 8 4 1      9 5 6 0 4 3 8 0 1
1 1 6 3 9 9 5 6 2  ->  0 1 0 3 9 0 5 6 2
1 1 4 7 3 8 3 8 6      1 0 4 7 0 8 3 0 6
3 7 4 1 2 6 4 5 5      3 7 0 1 2 6 4 5 0
3 3 1 9 8 7 7 4 5      0 3 1 9 8 0 7 4 5
2 9 7 5 3 5 9 1 3      2 9 7 0 3 5 0 1 0 

Ці тестові приклади взяті відповідно з концептуальних головоломок , головоломки , концептуальних головоломок , Вікіпедії та Youtube .

Технічні характеристики

  • Не потрібно турбуватися про обробку винятків.

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

  • Це , найменша кількість виграних байтів.

  • 4 <= n <= 9 (16 спочатку було змінено на 9 за пропозицією Стіві Гріффіна, також врятуйте деякі проблеми в IO)

  • Ви можете взяти вхід і надати вихід через будь-яку стандартну форму , і ви можете вільно вибрати формат.

  • Деякі пропозиції щодо вихідного формату є (але ви не обмежуєтесь цим)

    • Виведення підсумкової сітки
    • Виведення сітки, що містить усі вилучені числа
    • Виведіть список координат одного з вищезазначених
  • Як завжди, тут застосовуються лазівки за замовчуванням .


Пов'язане (натхнене цим викликом): Перевірте, чи всі елементи в матриці пов'язані

Моє останнє завдання: продовження гри сімки


2
Я пропоную вам вимагати детермінованого виконання або вимагати, щоб найбільший тестовий випадок можна було вирішити не більше ніж за 1 хвилину (а може і більше / менше). Крім того, ви кажете 4 <= n <= 16, але найбільший тестовий випадок призначений для n=9. Я пропоную вам або опублікувати n=16тестовий випадок, або сказати 4 <= n <= 9. Приємний виклик до речі :)
Стюі Гріффін

1
@StewieGriffin як щодо того, щоб просто мати окремий найшвидший виклик алгоритму?
Джонатан Аллан

@StewieGriffin Намагався додати 16x16, але ще не зовсім готовий. Змінено на 9 зараз.
Вейджун Чжоу

@JonathanAllan Як хочеш.
Вейджун Чжоу

Повторно "Я вирішую внести зміни, щоб побачити, чи буде краще": Це було б точно гірше. Також ви не повинні змінювати вже опублікований виклик.
користувач202729

Відповіді:


3

Haskell , 374 байт

import Data.Array;import Data.List;r=range;p=partition
c(e,f)=p(\(b,p)->any(==1)[(b-d)^2+(p-q)^2|(d,q)<-e])f
n#g=[s|(o,(e:f))<-[p((==0).(g!))$indices g],
 null.fst$c(o,o),null.snd$until(null.fst)c([e],f),
 s<-case[((l,c),d)|((l,c),h)<-assocs g,h>0,
 d<-[filter((==h).(g!))$r((l,c+1),(l,n))++r((l+1,c),(n,c))],d/=[]]
 of[]->[g];((c,d):_)->n#(g//[(c,0)])++n#(g//[(c,0)|c<-d])]

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


Дякую. Дуже вражає. Особисто я початківець, але також великий фанат Haskell.
Вейджун Чжоу


1
Вище сказане було занадто багато символів, також залишайте коментар поряд. Це просто видалення пробілу
H.PWiz


2

APL (Dyalog Unicode) , 133 байти SBCS

{q←{⊢/4 2⍴⍵}⌺3 3g←⍵=⊂∪,⍵⋄⍵×~1⊃{((⌈/q b)⌈b<{2<≢∪0,,(⍵×⊢⌈⌈/∘q)⍣≡⍵×(⍴⍵)⍴1+⍳≢,⍵}¨~b∘⌈¨⊂⍤2∘.≡⍨⍳⍴b)(+/↑w<g×⌈.⌈⍨w×g)⌈w b←⍵}⍣≡×\(⌈/=∘⌽⍨q⍵)0}

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

Моя реалізація правила №4 (клітини повинні утворювати єдиний підключений компонент) є досить марною, але все-таки це проходить усі тести приблизно за 10 секунд на TIO.


Загальний алгоритм: зберігайте дві булеві матриці bта wдля комірок, які, безумовно, чорні та білі відповідно. Ініціалізуйте bяк «нуль». Ініціалізуйте wяк 1 лише для тих комірок, які мають протилежних сусідів.

Повторювати до тих пір , bі wосідають вниз:

  • додайте до bкомірок, які знаходяться в одній лінії (горизонтальній чи вертикальній) і мають те саме значення, що й комірка вw

  • додати до wбезпосередніх сусідів усіх комірок уb

  • додати до wвсіх точок вирізу - осередків, видалення яких розділило б графік нечорних клітин на кілька з'єднаних компонентів

Нарешті, виведення, not(b)помножене на вихідну матрицю.


Дуже дякую за ваш інтерес та пояснення. Я думаю, те, що ви описали, - це також типовий алгоритм, який використовується, якщо вирішувати головоломку вручну.
Вейджун Чжоу

1
Якщо чесно, я навіть не намагався вирішити Хіторі вручну. Я отримав ці хитрощі з Вікіпедії, і у мене немає доказів того, що алгоритм завжди збігався б до (унікального) рішення.
ngn

2

Желе , 62 байти

Використовує is20, пов'язане з монадичним посиланням user202729 з іншого питання.


FJṁa@µ«Ḋoµ€ZUµ4¡ÐLFQL<3
ḟ0ĠḊ€
¬T€œ&2\;Ç€FȦ
ZÇȯÇ_1Ŀ
2ḶṗLṗLa⁸ÇÞḢ

Повна програма, що друкує представлення списку списків.
Працює грубою силою і тупо неефективно.

Спробуйте в Інтернеті!- 3 на 3, оскільки це занадто неефективно для виконання навіть розміру 4 в межах 60-секундного TIO!

Як?

FJṁa@µ«Ḋoµ€ZUµ4¡ÐLFQL<3 - Link 1 isConnected? List of lists
...                     - 1 if connected 0 if not -- see linked answer in the header

ḟ0ĠḊ€ - Link 2, helperFor-AnyRepeatedValues: list
ḟ0    - filter out zeros
  Ġ   - group indices by value (i.e. [[indices of min],...,[indices of max]]
   Ḋ€ - dequeue €ach -- leaving a list of empty lists iff no repeated values
      -                 any remaining values are non-zero (1-based indexing in Jelly)

¬T€œ&2\;Ç€FȦ - Link 3, columnwiseAnyAdjacentZerosOrRowwiseAnyRepeatedValues: list of lists
¬            - logical not (convert all zeros to ones and all others to zeros)
 T€          - for €ach row get a list of truthy indexes (i.e. indexes of original zeros)
     2\      - pairwise reduction (i.e. for neighbouring rows) with:
   œ&        -   intersection (empty if no columnwise adjacent original zeros
             -                 any remaining values are non-zero due to 1-based indexing)
        Ç€   - call last link (1) as a monad for €ach row
       ;     - concatenate
          F  - flatten into a single list (empty iff no columnwise adjacent original zeros
             -                                   AND no rowwise repeated values)
           Ȧ - any and all (0 if empty [or contains any zero -- never] else 1)

ZÇȯÇ_1Ŀ - Link 4, validity check? list of lists
Z       - transpose
 Ç      - call last link (2) as a monad rowwiseAnyAdjacentZerosOrColumnwiseAnyRepeatedValues?
   Ç    - call last link (2) as a monad columnwiseAnyAdjacentZerosOrRowwiseAnyRepeatedValues?
  ȯ     - logical OR
     1Ŀ - call link 1 as a monad (isConnected?)
    _   - subtract
        - this yields -1 for valid, while it yields 0 or 1 if not.

2ḶṗLṗLa⁸ÇÞḢ - Main link: list of lists
2Ḷ          - lowered range of 2 -> [0,1]
   L        - length (number of rows in the input)
  ṗ         - Cartesian power (all lists of zeros and ones of length L)
     L      - length (number of rows in the input again)
    ṗ       - Cartesian power (all grids of zeros and ones of same shape as the input)
       ⁸    - the input
      a     - logical AND -- effectively uses each of the formed grids as a mask
         Þ  - sort by:
        Ç   -   last link (3) as a monad
          Ḣ - head
            - implicit print

NIce як початок. Дякую. Я погляну.
Вейджун Чжоу

Ви забули 4 правило. (підключено)
користувач202729

(удачі з впровадженням BFS / DFS / DSU в Jelly)
користувач202729

Ох ... видалять, коли за комп’ютером. Спасибі.
Джонатан Аллан

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