이 세포들을 그룹화하십시오!


12

이 도전은 게임 Layerz를 기반으로합니다 .

stdin 또는 함수 인수로 각 셀에 공백이 포함 된 2D 직사각형 셀 배열 (벌금없이 공백 대신 0을 사용하도록 선택할 수 있음), 1, a 2, 3 또는 4 ; 공백이 아닌 각 셀이 정확히 하나의 영역에 포함되도록 유효한 영역으로 나누는 방법을 찾으십시오 (아래 정의 참조). 그런 다음 합리적인 형식으로 찾은 솔루션을 출력하십시오. 솔루션이 없으면 출력을 생성하지 않고 정지하거나 단일 거짓 값을 출력 한 다음 정지합니다.

다음 중 하나가 유효한 지역을 구성합니다.

  • 1을 포함하는 단일 셀
  • 2와 비어 있지 않은 직교 이웃 중 하나를 포함하는 셀
  • 비어 있지 않은 직교 이웃 중 3 개와 정확히 2 개를 포함하는 셀
  • 공백이 아닌 직교 이웃 4 개와 정확히 3 개를 포함하는 셀

이것은 이므로 바이트 단위의 가장 짧은 유효한 답변이 이깁니다.

일부 테스트 사례 :

1. 다소 사소한 것 :

여기에 이미지 설명을 입력하십시오

그리고 이것은 각 지역마다 다른 색상의 솔루션입니다.

여기에 이미지 설명을 입력하십시오

2. 더 흥미로운 것

여기에 이미지 설명을 입력하십시오

이 솔루션에는 둘 이상의 솔루션이 있지만 그중 하나가 있습니다.

여기에 이미지 설명을 입력하십시오

3. 공백이 포함 된 작은 솔루션 (솔루션이 없음) (둘 중 하나를 사용하여 셋을 "캡처"하는지 또는 셋 중 둘을 사용하여 둘 중 하나를 사용하는지 여부에 따라 인접하지 않은 [따라서 그룹화 할 수없는] 두 쌍 또는 그 자체로 단일 두 쌍) :

여기에 이미지 설명을 입력하십시오

이 그리드에는 솔루션이 없기 때문에이 그리드가 주어지면 출력을 생성하지 않고 프로그램을 중단해야합니다.

4.이 것 (상단 2 개가 한 셀을 왼쪽으로 이동 한 경우)에는 다음과 같은 해결책이 있습니다.

여기에 이미지 설명을 입력하십시오

해결책:

여기에 이미지 설명을 입력하십시오

(오른쪽 아래 2는 3을 "캡처"하는 데 사용됩니다)

5. 우리는 약 네 개의 테스트 케이스가 필요했기 때문에 :

하나의 솔루션 :


2
테스트 케이스의 ASCII 버전이 있으면 사람들이 모두 입력 할 필요가 없으며, 4유효한 입력 인 경우 테스트 케이스도 다루어야 합니다.
Martin Ender

1
직교 이웃은 오른쪽 위 아래 또는 대각선을 의미합니까? 오른쪽 아래로만 왼쪽으로 향하면 3이 다른 2 개의 3과 같은 지역에있는 방법은 무엇입니까? 그들 중 하나는 직교 이웃이 아닙니다.
Eyal Lev

@EyalLev 왼쪽 위에서 만 아래로. 오른쪽 상단 3과 2 개의 이웃이이 지역을 구성합니다.
SuperJedi224

@ SuperJedi224는 오른쪽 상단 3이며 두 이웃이 유효한 지역을 구성하지만 그 이웃은 그렇지 않습니다. 영역이 "닫힌 세트"일 필요는 없습니까? 즉, 해당 지역의 모든 회원이 해당 지역의 유효한 회원이어야합니까?
Eyal Lev

답변:


3

나는이 도전이 1 년이 넘었 음을 알고 있지만, "답이없는"에서 이것을 발견하고 나에게 흥미로워 보였다.

"루트"셀의 숫자가 각 지역에서 유일하게 중요한 숫자라고 가정하면 (예제에서 제외 가능) 다음은 역 추적 솔루션입니다.

파이썬 (3) , 355 (351) 349 바이트

from itertools import*
def f(a):
 D=len(a[0])+1;S={D*r+c for r in range(len(a))for c in range(D-1)if a[r][c]};s=[{x,*t}for x in S for t in combinations({x-D,x-1,x+1,x+D}&S,a[x//D][x%D]-1)]
 def B(s,S,d=1):
  if{0}>S:return a
  if[]==s:return 0
  h,*t=s
  if h<=S:
   for x in h:a[x//D][x%D]=d
  return h<=S and B(t,S-h,d+1)or B(t,S,d)
 return B(s,S)

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

입력 형식은 2D 정수 목록이고 공백은 0이며 출력 형식은 숫자 당 하나의 영역을 나타내는 2D 정수 목록입니다. 지역 번호는 하나에서 시작합니다. 빈 셀에 대해서는 0이 예약되어 있습니다 (입력에서와 같이). 주어진 입력을 해결할 수없는 경우, 함수는 단일 제로 (거짓 값)를 반환합니다.

예를 들어, 테스트 케이스 5는 다음과 같이 입력됩니다.

[[2,3,2],
 [3,4,3],
 [0,4,0],
 [3,3,3],
 [2,3,2],
 [0,3,0]]

출력은

[[1,1,1],
 [2,2,2],
 [0,2,0],
 [3,4,5],
 [3,4,5],
 [0,4,0]]

코멘트가없는 언 골프 드 :

from itertools import*
def f(a):
 # Rows, cols, fake-cols to prevent neighbors wrap around
 R,C=len(a),len(a[0]);D=C+1
 # All valid cells represented as integers
 S={D*r+c for r in range(R) for c in range(C) if a[r][c]}
 # All valid regions rooted at each cell
 s=[{x,*t} for x in S for t in combinations({x-D,x-1,x+1,x+D}&S,a[x//D][x%D]-1)]
 # Start backtracking
 return backtrack(a,s,S,D)

# a: array to fill in the region numbers
# s: current candidates of regions
# S: current remaining cells to cover
# D: constant from f
# d: recursion depth == group number in the result
def backtrack(a,s,S,D,d=1):
 # Empty S: the board is correctly covered, return the result
 if not S:return a
 # Empty s: no more candidate regions to use, return false
 if not s:return 0
 h,*t=s
 # h is not a subset of S: h is not a valid cover, try with the rest using same depth
 if not h<=S:return backtrack(a,t,S,D,d)
 # h is a valid cover, write d to the cells in h
 for x in h:a[x//D][x%D]=d
 return backtrack(a,t,S-h,D,d+1)or backtrack(a,t,S,D,d)
 

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

참고 : 이것은 NP- 완전으로 잘 알려진 특수 세트 포장의 경우입니다 . 이 특정 문제는 세트 크기가 제한적이며 (최대 4 개) 다항식 시간에 "좋은"세트 패킹을 찾기위한 근사 알고리즘이 있지만 가능한 최대 세트 패킹을 보장하지는 않습니다 (이 문제에서 엄격하게 요구됨).

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