Löse eine 0h n0 Karte

19

0h n0 ist ein sehr einfaches und unterhaltsames Spiel, ähnlich wie Sudoku oder Minensuchboot.

Spielregeln

(Ich empfehle die Verwendung des Tutorials im Spiel, wenn Sie können, es ist sehr einfach und nützlich)

Das Puzzle beginnt mit einer n * nTafel, die einige feste Teile und einige leere Zellen enthält, und der Löser muss einen Weg finden, um die leeren Zellen mit Teilen zu füllen und alle durch die festen Teile auferlegten Einschränkungen zu erfüllen. Hier sind die Stückarten, die wir mit der Abkürzung verwenden werden:

  • # Rotes Stück (Blockansicht eines blauen Stückes)
  • O Blaues Stück
  • . Leerer Standort
  • numberNummeriertes blaues Stück ( numberist eine einstellige Zahl> 0)

Alle nummerierten Teile müssen genauso viele blaue Teile enthalten wie die Zahl. Beispielsweise:

#1O#O
...O.

Das 1Stück kann nur ein anderes blaues Stück sehen.

Wie Stücke sich sehen

Zwei blaue Teile können sich sehen, wenn sie sich in derselben Zeile oder Spalte befinden und sich kein rotes Teil dazwischen befindet. Beispiel:

( Sist ein Ort, den das OStück sehen Xkann, nicht gesehen werden kann)

   S
   S
X#SOSS
   #
   X

Jedes blaue Stück muss mindestens ein anderes blaues Stück sehen:

#O#

Wird nicht funktionieren, aber:

#OO

Oder:

###

Arbeite.

Demoboard lösen

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

Der rechte untere Teil 2 kann nur über sich selbst sehen, daher müssen sie blau und der obere rechte Teil rot sein.

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

Da das 1gefüllt ist, können wir es mit roten Stücken umgeben.

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

Die obere linke Seite 1kann jetzt nur in eine Richtung sehen, sodass wir sie ausfüllen können.

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

Nun zu den letzten 2s. Wir können 2 blaue Teile darüber legen.

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

Der letzte wird mit gefüllt #

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

Eingang

Die Eingabe ist eine mehrzeilige Zeichenfolge. Die Größe wird 9x9ohne Leerzeichen angegeben. Es hat die folgenden Stückarten:

  • . Leeren
  • # Voreinstellung rot, kann nicht geändert werden
  • number Voreinstellungsnummer, kann nicht geändert werden

(Beachten Sie, dass Blau niemals in der Eingabe enthalten sein wird.)

Ausgabe

Die Ausgabe ist die gleiche wie die Eingabe, mit der Änderung, dass empty ( .) entweder durch ein rotes oder ein blaues ersetzt wird, um die Karte zu lösen, und die Zahlen durch blaue Teile ( O) ersetzt werden.

Beispiele

(Beachten Sie, dass für jedes Puzzle mehrere Lösungen möglich sind, Sie jedoch nur eine davon anzeigen müssen.)

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

Vielen Dank an @PeterTaylor und @apsillers für all ihre Hilfe im Sandkasten!

J Atkin
quelle
Ich habe den Titel nur sehr geringfügig bearbeitet, weil "an" besser klingt, wenn das folgende Wort mit einem Vokal beginnt - ich erwarte nicht, dass nicht-englische Muttersprachler oder sogar Muttersprachler damit zu tun haben, aber es ist grammatikalisch.
Katze

Antworten:

2

Haskell, 224 Bytes

Nicht vollständig getestet, weil es (zumindest O(n*2^n^2)) so langsam ist .

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

Erläuterung:

Die Grundidee besteht darin, Red, Blueeine Stückliste als Liste von Listen von darzustellen 0, 1, wobei die Liste von Listen zur einfacheren Aufzählung in eine einzelne Ganzzahl gepackt wird. Alle diese Ganzzahlen für die Boardgröße werden generiert und in ein Formular mit Nachbarzahlen konvertiert. Die erste solche Karte, die eine gültige Lösung der Eingabe ist, wird zurückgegeben.

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

Der Teil, der wahrscheinlich golfed werden die meisten könnte , ist: and.map and$zipWith(zipWith(%)). Ansonsten habe ich ein paar Fehler nach dem anderen entdeckt, die die Länge vergrößerten und wahrscheinlich mehr Golf hätten spielen können.

Michael Klein
quelle