Risolvi una scheda 0h n0


19

0h n0 è un gioco molto semplice e divertente, un po 'come il Sudoku o il dragamine.

Regole del gioco

( Se possibile, ti consiglio di usare il tutorial nel gioco, è molto semplice e utile)

Il puzzle inizia con una n * ntavola contenente alcuni pezzi fissi e alcune celle vuote, e il risolutore deve trovare un modo per riempire le celle vuote di pezzi e soddisfare tutti i vincoli imposti dai pezzi fissi. Ecco i tipi di pezzo che useremo con l'abbreviazione:

  • # Pezzo rosso (blocca la vista di un pezzo blu)
  • O Pezzo blu
  • . Posizione vuota
  • numberPezzo blu numerato ( numberè un numero di una cifra> 0)

Tutti i pezzi numerati devono vedere esattamente la stessa quantità di pezzi blu del numero. Per esempio:

#1O#O
...O.

Il 1pezzo può vedere solo un altro pezzo blu.

Come i pezzi si vedono

Due pezzi blu possono vedersi se si trovano nella stessa riga o colonna e non c'è nessun pezzo rosso tra di loro. Esempio:

( Sè una posizione che il Opezzo può vedere, Xnon può essere visto)

   S
   S
X#SOSS
   #
   X

Ogni pezzo blu deve vedere almeno un altro pezzo blu:

#O#

Non funziona, ma:

#OO

O:

###

Lavora.

La scheda demo si risolve

.1..
..1.
....
22#2

Il 2 in basso a destra può vedere solo sopra se stesso, quindi devono essere blu e quello in alto a destra deve essere rosso.

.1.#
..1O
...O
22#2

Dato che 1è pieno, possiamo circondarlo con pezzi rossi.

.1##
.#1O
..#O
22#2

L'angolo in alto a sinistra ora 1può vedere solo in una direzione, quindi possiamo riempirlo.

O1##
.#1O
..#O
22#2

Ora su quelle ultime 2s. Possiamo mettere 2 pezzi blu su di essi.

O1##
.#1O
OO#O
22#2

L'ultimo verrà riempito #

O1##
##1O
OO#O
22#2

Ingresso

L'input è una stringa multilinea. La dimensione sarà 9x9senza spazio finale. Ha i seguenti tipi di pezzi:

  • . Vuoto
  • # Rosso preimpostato, non modificabile
  • number Numero di preselezione, non può essere modificato

(Nota che il blu non sarà mai nell'input)

Produzione

L'output è uguale all'input, con la modifica che empty ( .) viene sostituito con un rosso o un blu per risolvere la scheda e i numeri vengono sostituiti con pezzi blu ( O).

Esempi

(Nota che possono essere possibili più soluzioni per ogni puzzle, ma devi solo mostrarne una)

Input:
........4
...3.1...
45...2.3.
..9......
1..6#44..
....4..5.
....4.36.
2.......6
1....4...

Output:
OOO###OOO
OOOO#O#OO
OOO#OO#OO
#OOOO#O##
O#OO#OOOO
O#OOOO#OO
#OOOO#OOO
OO#O#OOOO
O#OOOO#O#

Input:
..7..#...
#...8..11
2....5...
..5...48.
...#...4.
.5...6...
...1.2...
2.....6.8
.7..#....

Output:
OOOOO####
##OOOO#OO
O#OOOO###
OOO#OOOOO
OO##O##O#
#O##OOOOO
#O#O#O#OO
OO#OOOOOO
OOO###O#O

Input:
5.3..33..
...4...23
.6.6.34..
...3#....
....5..4.
.5....3..
7.98.6#.3
.5.6..2..
..6...2..

Output:
OOOOO####
##OOOO#OO
O#OOOO###
OOO#OOOOO
OO##O##O#
#O##OOOOO
#O#O#O#OO
OO#OOOOOO
OOO###O#O

Grazie a @PeterTaylor e @apsillers per tutto il loro aiuto nella sandbox!


Ho apportato solo una modifica molto minore al titolo perché "an" suona meglio se la parola seguente inizia con una vocale: non mi aspetto che chi parla inglese non madrelingua o addirittura madrelingua si prenda la briga di farlo, ma è grammaticale.
gatto

Risposte:


2

Haskell, 224 byte

Non completamente testato, perché è così lento (almeno O(n*2^n^2)).

t=1<2
x!p|p<0=0|t=mod(div x$2^p)2
l#x=[[sum$map(p&)[-1,1,l+1,-l-1]|p<-[q..q+l]]|q<-[0,l..l*l],let i&v|x!i<1=0|t=x!(i+v)+(i+v)&v]
b%v|b<1=t|t=b==v
s b|l<-length b-1=[l#x|x<-[0..2^l^2],and.map and$zipWith(zipWith(%))b(l#x)]!!0

Spiegazione:

L'idea di base è quella di rappresentare una tavola di Red, Bluepezzi come un elenco di elenchi di 0, 1, in cui l'elenco di elenchi è impacchettato in un unico numero intero per una più semplice enumerazione. Tutti questi numeri interi per le dimensioni della scheda vengono generati e convertiti in un modulo con conteggi vicini. Viene restituita la prima scheda di questo tipo che è una soluzione valida dell'input.

-- integer x at position p with out of bounds defined to be 0 (so no bounds checking)
(!) :: (Integral b, Integral r) => r -> b -> r
x ! p | p < 0     = 0 
      | otherwise = mod (div x (2^p)) 2


-- Sum of values from position p along vector v (x is implicit)
-- Note that a cartesian vector (x,y) in this representation is (l*x + y)
(&) :: (Integral a, Integral b) => b -> b -> a
p & v | x ! p == 0 = 0
      | otherwise  = x ! (p+v)  +  (p+v) & v


-- Value of board at position p (implicit x, l)
value :: Integral a => a -> a
value p = sum $ map (p&) [-1, 1, l+1, -l-1]


-- Integer to board, where l is length, x is input integer
(#) :: (Integral t, Integral a) => a -> t -> [[t]]
l # x = [[sum $ map (p&) [-1,1,l+1,-l-1] | p <- [q..q+l-1]] | q <- [0,l..l*l]]


-- Comparison operator, to see whether a solved board is a solution of the input
(%) :: (Num a, Ord a) => a -> a -> Bool
b % v | b == 0    = True
      | otherwise = b == v


-- Check one possible solution
check :: Integral a => [[a]] -> Int -> [[a]] -> Bool
check b l x = (and . (map and)) zipWith(zipWith (%)) b (l # x)

-- Solver
solve :: Integral t => [[t]] -> [[t]]
solve b = [l # x | x <- [0..2^l^2], check b l x]
  where
    l = length b

La parte che potrebbe probabilmente essere più giocato a golf è: and.map and$zipWith(zipWith(%)). Altrimenti, ho riscontrato alcuni errori off-by-one che hanno aggiunto lunghezza e probabilmente avrei potuto giocare di più.

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.