Решить головоломки Hitori

21

Вступление

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

Вызов

Ваша задача - написать решатель для логических головоломок Hitori (itor と り, слово «один» на японском языке; значение названия игры - «Оставь меня в покое»). Правила следующие:

  • Вам представлена ​​n-n-n-сетка ячеек, каждая ячейка содержит целое число от 1 до n (включительно).
  • Ваша цель состоит в том, чтобы убедиться, что никакие числа не появляются более одного раза в каждой строке и каждом столбце сетки, удаляя числа из данной сетки, с учетом ограничения, указанного в следующих двух правилах,
  • Вы не можете удалить два числа из двух смежных (горизонтально или вертикально) ячеек.
  • Все остальные пронумерованные ячейки должны быть связаны друг с другом. Это означает, что любые две оставшиеся пронумерованные ячейки могут быть связаны с кривой, которая состоит исключительно из сегментов, соединяющих соседние оставшиеся числа (по горизонтали или по вертикали). (Спасибо @ user202729 за указание, что это отсутствует)

Я надеюсь, что правила уже ясны. Если что-то неясно в правилах, проверьте страницу Википедии .

Тестовые случаи

Ячейки, из которых удалены числа, обозначены нулями.

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 

Эти тестовые примеры взяты из концептов Puzzles , PuzzleBooks , Concept Is Puzzles , Wikipedia и Youtube соответственно.

Спекуляции

  • Не нужно беспокоиться об обработке исключений.

  • Вы можете предположить, что ввод - это всегда правильная головоломка с уникальным решением, и вы можете воспользоваться этим при написании кода.

  • Это , выигрывает наименьшее количество байтов.

  • 4 <= n <= 9 (изначально 16, изменено на 9 по предложению Стьюи Гриффина, также избавляет от некоторых проблем при вводе-выводе)

  • Вы можете принять ввод и предоставить вывод через любую стандартную форму , и вы можете выбрать формат.

  • Некоторые предложения для выходного формата (но вы не ограничены этим)

    • Вывод окончательной сетки
    • Вывод сетки, содержащей все удаленные числа
    • Вывести список координат одного из вышеперечисленных
  • Как обычно, здесь применяются лазейки по умолчанию .


Связанный (вдохновленный этим испытанием): Проверьте, все ли элементы в матрице связаны

Мой последний вызов: продление игры семерок

Вейцзюнь Чжоу
источник
2
Я предлагаю, чтобы вам требовалось детерминированное время выполнения или требовалось, чтобы самый большой тестовый пример мог быть решен не более чем за 1 минуту (или, может быть, больше / меньше). Кроме того, вы говорите 4 <= n <= 16, но самый большой контрольный пример для n=9. Я предлагаю вам либо опубликовать n=16тестовый пример, либо сказать 4 <= n <= 9. Между прочим, хороший вызов :)
Стьюи Гриффин
1
@StewieGriffin, как насчет того, чтобы иметь отдельный вызов для самого быстрого алгоритма?
Джонатан Аллан
@StewieGriffin Пытался добавить 16x16, но пока не совсем готов. Изменено на 9 сейчас.
Вейцзюнь Чжоу
@JonathanAllan Как пожелаешь.
Вейцзюнь Чжоу
Re: «Я решил внести изменения, чтобы увидеть, будет ли это лучше»: Это определенно будет хуже. Также вы не должны изменять уже опубликованный вызов.
user202729

Ответы:

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.
Вейцзюнь Чжоу,
tio.run/…
H.PWiz
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
Честно говоря, я никогда даже не пытался решить Хитори вручную. Я получил эти трюки из Википедии, и у меня нет доказательств того, что алгоритм всегда будет сходиться до (уникального) решения.
августа
2

Желе , 62 байта

Использует монадическую ссылку is20n29 пользователя 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
Джонатан Аллан
источник
Хороший как начало. Спасибо. Я посмотрю.
Вейцзюнь Чжоу
Вы забыли 4-е правило. (подключен)
user202729
(удачи в реализации BFS / DFS / DSU в Jelly)
user202729
Ох ... удаляю когда за компом. Спасибо.
Джонатан Аллан
да, я не думаю, что это возможно, скажем, в <60 байтах желе, а не в <100 ...
Эрик Аутгольфер