Trăn 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)]
Brax-lực tìm kiếm tối thiểu. Đối với mọi di chuyển có thể, chúng tôi xem xét đệ quy xem đối thủ có thể giành chiến thắng sau khi chúng tôi thực hiện di chuyển đó không. Khá yếu chơi golf; người khác sẽ có thể làm tốt hơn nhiều. Cảm giác này giống như một công việc cho APL.
winlà giao diện công cộng. Nó lấy kích thước của bảng, chuyển đổi nó thành một bảng đại diện và chuyển nó sang w.
wlà thuật toán minimax. Nó có một trạng thái bảng, thử tất cả các di chuyển, xây dựng một danh sách có các yếu tố tương ứng với các nước đi chiến thắng và trả về True nếu danh sách trống. Với mặc định f=print, việc xây dựng danh sách có tác dụng phụ là in các bước đi chiến thắng. Tên hàm được sử dụng để có ý nghĩa hơn khi nó trả về một danh sách các bước di chuyển chiến thắng, nhưng sau đó tôi di chuyển notphía trước danh sách để tiết kiệm một khoảng trống.
for r,p in enumerate(b)for c in xrange(p) if(r+c): Lặp đi lặp lại tất cả các động thái có thể. 1 1được coi là không phải là một động thái hợp pháp, đơn giản hóa trường hợp cơ sở một chút.
b[:r]+[min(i,c)for i in b[r:]]: Xây dựng trạng thái của bảng sau khi di chuyển được biểu thị bằng tọa độ rvà c.
w(b[:r]+[min(i,c)for i in b[r:]],max): Recurse để xem liệu trạng thái mới là trạng thái mất. maxlà hàm ngắn nhất tôi có thể tìm thấy sẽ có hai đối số nguyên và không phàn nàn.
f(r+1,c+1): Nếu flà in, in di chuyển. Dù flà gì , nó tạo ra một giá trị để đệm chiều dài danh sách.
not [...]: nottrả về Truecho danh sách trống và Falsecho nonempty.
Mã Python 2 gốc, hoàn toàn không được mã hóa, bao gồm ghi nhớ để xử lý các đầu vào lớn hơn nhiều:
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))]
Bản giới thiệu:
>>> 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