0h n0 보드 풀기


19

0h n0 은 스도쿠 나 지뢰 찾기와 같은 매우 간단하고 즐거운 게임입니다.

게임 규칙

(가능한 경우 게임 에서 튜토리얼 을 사용하는 것이 좋습니다. 매우 간단하고 유용합니다)

퍼즐은 n * n고정 된 조각과 빈 셀을 포함 하는 보드로 시작 하며 솔버는 빈 셀을 조각으로 채우고 고정 된 조각에 의해 부과 된 모든 제약 조건을 충족시키는 방법을 찾아야합니다. 약어와 함께 사용할 조각 유형은 다음과 같습니다.

  • # 빨간 조각 (파란 조각의 블록보기)
  • O 파란 조각
  • . 빈 위치
  • number번호가 매겨진 파란색 조각 ( number숫자> 0)

번호가 매겨진 모든 조각은 숫자와 정확히 같은 양의 파란색 조각을보아야합니다. 예를 들면 다음과 같습니다.

#1O#O
...O.

1조각은 다른 하나의 파란색 조각을 볼 수 있습니다.

조각들이 서로를 보는 방법

두 개의 파란색 조각이 같은 행이나 열에 있고 그 사이에 빨간색 조각이 없으면 서로를 볼 수 있습니다. 예:

( 조각이 볼 수 S있는 위치입니다. )OX

   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

이제 그 마지막에 대해 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 에게 감사드립니다 !


다음 단어가 모음으로 시작하면 "an"소리가 더 좋기 때문에 제목을 아주 조금만 편집했습니다. 나는 영어가 모국어가 아닌 사람이나 원어민이 그것을 귀찮게 생각하지는 않지만 문법적입니다.
고양이

답변:


2

하스켈, 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(%)). 그렇지 않으면, 나는 길이를 추가하고 아마도 더 골프를 칠 수있는 몇 가지 off-by-one 오류를 발견했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.