파이썬 2 3, 141-15 = 126
def win(x,y):w([y]*x)
w=lambda b,f=print:not[f(r+1,c+1)for r,p in enumerate(b)for c in range(p)if(r+c)*w(b[:r]+[min(i,c)for i in b[r:]],max)]
무차별 미니맥 검색. 가능한 모든 움직임에 대해, 우리는 그 움직임을 한 후에 상대방이 이길 수 있는지 재귀 적으로 봅니다. 꽤 약한 골프; 다른 사람은 훨씬 더 잘할 수 있어야합니다. 이것은 APL의 직업처럼 느껴집니다.
win
공용 인터페이스입니다. 보드의 크기를 가져와 보드 표현으로 변환 한 후로 전달합니다 w
.
w
minimax 알고리즘입니다. 보드 상태를 취하고 모든 이동을 시도하고 승리 한 이동에 해당하는 요소를 가진 목록을 작성하고 목록이 비어 있으면 True를 반환합니다. 기본값을 사용하면 f=print
목록을 작성하면 승리 한 동작을 인쇄하는 부작용이 있습니다. 함수 이름은이기는 동작 목록을 반환 할 때 더 의미가 있었지만 not
공간을 절약하기 위해 목록 앞을 이동했습니다 .
for r,p in enumerate(b)for c in xrange(p) if(r+c)
: 가능한 모든 동작을 반복합니다. 1 1
법적 소송이 아닌 것으로 간주되어 기본 사례를 약간 단순화합니다.
b[:r]+[min(i,c)for i in b[r:]]
: 좌표로 표시된 이동 후 보드의 상태를 구성 r
하고c
.
w(b[:r]+[min(i,c)for i in b[r:]],max)
: 새 상태가 손실 상태인지 확인하기 위해 되풀이합니다. max
내가 찾을 수있는 가장 짧은 함수는 두 개의 정수 인수를 취하고 불평하지 않습니다.
f(r+1,c+1)
: f
가 인쇄되면 이동을 인쇄합니다. 도대체 무엇이f
목록 길이를 채우는 값을 생성합니다.
not [...]
: 빈 목록을 not
반환 True
하고False
비어 있지 않은 경우 .
훨씬 더 큰 입력을 처리하기위한 메모를 포함하여 완전히 압축되지 않은 원래 Python 2 코드 :
def win(x, y):
for row, column in _win(Board([y]*x)):
print row+1, column+1
class MemoDict(dict):
def __init__(self, func):
self.memofunc = func
def __missing__(self, key):
self[key] = retval = self.memofunc(key)
return retval
def memoize(func):
return MemoDict(func).__getitem__
def _normalize(state):
state = tuple(state)
if 0 in state:
state = state[:state.index(0)]
return state
class Board(object):
def __init__(self, state):
self.state = _normalize(state)
def __eq__(self, other):
if not isinstance(other, Board):
return NotImplemented
return self.state == other.state
def __hash__(self):
return hash(self.state)
def after(self, move):
row, column = move
newstate = list(self.state)
for i in xrange(row, len(newstate)):
newstate[i] = min(newstate[i], column)
return Board(newstate)
def moves(self):
for row, pieces in enumerate(self.state):
for column in xrange(pieces):
if (row, column) != (0, 0):
yield row, column
def lost(self):
return self.state == (1,)
@memoize
def _win(board):
return [move for move in board.moves() if not _win(board.after(move))]
데모:
>>> for i in xrange(7, 11):
... for j in xrange(7, 11):
... print 'Dimensions: {} by {}'.format(i, j)
... win(i, j)
...
Dimensions: 7 by 7
2 2
Dimensions: 7 by 8
3 3
Dimensions: 7 by 9
3 4
Dimensions: 7 by 10
2 3
Dimensions: 8 by 7
3 3
Dimensions: 8 by 8
2 2
Dimensions: 8 by 9
6 7
Dimensions: 8 by 10
4 9
5 6
Dimensions: 9 by 7
4 3
Dimensions: 9 by 8
7 6
Dimensions: 9 by 9
2 2
Dimensions: 9 by 10
7 8
9 5
Dimensions: 10 by 7
3 2
Dimensions: 10 by 8
6 5
9 4
Dimensions: 10 by 9
5 9
8 7
Dimensions: 10 by 10
2 2