Risolvi i puzzle di Hitori


21

introduzione

Scrivi un risolutore per i puzzle di Hitori usando meno byte.

Sfida

Il tuo compito è scrivere un risolutore per l'Hitori (ひ と り, la parola per "solo" in giapponese; il significato del nome del gioco è "Lasciami in pace") puzzle logici. Le regole sono le seguenti:

  • Ti viene presentata una griglia di celle n-by-n, ogni cella contiene un numero intero compreso tra 1 e n (compreso).
  • Il tuo obiettivo è assicurarti che nessun numero appaia più di una volta in ogni riga e ogni colonna della griglia, rimuovendo i numeri dalla griglia data, soggetto alla restrizione indicata nelle due regole successive,
  • Non è possibile rimuovere due numeri da due celle adiacenti (orizzontalmente o verticalmente).
  • Le celle numerate rimanenti devono essere tutte collegate tra loro. Significa che ogni due celle numerate rimanenti possono essere collegate con una curva composta esclusivamente da segmenti che collegano i numeri rimanenti adiacenti (in orizzontale o in verticale). (Grazie a @ user202729 per aver sottolineato che manca questo)

Spero che le regole siano chiare ormai. Se c'è qualcosa di poco chiaro nelle regole, controlla la pagina di Wikipedia .

Casi test

Le celle da cui vengono rimossi i numeri sono rappresentate con 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 

Questi casi di test sono tratti rispettivamente da Concept Is Puzzles , PuzzleBooks , Concept Is Puzzles , Wikipedia e Youtube .

Specifiche

  • Non è necessario preoccuparsi della gestione delle eccezioni.

  • È possibile supporre che l'ingresso è sempre un puzzle valida con una unica soluzione ed è possibile usufruire di questo nella scrittura del codice.

  • Questo è , vince il numero più basso di byte.

  • 4 <= n <= 9 (16 originariamente, cambiato in 9 in seguito al suggerimento di Stewie Griffin, risparmiando anche qualche problema in IO)

  • Puoi prendere input e fornire output attraverso qualsiasi modulo standard e sei libero di scegliere il formato.

  • Alcuni suggerimenti per il formato di output sono (ma non sei limitato a questi)

    • Emissione della griglia finale
    • Emissione della griglia contenente tutti i numeri rimossi
    • Emette un elenco di coordinate di una delle precedenti
  • Come al solito, qui si applicano scappatoie predefinite .


Correlato (ispirato a questa sfida): Verifica se tutti gli elementi in una matrice sono collegati

La mia ultima sfida: l' estensione del gioco dei sette


2
Suggerisco di richiedere un runtime deterministico o di risolvere il caso di test più grande in non più di 1 minuto (o forse più / meno). Inoltre, dici 4 <= n <= 16, ma il più grande caso di test è per n=9. Ti suggerisco di pubblicare un n=16caso di prova o di dirlo 4 <= n <= 9. Bella sfida a proposito :)
Stewie Griffin,

1
@StewieGriffin che ne dici di avere una sfida algoritmo più veloce separata?
Jonathan Allan,

@StewieGriffin Ho provato ad aggiungere un 16x16 ma non ancora del tutto pronto. Modificato in 9 ora.
Weijun Zhou,

@JonathanAllan Come desideri.
Weijun Zhou

Ri "Decido di fare un cambiamento per vedere se sarebbe meglio": sarebbe sicuramente peggio. Inoltre, non dovresti cambiare una sfida già pubblicata.
user202729

Risposte:


3

Haskell , 374 byte

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])]

Provalo online!


Grazie. Molto impressionante. Personalmente sono un principiante ma anche un grande fan di Haskell.
Weijun Zhou,


1
Quanto sopra era troppi personaggi anche lasciare un commento a fianco. Sta solo rimuovendo un po 'di spazio
H.Piz


2

APL (Dyalog Unicode) , 133 byte 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}

Provalo online!

La mia implementazione della regola n. 4 (le celle devono formare un singolo componente collegato) è piuttosto dispendiosa, ma comunque questo supera tutti i test in circa 10 secondi su TIO.


L'algoritmo generale: memorizza due matrici booleane be wper le celle che sono sicuramente rispettivamente in bianco e nero. Inizializza bcome zero. Inizializza wcome 1 solo per quelle celle che hanno vicini corrispondenti opposti.

Ripeti fino a quando be wsistemati:

  • aggiungi alle bcelle che si trovano sulla stessa linea (orizzontale o verticale) e dello stesso valore di una cella inw

  • aggiungere ai wvicini immediati di tutte le celle inb

  • aggiungere a wtutti i punti di taglio - celle la cui rimozione dividerebbe il grafico delle celle non nere in più componenti collegati

Infine, l'output si è not(b)moltiplicato per la matrice originale.


Grazie mille per l'interesse e la spiegazione. Penso che quello che hai descritto sia anche un tipico algoritmo usato se si vuole risolvere il puzzle a mano.
Weijun Zhou

1
Ad essere sincero, non ho mai nemmeno provato a risolvere Hitori a mano. Ho ricevuto questi trucchi da Wikipedia e non ho la prova che l'algoritmo converrebbe sempre fino alla soluzione (unica).
ngn

2

Gelatina , 62 byte

Utilizza il collegamento monadico isConnected dell'utente202729 da un'altra domanda.


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

Un programma completo che stampa una rappresentazione di un elenco di elenchi.
Funziona con la forza bruta ed è stupidamente inefficiente.

Provalo online! - un 3 per 3, poiché è troppo inefficiente per eseguire anche una dimensione 4 entro il limite TIO di 60 secondi!

Come?

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

Bella come inizio. Grazie. Darò un'occhiata.
Weijun Zhou,

Hai dimenticato la 4a regola. (connesso)
user202729

(buona fortuna con l'implementazione di BFS / DFS / DSU in Jelly)
user202729

Oh ... cancellerà quando su un computer. Grazie.
Jonathan Allan,

sì, non penso che ciò sia possibile, diciamo, <60 byte di Jelly, per non dire <100 ...
Erik the Outgolfer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.