최악의 경우 맨해튼 제외


20

토 로이드 형으로 감싼 W x H 격자 사각형을 상상해보십시오 . 다음과 같이 항목이 그리드에 배치됩니다.

첫 번째 항목은 모든 사각형에 배치 할 수 있지만 후속 항목은 이전 항목의 맨하탄 거리 R 내에 있지 않아야합니다 ( 범위 RVon Neumann 이웃 이라고도 함 ). 위치를 신중하게 선택하면 더 이상 유효한 위치가 없어지기 전에 많은 항목을 그리드에 맞출 수 있습니다. 그러나 반대의 목표를 생각해보십시오. 배치 할 수있는 가장 적은 품목은 무엇입니까?

반경 5 제외 영역은 다음과 같습니다.

반경 5 제외 영역

여기에 또 다른 반경 5 제외 영역이 있습니다. 이번에는 가장자리 근처에서 래핑 동작이 분명합니다.

랩핑 반경 5 제외 영역

입력

세 정수

  • W : 그리드 폭 (양의 정수)
  • H : 그리드 높이 (양의 정수)
  • R : 제외 영역 반경 (음이 아닌 정수)

산출

더 이상 유효한 배치를 막기 위해 배치 할 수있는 최소 개수의 항목 인 정수 N 입니다.

세부

  • 반지름이 0이면 제외 영역이 1 제곱 (항목이있는 영역)입니다.
  • N의 반경은 N 직교 단계에서 도달 할 수있는 영역을 제외합니다 (가장자리를 환상으로 감싸는 것을 기억하십시오).

코드는 R = 0 의 사소한 경우에는 작동해야하지만 W = 0 또는 H = 0 에서는 작동하지 않아도됩니다 .

코드는 R > W 또는 R > H 인 경우도 처리해야합니다 .

시간 제한 및 테스트 사례

코드는 모든 테스트 사례를 처리 할 수 ​​있어야하며 각 테스트 사례는 5 분 이내에 완료되어야합니다. 이 작업은 쉬워야합니다 (예 : JavaScript 솔루션 예제는 각 테스트 사례마다 몇 초가 걸립니다). 시간 제한은 주로 극단적 인 무차별 접근 방식을 배제하는 것입니다. 예시적인 접근법은 여전히 ​​상당히 무차별 한 힘입니다.

한 시스템에서 5 분 이내에 코드가 완료되었지만 다른 시스템에서는 그렇지 않은 경우

입력 형식의 테스트 사례 :W H R : N

5 4 4 : 1
5 4 3 : 2
5 4 2 : 2
5 4 1 : 5

7 5 5 : 1
7 5 4 : 2
7 5 3 : 2
7 5 2 : 4

8 8 8 : 1
8 8 7 : 2
8 8 6 : 2
8 8 5 : 2
8 8 4 : 2
8 8 3 : 4

 7  6  4 : 2
 7  6  2 : 4
11  7  4 : 3
11  9  4 : 4
13 13  6 : 3
11 11  5 : 3
15 14  7 : 2
16 16  8 : 2

아이디어로 시각화하고 둘러 볼 수있는 스 니펫

예제 (비 고정) 솔루션

작은 출력에 대한 예일뿐입니다 (너비와 높이보다 크지 않은 반지름 결과). 테스트 사례를 처리 할 수 ​​있지만 시간이 초과되어 더 큰 사례를 포기합니다.


4
멋진 코드 스 니펫!
스트레칭 미치광이

@StretchManiac 덕분에 나는 어떤 의견을 환영합니다 그래서 자바 스크립트를 배우려고 노력 해요 :)
trichoplax가

1
꽤 좋은 스 니펫입니다. 나는 그 색 구성표도 좋아합니다. 팔레트에서 왔습니까?
마일

@ 마일리지 감사합니다-색상이 추측되고 약간 미세 조정됩니다 (그러나 그다지 많지는 않습니다-여전히 6이 아닌 3 문자 색상 코드입니다). 스 니펫 코드의 세 번째 줄 블록에 사용 된 색상을 볼 수 있습니다.
trichoplax

답변:


5

파이썬 2 216 182 바이트

def f(W,H,R):L={(i%W,i/W)for i in range(W*H)};M={(x,y)for x,y in L if min(x,W-x)+min(y,H-y)>R};g=lambda s:min([1+g(s-{((a+x)%W,(b+y)%H)for x,y in L-M})for a,b in s]or[1]);return g(M)

처럼 입력하십시오 f(16,16,8). @trichoplax의 sample 과 거의 동일한 알고리즘을 사용 하지만 세트를 사용합니다. 처음에는에 첫 번째 항목을 배치하지 않았지만 (0, 0)마지막 몇 가지 경우에 질식했습니다.

위의 모든 사례는 10 초 이내에 완료되며 한도 미만입니다. 사실, 케이스의 크기가 작아서 효율성이 떨어질 여지가 적으므로 중복 상태를 확인한 수표를 제거 할 수 있습니다.

(골프 도움을 위해 @trichoplax에게 감사드립니다)

넓히는:

def f(W,H,R):
  # All cells
  L={(i%W,i/W)for i in range(W*H)}                 

  # Mask: Complement of exclusion zone around (0, 0) 
  M={(x,y)for x,y in L if min(x,W-x)+min(y,H-y)>R}

  # Place recursively
  g=lambda s:min([1+g(s-{((a+x)%W,(b+y)%H)for x,y in L-M})for a,b in s]or[1])
  return g(M)

2

파이썬 3 270 262 260 251 246 226

(Sp3000에 감사합니다 :

  • -~ 대신 +1 , 어느 날 뒤에 공백을 잃을 수 있습니다 return 마지막 줄에.
  • 불필요한 괄호를 잃어 버렸습니다 W*H .
  • 람다 ...
  • 한 줄에 모든 것을 넣습니다.
  • 파이썬 모듈로 %는 음수에 긍정적 인 결과를 제공하여 20 바이트를 더 절약합니다)

이것은 Python 3으로 이식 된 질문의 JavaScript 예제 답변입니다.

너무 많은 함수 인수를 전달하지 않기 위해 두 개의 지원 함수를 계산 함수 내부로 이동하여 범위를 공유했습니다. 또한 들여 쓰기 비용을 피하기 위해 이러한 각 기능을 한 줄로 정리했습니다.

설명

이 상당히 무차별 접근 방식은 첫 번째 항목을 (0, 0)에 배치 한 다음 제외 된 모든 사각형을 표시합니다. 그런 다음 모든 사각형이 제외 될 때까지 나머지 모든 유효한 사각형에 항목을 반복적으로 배치하고 필요한 최소 항목 수를 반환합니다.

골프 코드 :

def C(W,H,R):r=range;M=lambda g:min([M(G(g,x,y))for x in r(W)for y in r(H)if g[x+W*y]]or[-1])+1;G=lambda g,x,y:[g[a+W*b]if min((x-a)%W,(a-x)%W)+min((y-b)%H,(b-y)%H)>R else 0for b in r(H)for a in r(W)];return-~M(G([1]*W*H,0,0))

Ungolfed 코드 :

def calculate(W, H, R):
    starting_min = W * H + 1
    cells = [0] * (W * H)
    grid_state = grid_with_item_added(cells, 0, 0, W, H, R)
    return min_from_here(grid_state, starting_min, W, H, R) + 1

def min_from_here(grid_state, starting_min, W, H, R):
    no_cells = True
    min = starting_min
    for x in range(W):
        for y in range(H):
            if grid_state[x + W * y] == 0:
                no_cells = False
                new_grid_state = grid_with_item_added(grid_state, x, y, W, H, R)
                m = min_from_here(new_grid_state, starting_min, W, H, R)
                if m < min:
                    min = m

    if no_cells:
        return 0
    else:
        return min + 1

def grid_with_item_added(grid_state, x, y, W, H, R):
    grid = grid_state[:]
    for a in range(W):
        for b in range(H):
            if manhattan_distance(a, b, x, y, W, H) <= R:
                grid[a + W * b] = 1

    return grid

def manhattan_distance(a, b, c, d, W, H):
    horizontal = min(abs(W + c - a) % W, abs(W + a - c) % W)
    vertical = min(abs(H + d - b) % H, abs(H + b - d) % H)
    return horizontal + vertical


if __name__ == '__main__':
    import sys
    arguments = sys.argv[1:]
    if len(arguments) < 3:
        print('3 arguments required: width, height and radius')
    else:
        print(calculate(int(arguments[0]), int(arguments[1]), int(arguments[2])))

ungolfed 코드는 함수를 정의하고 명령 줄에서 호출 할 수있는 코드도 포함합니다. 골프 코드는 표준 코드 골프 질문에 충분한 기능을 정의합니다 .

명령 행에서 골프 코드를 테스트하려면 여기에 명령 행 처리 (골프는 아님)가 포함됩니다.

명령 줄 테스트 가능한 골프 코드

def C(W,H,R):r=range;M=lambda g:min([M(G(g,x,y))for x in r(W)for y in r(H)if g[x+W*y]]or[-1])+1;G=lambda g,x,y:[g[a+W*b]if min((x-a)%W,(a-x)%W)+min((y-b)%H,(b-y)%H)>R else 0for b in r(H)for a in r(W)];return-~M(G([1]*W*H,0,0))

if __name__ == '__main__':
    import sys
    arguments = sys.argv[1:]
    if len(arguments) < 3:
        print('3 arguments required: width, height and radius')
    else:
        print(C(int(arguments[0]), int(arguments[1]), int(arguments[2])))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.