Riesci a collegare i punti?


18

Questa sfida si basa su Flow Free. Una versione online è disponibile qui: http://www.moh97.us/

Ti verrà dato un enigma e dovrai tornare 1se l'enigma è risolvibile o in 0caso contrario.

Per risolvere un puzzle, il giocatore deve creare un percorso per collegare ogni coppia di numeri usando ogni quadrato vuoto esattamente una volta.

Vengono passate le dimensioni del quadrato e quindi la x, y, c (dove c è un numero che rappresenta il colore) di ciascun punto. Per esempio:

Se ti 5,5 0,0,0 3,0,1 1,1,2 1,2,2 4,2,1 4,4,0fosse passato, rappresenterebbe:

0..1.
.2...
.2..1
....0

E dovrebbe restituire 1.


Ecco alcuni altri problemi di test:

5,2 2,0,1 0,1,2 4,1,2 rappresenta:

..1..
2...2

e non è risolvibile perché ne esiste solo 1 1.

4,2 0,0,0 3,0,0 0,1,0 3,1,0 rappresenta:

0..0
0..0

e non è risolvibile perché include più di 2 0secondi.

8,6 0,0,1 7,5,1 rappresenta:

1.......
........
........
........
........
.......1

e non è risolvibile (in quanto non è possibile utilizzare tutti i quadrati).

2,5 0,0,1 2,0,6 4,0,6 0,1,4 3,1,4 4,1,1 rappresenta:

1.6.6
4..41

e non è risolvibile perché non è possibile collegare gli 1.

6,3 1,0,4 5,0,1 0,1,4 1,1,3 5,1,3 0,2,2 3,2,2 5,2,1 rappresenta:

.4...1
43...3
2..2.1

e non è risolvibile perché non è possibile collegare 1 (o 3), poiché i due percorsi devono necessariamente incrociarsi.

5,2 0,0,1 3,0,1 0,1,3 4,1,1 rappresenta:

1..1.
3...3

e non è risolvibile perché non è possibile utilizzare tutti i quadrati nella costruzione di un tracciato.

2,2 0,0,0 1,1,0 rappresenta:

1.
.1

e non è risolvibile perché non è possibile utilizzare tutti i quadrati qui

Ecco alcuni altri test:

5,5 0,3,0 0,4,1 1,2,2 1,3,1 2,0,0 3,0,4 3,1,2 3,3,5 3,4,4 4,4,5 dovrebbe restituire 1

13,13 1,1,0 9,1,1 10,1,2 11,1,3 1,2,4 2,2,5 5,2,6 7,2,7 3,3,0 5,4,6 6,4,1 9,6,3 4,7,8 5,8,9 12,8,8 11,9,10 2,10,4 4,10,2 9,10,5 11,10,7 1,11,9 12,12,10 dovrebbe restituire 1

7,7 0,0,0 0,1,1 1,1,2 2,1,3 4,2,4 0,3,1 5,3,3 0,4,4 2,4,5 5,4,2 0,5,0 1,5,5 3,5,6 3,7,6 dovrebbe restituire 0


Questo è un codice golf e si applicano le regole standard.


2
Una soluzione deve essere "realisticamente" corretta o solo teoricamente corretta? Ad esempio, lo spazio degli stati può essere suddiviso nell'assegnazione di una delle 6 possibili configurazioni input-to-input a ciascuna cella vuota. La risolvibilità è facilmente determinata tentando tutte le combinazioni 6 ^ N e ritornando 1se una di esse visita tutte le celle e collega tutti i terminali. Ovviamente questo approccio non si completerebbe in un lasso di tempo ragionevole per tutto tranne che per il più piccolo N(numero di celle vuote), ma abbiamo ancora una garanzia matematica che l'algoritmo alla fine restituirà il valore corretto.
COTO

1
Forse se hai trovato due enormi set di griglie di gioco (uno pubblico per i test, uno privato per la convalida) usando un algoritmo comune e hai ritenuto il vincitore come l'invio che ha identificato correttamente la solvibilità della maggior parte delle griglie nel set privato in alcuni ragionevole quantità di tempo per griglia, con dimensione del programma come tiebreaker se due invii avessero la stessa utilità. Ci proverei sicuramente.
COTO

1
@NathanMerrill: il problema è riducibile a SAT e quindi a NP difficile.
COTO

3
@NathanMerrill ridurre un problema a SAT significa che il problema è in NP, non che è NP-difficile - sta riducendo SAT a un problema che mostra la durezza NP del problema. La pagina a cui ti sei collegato ha un link a una prova di completezza NP.
cardboard_box

1
@VisualMelon Digit color è la parola sbagliata. Ogni colore è rappresentato da un numero diverso, non da una cifra.
Nathan Merrill,

Risposte:


3

Haskell

import Data.List.Split
import qualified Data.Sequence as Q
import Data.List
import Control.Monad

data A a = S a | E a | P a | X deriving Eq

sc = foldr1 (Q.><)
sp b x y p = Q.update y (Q.update x p $ b `Q.index` y) b
dt b c | S c `elem` sc b = E c
       | otherwise = S c
ad b [x, y, c] = sp b x y (dt b c)

ep b [x, y, c] = do
  let nps = filter ob [(x+1, y), (x-1, y), (x, y+1), (x, y-1)]
      ns = map gp nps
  [b | E c `elem` ns] ++ do
    (x', y') <- filter ((== X) . gp) nps
    ep (sp b x' y' (P c)) [x', y', c]
  where ob (u, v) = 0 <= u && u < length (b `Q.index` 0) && 0 <= v && v < length b
        gp (u, v) = b `Q.index` v `Q.index` u

rd i = let [c, r] : ps = (map read . splitOn ",") <$> words i :: [[Int]]
           e = Q.replicate r $ Q.replicate c X
           cs = map last ps
           ss = nubBy (\[_,_,c1] [_,_,c2] -> c1 == c2) ps
           b = foldl ad e ps
           bs = foldM ep b ss
       in if even (length cs) && length ss == length cs `div` 2 &&
             (all (\[j,k] -> j==k) . chunksOf 2 . sort $ cs) &&
             any (null . Q.elemIndicesL X . sc) bs
           then 1
           else 0

main = rd <$> getContents >>= print

Chiave

  • sc: Seq concat
  • sp: imposta la posizione
  • dt: tipo di punto (ovvero inizio o fine della riga)
  • annuncio: aggiungi punto
  • ep: estende il percorso
  • rd: run points (algoritmo puro primario)

2
Grazie per l'invio e benvenuto nello scambio di stack PPCG. Questa è una sfida di golf del codice, il che significa che lo scopo è quello di scrivere il programma più breve che risolva la sfida. Sei in testa, perché hai l'unica risposta, ma dovresti cercare di abbreviare il programma il più possibile.
isaacg,

Sono sinceramente colpito dal fatto che tu abbia risposto a questa domanda dopo tutto questo tempo. Inoltre, questo problema rappresentava più una sfida al codice, ma ho usato il code-golf, poiché era difficile trovare una base di punteggio diversa.
Nathan Merrill,

Sì, non mi sono preoccupato troppo dell'aspetto "golf"; Sto cercando di imparare Haskell e mi è sembrato un problema divertente :-)
Matt,
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.