แก้ 0h n0 บอร์ด


19

0h n0เป็นเกมที่เล่นง่ายและสนุกมากเช่น Sudoku หรือเรือกวาดทุ่นระเบิด

กฎของเกม

(ฉันขอแนะนำให้ใช้บทช่วยสอนในเกมถ้าทำได้ทำได้ง่ายและมีประโยชน์)

จิ๊กซอว์เริ่มต้นด้วยn * nกระดานที่มีชิ้นส่วนคงที่และเซลล์ว่างบางส่วนและผู้แก้ปัญหาต้องหาวิธีในการเติมชิ้นส่วนที่ว่างเปล่าด้วยเซลล์และสนองข้อ จำกัด ทั้งหมดที่กำหนดโดยชิ้นส่วนคงที่ นี่คือประเภทของชิ้นส่วนที่เราจะใช้กับตัวย่อ:

  • # ชิ้นสีแดง (บล็อกมุมมองของชิ้นส่วนสีน้ำเงิน)
  • O ชิ้นส่วนสีน้ำเงิน
  • . ตำแหน่งว่าง
  • numberชิ้นสีน้ำเงินที่มีหมายเลข ( numberเป็นตัวเลขหนึ่งหลัก> 0)

ชิ้นส่วนที่เป็นตัวเลขทั้งหมดจะต้องเห็นจำนวนชิ้นสีน้ำเงินเท่ากับจำนวน ตัวอย่างเช่น:

#1O#O
...O.

1ชิ้นสามารถดูเพียงชิ้นเดียวสีฟ้าอื่น ๆ

ชิ้นส่วนมองเห็นซึ่งกันและกัน

ชิ้นสีน้ำเงินสองชิ้นสามารถมองเห็นซึ่งกันและกันหากอยู่ในแถวหรือคอลัมน์เดียวกันและไม่มีชิ้นสีแดงอยู่ระหว่างกัน ตัวอย่าง:

( Sเป็นตำแหน่งที่Oชิ้นส่วนสามารถมองเห็นXไม่เห็น)

   S
   S
X#SOSS
   #
   X

ชิ้นส่วนสีน้ำเงินแต่ละชิ้นต้องดูอย่างน้อยหนึ่งชิ้นสีน้ำเงินอื่น ๆ :

#O#

ทำงานได้ แต่:

#OO

หรือ:

###

ทำงาน.

คณะกรรมการการสาธิตแก้ปัญหา

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

ด้านล่างขวา 2 สามารถมองเห็นตัวเองด้านบนดังนั้นพวกเขาจะต้องเป็นสีฟ้าและด้านบนขวาจะต้องเป็นสีแดง

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

เมื่อ1เติมเต็มเราสามารถล้อมรอบด้วยชิ้นส่วนสีแดง

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

มุมซ้ายบน1สามารถเห็นได้ในทิศทางเดียวเท่านั้นดังนั้นเราจึงสามารถเติมได้

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

ตอนนี้เกี่ยวกับ2s ล่าสุด เราสามารถใส่สีน้ำเงิน 2 ชิ้นไว้เหนือพวกมันได้

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

อันสุดท้ายจะเต็มไปด้วย #

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

อินพุต

อินพุตเป็นสตริงที่มีหลายบรรทัด ขนาดจะ9x9ไม่มีพื้นที่ต่อท้าย มันมีประเภทชิ้นต่อไปนี้:

  • . ว่างเปล่า
  • # พรีเซ็ตสีแดงไม่สามารถเปลี่ยนได้
  • number หมายเลขที่ตั้งไว้ไม่สามารถเปลี่ยนแปลงได้

(โปรดทราบว่าสีน้ำเงินจะไม่อยู่ในอินพุต)

เอาท์พุต

เอาท์พุทเป็นเช่นเดียวกับการป้อนข้อมูลด้วยการเปลี่ยนแปลงที่ว่างเปล่า ( .) จะถูกแทนที่ด้วยสีแดงหรือสีน้ำเงินเพื่อแก้ปัญหาคณะกรรมการและตัวเลขจะถูกแทนที่ด้วยชิ้นส่วนสีฟ้า ( O)

ตัวอย่าง

(โปรดทราบว่าอาจมีการแก้ปัญหาหลายอย่างสำหรับแต่ละปริศนา แต่คุณจะต้องแสดงเพียงภาพเดียว)

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

ขอบคุณ@PeterTaylorและ@apsillersสำหรับความช่วยเหลือในกล่องทราย!


ฉันทำเพียงเล็กน้อยแก้ไขชื่อเพราะ "เสียง" ดีกว่าถ้าคำต่อไปนี้เริ่มต้นด้วยเสียงสระ - ฉันไม่ได้คาดหวังว่าผู้พูดที่ไม่ใช่เจ้าของภาษาอังกฤษหรือแม้แต่เจ้าของภาษาจะต้องใส่ใจกับมัน แต่มันเป็นไวยากรณ์
แมว

คำตอบ:


2

Haskell, 224 ไบต์

ไม่ผ่านการทดสอบอย่างเต็มที่เพราะช้ามาก (อย่างน้อย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

คำอธิบาย:

แนวคิดพื้นฐานคือการแสดงบอร์ดRed, Blueชิ้นเป็นรายการของรายการ0, 1ที่บรรจุรายการเป็นจำนวนเต็มเดียวเพื่อให้การแจงนับง่ายขึ้น จำนวนเต็มทั้งหมดสำหรับขนาดกระดานถูกสร้างและแปลงเป็นแบบฟอร์มที่มีจำนวนเพื่อนบ้าน บอร์ดแรกที่เป็นทางออกที่ถูกต้องของอินพุตจะถูกส่งคืน

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

and.map and$zipWith(zipWith(%))ส่วนหนึ่งที่ได้อาจแข็งแรงเล่นกอล์ฟมากที่สุดคือ: ไม่เช่นนั้นฉันพบข้อผิดพลาดเล็กน้อยโดยเพิ่มความยาวและอาจเพิ่มจำนวนกอล์ฟ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.