다다미 바리 솔버


10

배경

Tatamibari 는 Nikoli가 디자인 한 논리 퍼즐입니다.

Tatamibari 퍼즐은 심볼의 세 가지 다른 종류의 사각형 격자에서 재생된다 +, -. 그리고 |. 솔버는 다음 규칙에 따라 그리드를 사각형 또는 사각형 영역으로 분할해야합니다.

  • 모든 파티션에는 정확히 하나의 기호가 포함되어야합니다.
  • +기호 사각형에 포함되어야합니다.
  • |심볼 폭보다 큰 높이를 가진 직사각형 내에 포함되어야한다.
  • -심볼 높이보다 더 큰 폭을 갖는 직사각형 내에 포함되어야한다.
  • 네 조각은 같은 구석을 공유하지 않을 수 있습니다. (일반적으로 일본식 다다미 타일이 배치되는 방식입니다.)

다음은 솔루션이 포함 된 예시 퍼즐입니다.

다다미 바리 퍼즐의 예 다다미 바리 퍼즐 솔루션의 예

직무

주어진 다다미 바리 퍼즐을 해결하십시오.

입출력

입력은 주어진 다다미 바리 퍼즐을 나타내는 2D 그리드입니다. 각 셀은 4 개 문자 중 하나를 포함 +, -, |, 당신의 선택의 문자는 비 단서 셀을 나타냅니다. 테스트 사례에서는 별표 *가 사용됩니다.

Tatamibari 퍼즐에 대한 유효한 솔루션을 모호하지 않게 표현할 수있는 적절한 출력 형식을 선택할 수 있습니다. 여기에는 다음이 포함되지만 이에 국한되지 않습니다. (의심스러운 경우 의견을 요청하십시오.)

  • 각 튜플에 사각형의 상단 인덱스, 왼쪽 인덱스, 너비 및 높이가 포함 된 4 개의 튜플 목록 (또는 동등한 표현)
  • 입력과 같은 모양의 숫자 그리드. 각 숫자는 사각형을 나타냅니다.
  • 각 세트가 사각형으로 셀의 모든 좌표를 포함하는 좌표 세트 목록

퍼즐에 여러 개의 솔루션이있는 경우 유효한 솔루션을 여러 개 (하나 이상) 출력 할 수 있습니다. 입력 값에는 하나 이상의 솔루션이 보장됩니다.

테스트 사례

Puzzle:
|-*
*+|
*-*
Solution:
122
134
554
=====
Puzzle:
+***
**|*
*+**
***-
Solution:
1122
1122
3322
3344
======
Puzzle:
|*+*+
*****
****-
***+|
+****
Solution:
12233
12233
44444
55667
55667
=======
Puzzle:
****-**
**-**|*
*|*****
****-**
*******
**+*|**
*****+*
One possible solution:
1122222
1133344
1155544
1155544
6667744
6667788
6667788
===========
Puzzle:
*-****|+**
+*-******|
****+*****
*-******||
**++|*****
+****-|***
-****-**+*
********-*
|*+*+|****
*-*--**+*+
Solution:
1111122334
5666622334
7777822994
7777A2299B
CCDEA2299B
CCFFFFGGHH
IIIIJJGGHH
KLLMMNGGOO
KLLMMNGGPP
QQRRSSSTPP

규칙

표준 규칙이 적용됩니다. 바이트 단위의 가장 짧은 코드가 이깁니다.

답변:


5

파이썬 (2) , 417 (374) 366 바이트

입력은 ~단서가 아닌 행 목록입니다 . 형식으로 stderr에 단일 솔루션을 출력합니다 (x_start, width, y_start, height).

R=range
k=input()
X,Y=len(k[0]),len(k)
W,H=R(X),R(Y)
Q=[[]]
for q in Q:C=[(x,y)for(a,b,c,d)in q for x in(a,a+b)for y in(c,c+d)];max(map(C.count,C+W))<4>0<all(sum(w>x-s>-1<y-t<h<[c for r in k[t:t+h]for c in r[s:s+w]if'~'>c]==['+|-'[cmp(h,w)]]for(s,w,t,h)in q)==1for x in W for y in H)>exit(q);Q+=[q+[(s,w+1,t,h+1)]for s in W for w in R(X-s)for t in H for h in R(Y-t)]

온라인으로 사용해보십시오! 제안 된 테스트 사례에는이 방법이 너무 비효율적입니다.


언 골프

grid = input()
total_width = len(grid[0])
total_height = len(grid)

partitions = [[]]

for partition in partitions:
    # list the corners of all rectangles in the current partition
    corners = [(x, y)
               for (start_x, width, start_y, height) in partition
               for x in (start_x, start_x + width)
               for y in (start_y, start_y + height)]
    # if no corners appears more than three times ...
    if corners != [] and max(map(corners.count, corners)) < 4:
        # .. and all fields are covered by a single rectangle ...
        if all(
                sum(width > x - start_x > -1 < y - start_y < height
                    for (start_x, width, start_y, height) in partition) == 1
                for x in range(total_width)
                for y in range(total_height)):
            # ... and all rectangles contain a single non-~
            # symbol that matches their shape:
            if all(
                [char for row in grid[start_y: start_y + height]
                    for char in row[start_x:start_x + width] if '~' > char]
                == ['+|-'[cmp(height, width)]]
                    for (start_x, width, start_y, height) in partition):
                # output the current partition and stop the program
                exit(partition)

    # append each possible rectangle in the grid to the current partition,
    # and add each new partition to the list of partitions.
    partitions += [partition + [(start_x, width + 1, start_y, height + 1)]
                   for start_x in range(total_width)
                   for width in range(total_width - start_x)
                   for start_y in range(total_height)
                   for height in range(total_height - start_y)]

온라인으로 사용해보십시오!

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