노노 그램 라인 무차별 해결


25

배경

Picross 또는 Griddlers라고도하는 Nonogram 은 2D 그리드의 각 셀이 각 줄의 연속적인 색상 셀 수를 사용하여 색상을 지정하거나 비워 둘지를 결정하는 퍼즐입니다.

다음은 솔루션이있는 비노 그램 퍼즐의 예입니다.

문제는 일부 상용 Nonogram 게임 / 모바일 앱은 수작업으로 해결할 수없는 퍼즐을 가지고 있다는 것입니다 (예 : 여러 솔루션이 있거나 깊은 역 추적이 필요함). 그러나 정답이 공백 인 셀에 색상을 지정하려고 할 때 생명력이 손실 되는 플레이어에게 생명을 제공합니다 . 이제 그 불쾌한 "퍼즐"을 무차별 대입 할 차례입니다!

작업을 단순화하기 위해 단서와 단 하나의 행만 상상해보십시오.

3 7 | _ _ _ _ _  _ _ _ _ _  _ _ _ _ _

[3,7]단서, 그리고 라인 길이는 15 개 세포이다. 가능한 해결책이 여러 개 있기 때문에이 선을 완전히 풀기 위해서는 생명을 위험에 빠뜨려 야합니다 (즉, 모든 유색 세포를 결정).

도전

단서가있는 줄 (양의 정수 목록)과 줄 길이가 주어지면 최적의 전략으로 줄을 무차별하게한다고 가정 할 때 잃어 버릴 최대 수명을 찾으십시오.

항상 컬러 셀을 추측 한다는 점에 유의하십시오 . 실제 게임에서 빈 셀 (옳거나 그른 것)을 추측하는 것은 당신의 삶에 영향을 미치지 않으므로 퍼즐을 그런 식으로 "해결"할 수 없습니다.

또한 입력이 항상 유효한 Nonogram 행을 나타내는 것으로 가정 할 수 있으므로와 같은 것에 대해 걱정할 필요가 없습니다 [6], 5.

설명

더 간단한 예를 먼저 살펴 보겠습니다.

[1,2], 5

이 줄에는 세 가지 가능성이 있습니다 ( O색상 셀, .빈 셀 ).

O . O O .
O . . O O
. O . O O

셀 0 (왼쪽부터 0부터 시작하는 인덱스)을 색칠하려고하면 다음 중 하나가 발생합니다.

  • 셀의 색상이 올바르게 표시됩니다. 이제 우리는 두 가지 가능성을 가지고 있으며 선을 완전히 해결하기 위해 셀 2와 셀 4 중에서 선택할 수 있습니다. 두 경우 모두 최악의 경우 생명을 잃게됩니다.
  • 세포는 비어 있으며 생명을 잃습니다. 이 경우이 라인에 대한 고유 한 솔루션을 이미 식별 했으므로 1 명의 생명을 잃었습니다.

따라서 답 [1,2], 5은 1입니다.

[5], 10

이진 검색? 아니.

가장 명백한 첫 번째 선택은 4 또는 5이며, 비어있는 경우 하나의 가능성을 나타냅니다 (1 생명의 비용으로). 먼저 4를 선택했다고 가정 해 봅시다. 셀 4가 실제로 채색 된 경우 왼쪽으로 확장됩니다. 즉, 생명이 손실 될 때까지 3, 2, 1 및 0을 시도하십시오 (또는 셀 0이 채색되면 생명이 전혀 소비되지 않습니다). 생명을 잃을 때마다 우리는 해결책을 독특하게 결정할 수 있습니다.

_ _ X O O _ _ _ _ _

우리는 이미 그 답이 이것이라는 것을 알고 있습니다.

. . . O O O O O . .

따라서 답 [5], 10은 1입니다.

[3,7], 15

비어있는 경우 다음 솔루션을 즉시 표시하는 셀 11로 시작하십시오.

O O O . O O O O O O O X . . .

그런 다음 12를 시도하십시오. 비어있는 경우 추가 수명이 1 회 발생하여 해결할 수있는 두 가지 가능성이 있습니다.

O O O . . O O O O O O O X . .
. O O O . O O O O O O O X . .

이제 2를 시도하십시오. 비어 있으면 [1,2], 5예제 와 유사하게 해결할 수있는 3 가지 가능성이 있습니다 .

. . X O O O . O O O O O O O .
. . X O O O . . O O O O O O O
. . X . O O O . O O O O O O O

이러한 방식으로 위험을 최소화하면 최대로 솔루션에 도달 할 수 있습니다. 2 명의 삶이 소비되었습니다.

테스트 사례

[1,2] 5 => 1
[2] 5 => 2
[1] 5 => 4
[] 5 => 0
[5] 10 => 1
[2,1,5] 10 => 0
[2,4] 10 => 2
[6] 15 => 2
[5] 15 => 2
[4] 15 => 3
[3,7] 15 => 2
[3,4] 15 => 3
[2,2,4] 15 => 4
[1,1,1,1,1,1,1] 15 => 2

[2,1,1,3,1] 15 => 3
[1,1,1,2,1] 15 => 5

마지막 두 경우에, 최적의 전략은되어 있지 최소 공백을 통과, 단순히 오른쪽 (또는 오른쪽에서 왼쪽으로) 왼쪽에서 것이다. 지적 해 주신 @crashoz에게 감사드립니다.

규칙

표준 규칙이 적용됩니다. 바이트 단위의 가장 짧은 유효한 제출이 이깁니다.

하사품

누군가가 다항식 시간 알고리즘 (정확성의 증거와 함께)을 생각해 내면 그러한 해결책에 +100 현상금을 부여합니다.


의도 된 결과는 무엇입니까 [6], 5?
Leaky Nun

당신이 추측을 할 때, 당신은 세포가 검은 색인지 추측해야합니까, 아니면 검은 색이나 흰색을 추측 할 수 있습니까?
feersum

@LeakyNun 잘못된 줄입니다. 입력이 항상 유효한 Nonogram 행이라고 가정 할 수 있습니다.
버블 러

@feersum 당신은 항상 색깔의 세포를 추측합니다. 실제 게임에서 빈 셀 (옳거나 그른 것)을 추측해도 삶에 영향을 미치지 않으므로 피드백을받을 수 없습니다.
버블 러

환상적인 도전
엔리코 보르 바

답변:


19

루비 , 85 바이트

f=->l,n,s=n-l.sum-l.size+1{*a,b=l;b&&s>0?(a[0]?1+f[a,n-b-2,s-1]:(n.to_f/b).ceil-1):0}

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

설명

l=[l1,l2,...,lx]xn

lx
nlx
nlx1+f(l,nlx)
1+f(l~,nlx2)l~l

f(l,n)={0,if 1xli+x1nnlx1if x=11+max{f(l,nlx)f(l~,nlx2),otherwise

여기에 예제 _가 알려지지 않았고, X알려진 공간이고 O, 알려진 색상의 셀이며, L생명이 손실되었습니다.

[2,2,4] 15                  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
(1) -> [2,2,4] 11           _ _ _ _ _ _ _ _ _ _ _ L X X X
    (1) -> [2,2,4] 7        _ _ _ _ _ _ _ L X X X L X X X
        0                   X X X L X X X L X X X L X X X
    (2) -> [2,2] 5          _ _ _ _ _ X O O O O L L X X X
        0                   O O X O O X O O O O L L X X X 
(2) -> [2,2] 9              _ _ _ _ _ _ _ _ _ X O O O O L
    (1) -> [2,2] 7          _ _ _ _ _ _ _ L X X O O O O L
        (1) -> [2,2] 5      _ _ _ _ _ L X L X X O O O O L
            0               O O X O O L X L X X O O O O L
        (2) -> [2] 3        _ _ _ X O O L L X X O O O O L
            1               O O L X O O L L X X O O O O L               
    (2) -> [2] 5            _ _ _ _ _ X O O L X O O O O L
        2                   O O L L X X O O L X O O O O L

그것은 이진 트리를 만들고, 목숨을 잃기 위해 나무의 최대 높이를 세면됩니다. 그러나 모든 분기를 평가하기 때문에 이됩니다. 우리는 더 잘할 수 있습니다.O(2n)

각 단계에서 올바른 지점을 "선택"하는 데 도움이 되는 비용 함수 를 정의합시다 .h

h(l,n)=n1xlix+1

h 는 모든 단서를 하나의 공백으로 묶을 경우 우리가 가지고있는 불필요한 공간의 수를 계산합니다. 따라서 본질적으로 우리가 인스턴스를 해결하기 위해 얼마나 많은 생명이 필요한지, 지표가 높을수록 더 많은 생명이 필요하다는 지표입니다. 아이디어는이 지표를 재귀 공식에 적용하는 것입니다.

정의에 따라 h

h(l,nlx)=nlx1xlix+1=(n1xlix+1)lx=h(l,n)lx

그리고

h(l~,nlx2)=nlx21x1li(x1)+1=(n1xlix+1)1=h(l,n)1

그런 다음

h(l,n)={0,if 1xli+x1nnlx,if x=1max{h(l,nlx)+lxh(l~,nlx2)+1,otherwise

우리 는 최악의 경우를 얻기 위해 각 단계에서 를 최대화하기를 원 하므로 반복에서 두 표현의 차이를 확인하십시오.h

[h(l,nlx)+lx][h(l~,nlx2)+1]=nlxn1xlix+1+lx[nlx21x1li(x1)+1+1]=2

[h(l,nlx)+lx][h(l~,nlx2)+1]=2[h(l,nlx)+lx][h(l~,nlx2)+1]<0[h(l,nlx)+lx]<[h(l~,nlx2)+1]
따라서 두 번째 표현은 항상 최대이므로 첫 번째 표현은 제거 할 수 있습니다

h(l,n)={0,if 1xli+x1nnlx,if x=1h(l~,nlx2)+1otherwise

마지막으로이 재귀 정의 는 함수 옵션 (2) 가 항상 최악의 경우 임을 나타냅니다 (최대 가능성을 제공합니다 (즉, 최대화 )).hfh

f(l,n)={0,if 1xli+x1nnlx1if x=11+f(l~,nlx2),otherwise

모든 단계 에서 을 3 이상 줄이며 이제는 단일 재귀 호출이 있습니다. 복잡성은nO(n)


2
PPCG에 오신 것을 환영합니다, 놀라운 첫 번째 게시물!
cole

1
@cole 그것은 첫 번째 게시물이 아니지만 확실히 믿어지지 않습니다! 매우 영리한 접근 +1
Mr. Xcoder

1
멋진 일. 그때까지 아무도 심각한 논리적 결함을 발견하지 못하면 2 일 후에 현상금을 수여합니다.
버블 러

2

파이썬, 303 289 바이트

오랜 시간에 처음 골프를해서 과도한 지방이 많을 수 있습니다. ( 14 바이트-가치를 찾은 Jo King 에게 감사합니다 .)

함수 f는 가능한 모든 배열을 생성합니다 (항상 첫 문자가 공백이지만 항상 호출하기 전에 길이를 1 씩 늘리면 괜찮습니다). 함수 g는 가장 적은 수의 공백이있는 위치를 선택하고 되풀이합니다. 함수 h는 그것들을 합칩니다.

f=lambda l,n:["."*i+"X"*l[0]+c for i in range(1,n-l[0]+1)for c in f(l[1:],n-i-l[0])]if l else["."*n]
def g(q,n):O,X=min([[[p[:i]+p[i+1:]for p in q if p[i]==u]for u in".X"]for i in range(n)],key=lambda x:len(x[0]));return(len(q)>1)*1and max(1+g(O,n-1),g(X,n-1))
h=lambda l,n:g(f(l,n+1),n+1)

예제는 모두 정상적으로 실행됩니다.

>>> h([3,7],15)
2
>>> h([3,4],15)
3
>>> h([1,1,1,2,1],15)
6


1
돌아올 False0있습니까? 그렇다면, 당신은 변경할 수 있습니다 (len(q)>1)*1andlen(q)>1and. 당신은 반환 할 수 없습니다 경우 False에 대해 0그 작업을 수행하지만, 변화 g(f(l,n+1),n+1)1*g(f(l,n+1),n+1)그것은 것입니다 여전히 한 바이트 저장
재커리

1
더 나은는 : 경우에 False허용되지 않는 0대신 변화의, g(f(l,n+1),n+1)1*g(f(l,n+1),n+1)로 변경,+g(f(l,n+1),n+1)
재커리

2
또한 h=바이트 수 를 계산할 필요가 없습니다
Zacharý

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