0h n0 kartını çözme


19

0h n0 , biraz basit ve eğlenceli bir oyundur, biraz Sudoku veya mayın tarama gemisi gibi.

Oyun kuralları

( Yapabiliyorsanız oyundaki öğreticiyi kullanmanızı öneririm , çok basit ve kullanışlı)

Bulmaca n * n, bazı sabit parçalar ve bazı boş hücreler içeren bir tahta ile başlar ve çözücü boş hücreleri parçalarla doldurmanın ve sabit parçaların getirdiği tüm kısıtlamaları karşılamanın bir yolunu bulmalıdır. Kısaltma ile kullanacağımız parça türleri şunlardır:

  • # Kırmızı parça (mavi parçanın blok görünümü)
  • O Mavi parça
  • . Boş yer
  • numberNumaralı mavi parça ( numberbir basamaklı sayı> 0)

Tüm numaralı parçalar tam olarak aynı mavi parçaları görmelidir. Örneğin:

#1O#O
...O.

1Parça yalnızca bir diğer mavi parça görebilirsiniz.

Parçalar birbirini nasıl görür

Aynı satır veya sütundalarsa ve aralarında kırmızı bir parça yoksa iki mavi parça birbirini görebilir. Misal:

( parçanın görebildiği, görülemeyen Sbir konumdur )OX

   S
   S
X#SOSS
   #
   X

Her mavi parça en az bir mavi parça daha görmelidir:

#O#

Çalışmaz, ama:

#OO

Veya:

###

İşi yapmak.

Demo kurulu çözmek

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

Sağ alt 2 sadece kendi üstünü görebilir, bu yüzden mavi olmalı ve sağ üst kırmızı olmalıdır.

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

Yana 1doldurulur, kırmızı taşlarla onu çevreleyen olabilir.

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

Sol üst 1şimdi sadece bir yönde görebilir, bu yüzden doldurabiliriz.

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

Şimdi bu son 2s hakkında. Üzerine 2 mavi parça koyabiliriz.

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

Sonuncusu doldurulacak #

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

Giriş

Giriş çok satırlı bir dizedir. Boyut, 9x9boşluk bırakmadan olacaktır . Aşağıdaki parça türlerine sahiptir:

  • . Boş
  • # Ön ayar kırmızı, değiştirilemez
  • number Ön ayar numarası, değiştirilemez

(Mavinin girişte hiç olmayacağını unutmayın)

Çıktı

Çıktı, girişle aynıdır; değişiklik, boş ( .) kartın çözümü için kırmızı veya mavi ile değiştirilir ve sayılar mavi parçalarla ( O) değiştirilir.

Örnekler

(Her bir bulmaca için birden fazla çözümün mümkün olabileceğini unutmayın, ancak bunlardan yalnızca birini göstermeniz gerekir)

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

Kum havuzundaki tüm yardımları için @PeterTaylor ve @ apsillers'a teşekkürler !


Aşağıdaki kelime bir sesli harfle başlarsa "an" kulağa daha iyi geldiğinden başlığa çok küçük bir düzenleme yaptım - anadili İngilizce olmayanların, hatta anadili İngilizce olanların bile rahatsız olmasını beklemiyorum, ama dilbilgisi.
kedi

Yanıtlar:


2

Haskell, 224 bayt

Tamamen test edilmedi, çünkü çok yavaş (en azından 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

Açıklama:

Temel fikir, Red, Bluelistelerin 0, 1listesini daha kolay numaralandırma için tek bir tamsayı halinde paketlendiği bir liste listesi olarak temsil etmektir. Pano boyutu için bu tür tüm tamsayılar üretilir ve komşu sayıları olan bir forma dönüştürülür. Girişin geçerli bir çözümü olan bu tür ilk kart döndürülür.

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

Muhtemelen en golfed olabilir parçasıdır: and.map and$zipWith(zipWith(%)). Aksi takdirde, uzunluk ekledi ve muhtemelen daha fazla golf olabilir birkaç tek tek hatalar yakaladı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.