전략적 소멸자


15

이 게시물은 이 mathoverflow 게시물에서 느슨하게 영감을 받았습니다 .

소멸자는 Conway의 삶의 게임에서 한 단계 후에 완전히 사라지는 패턴입니다. 예를 들어 다음 패턴은 크기 9 Vanisher입니다.

사이즈 9 배니 셔

배니 셔의 흥미로운 특성은 단순히 더 많은 라이브 셀을 추가하여 모든 패턴 을 배니싱 패턴 으로 만들 수 있다는 것입니다. 예를 들어 다음 패턴은 소멸 패턴으로 완전히 둘러싸 일 수 있습니다.

사라지지 않는에워싸는

그러나 우리는 더 적은 수의 살아있는 세포를 추가함으로써 그 패턴을 배니 셔로 만들 수 있습니다.

작은 인클로저 더 작은 인클로저

당신의 임무는 우리를 위해이 작업을 수행하는 프로그램을 작성하는 것입니다. 입력으로 패턴이 주어지고 입력을 포함하는 소실 패턴을 출력합니다. 반드시 최적의 패턴을 찾을 필요는 없습니다.

채점

프로그램의 점수를 매기려면 크기가 6 인 polyplet 모두에서 실행해야합니다 (대칭 적으로 동등한 경우는 두 번 세지 않음). 다음 은 각각의 polyplet을 자체 라인에 포함하는 pastebin입니다. 총 524 개가 있어야합니다. 이들은 (x,y)각각 라이브 셀의 위치 인 6 개의 좌표 ( 튜플) 의 목록으로 표시됩니다 .

점수는 이러한 모든 폴리 플렛을 배니 셔로 만들기 위해 추가 된 총 새 셀 수입니다.

관계의 경우 프로그램을 실행할 크기 7 폴리 폴릿 목록을 제공합니다.

IO

IO를 매우 유연하게 사용하여 합리적인 형식으로 입력 및 출력 할 수 있지만 제공 한 원시 입력 데이터와 동일한 형식으로 입력을 원할 것입니다. 여러 실행에서 형식이 일관되어야합니다.

타이밍

프로그램은 적절한 시스템에서 적절한 시간 (약 <1 일) 동안 실행되어야합니다. 나는 정말로 이것을 너무 많이 시행하지는 않을 것입니다. 그러나 우리 모두가 좋은 경기를한다면 좋겠습니다.


(물론 당신은 당신 자신의 코드를 채점 할 수 있어야합니다)
user202729


하드 코딩을 금지 하시겠습니까?
FlipTack

1
@FlipTack 나는 이미 표준 허점이라고 확신합니다. 또한 잘 작성된 프로그램은 아마도 인간만큼이나 좋습니다.
Post Rock Garf Hunter

1
@ Οurous 나는 단지 세 번째 타이 브레이커를 제거 할 것 같아요.
Post Rock Garf Hunter

답변:


4

파이썬 + Z3 , 점수 = 3647

8 코어 시스템에서 14 초 안에 실행됩니다.

from __future__ import print_function

import ast
import multiprocessing
import sys
import z3

def solve(line):
    line = ast.literal_eval(line)
    x0, x1 = min(x for x, y in line) - 2, max(x for x, y in line) + 3
    y0, y1 = min(y for x, y in line) - 2, max(y for x, y in line) + 3
    a = {(x, y): z3.Bool('a_{}_{}'.format(x, y)) for x in range(x0, x1) for y in range(y0, y1)}
    o = z3.Optimize()
    for x in range(x0 - 1, x1 + 1):
        for y in range(y0 - 1, y1 + 1):
            s = z3.Sum([
                z3.If(a[i, j], 1 + ((i, j) != (x, y)), 0)
                for i in (x - 1, x, x + 1) for j in (y - 1, y, y + 1) if (i, j) in a
            ])
            o.add(z3.Or(s < 5, s > 7))
    o.add(*(a[i, j] for i, j in line))
    o.minimize(z3.Sum([z3.If(b, 1, 0) for b in a.values()]))
    assert o.check() == z3.sat
    m = o.model()
    return line, {k for k in a if z3.is_true(m[a[k]])}

total = 0
for line, cells in multiprocessing.Pool().map(solve, sys.stdin):
    added = len(cells) - len(line)
    print(line, added)
    x0, x1 = min(x for x, y in cells), max(x for x, y in cells) + 1
    y0, y1 = min(y for x, y in cells), max(y for x, y in cells) + 1
    for y in range(y0, y1):
        print(''.join('#' if (x, y) in line else '+' if (x, y) in cells else ' ' for x in range(x0, x1)))
    total += added
print('Total:', total)

전체 출력


1
이것이 어떻게 작동하는지에 대한 적절한 설명은 좋을 것이고 나의 투표에서 이길 것입니다. 그것은 polyplet을 둘러싼 직사각형 영역에 세포를 추가하는 무차별적인 힘을 시도하는 것 같습니다.
Level River St

+어떤 경우에는 왜 주 모양 과 분리되어 있는지 명확하지 않지만 새로운 세포가 생성되는 것을 피해야합니다. 따라서 이러한 솔루션이 최적입니까?
레벨 리버 St

호기심에서 z3.Or바닐라 대신 사용 하는 이유는 a or b무엇입니까? 순전히 성능입니까, 아니면 다른 기능이 있습니까?
caird coinheringaahing

@cairdcoinheringaahing 이것이 상징적 솔루션 인 것 같습니다.
user202729

1
@AndersKaseorg 1. 솔루션이 최적인지 묻는 내 의견에 대답하지 않았습니다. 이것은 답변 게시를 고려하는 다른 사람에게 매우 중요합니다. 2. Z3이 당신의 대답에서 무엇을하는지 설명하지 않으면 나는 그것이 문서를 읽을 시간이 없기 때문에 그것이 무엇을 추측 할 수 있기 때문에 무차별 짐작에 대한 무작위 추측입니다. 3이 답변에는 코드에 대한 공감대가 필요하지만 실제로는 위의 두 가지 사항에 대한 설명이 답변에 추가 될 때까지 공감하지 않습니다.
레벨 리버 세인트
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.