파이썬 2.7
이것은 진행중인 작업 제출물로 다른 응답자에게 골격 / 영감을주기 위해 제공합니다. 가능한 모든 우승 라인을 나열한 다음 휴리스틱을 적용하여 해당 라인의 가치에 따라 점수를 매 깁니다. 현재 휴리스틱은 비어 있습니다 (슈퍼 시크릿 작업). 또한 승리 및 충돌 오류 처리를 추가했습니다.
문제에 대한 참고 사항
이기는 선은 몇 개입니까? 1 차원 경우를 고려하십시오. 2 개의 정점, 1 개의 모서리 및 1 개의 선이 있습니다. 2 차원에서는 2 개의 선으로 연결된 4 개의 정점과 2 * n 개의 선으로 연결된 4 개의 모서리가 있습니다. 3 차원에는 4 개의 선으로 연결된 8 개의 정점, 6 * n 개의 선으로 연결된 12 개의 모서리 및 3*n^2
선으로 연결된 6 개의면이 있습니다.
일반적으로 정점을 0면, 모서리를 1면 등이라고 부릅니다. 그런 다음 N(i)
i면 d
의 수, 치수의 수 및 n
측면 길이를 나타냅니다. 그런 다음 당첨 횟수는 0.5*sum(N(i)*n^i,i=0..d-1)
입니다.
위키 백과 당 N(i)=2^(d-i)*d!/(i!*(n-1)!)
이므로 최종 공식은 다음과 같습니다.
sum(2^(d-i-1) n^i d! / (i! * (n-i)!),i=0..d-1)
wolfram | alpha가별로 좋아하지 않는 이것은 매우 빠르게 커지므로 프로그램이 d> 8에 대해 관리 가능한 런타임을 가질 것으로 기대하지 않습니다.
일부 결과 (포맷에 대해 죄송합니다.
d\n 0 1 2 3 4 5 6 7 8 9
0 1 1 1 1 1 1 1 1 1 1
1 2 4 6 8 10 12 14 16 18 20
2 4 11 26 47 74 107 146 191 242 299
3 8 40 120 272 520 888 1400 2080 2952 4040
4 16 117 492 1437 3372 6837 12492 21117 33612 50997
5 32 364 2016 7448 21280 51012 107744 206896 368928 620060
6 64 1093 8128 37969 131776 372709 908608 1979713 3951424 7352101
7 128 3280 32640 192032 807040 2687088 7548800 18640960 41611392 85656080
8 256 9834 130809 966714 4907769 19200234 62070009 173533434 432891129 985263594
I / O
현재 입력은 다음과 같이 입력해야합니다 tictactoe.py <ret> n,d <ret> move;move <ret>
.-여러 줄을 기록하고 final은 없습니다 ;
.
출력은 다음과 같습니다 (x_1,x_2,x_3...)
.
tictactoe.py <ret> 6,5 <ret> <ret>
=> 0, 0, 0, 0, 0
tictactoe.py <ret> 6,5 <ret> 0,0,0,0,0;0,0,0,0,5 <ret>
=> 0, 0, 0, 5, 0
# Notes on terminology:
#
# - A hypercube is the region [0,n]^d
# - An i-facet is an i-dimensional facet of a hypercube,
# which is to say, a 0-facet is a vertex, a 1-facet an
# edge, a 2-facet a face, and so on.
# - Any tuple {0,n}^i is a vertex of an i-hypercube
# which is why I've used vertex to describe such
# tuples
# - A winning line is a set of n coordinates which joins
# two opposite i-facets
# - i-facets are opposite if they differ in every co-
# ordinate which defines them
#
# Test Data:
#
import numpy
import itertools
def removeDuplicates(seq):
noDupes = []
[noDupes.append(i) for i in seq if not noDupes.count(i)]
return noDupes
def listPairedVertices (i,n):
"""
listPairedVertices returns a list L of elements of {0,n}^i which has the
property that for every l in L, there does not exist l' such that
l+l' = {n}^i.
"""
vertices = numpy.array([[b*(n-1) for b in a] for a in [
list(map(int,list(numpy.binary_repr(x,i)))) for x in range(2**i)
]])
result = []
while len(vertices)>1:
for j in range(len(vertices)):
if numpy.all(vertices[j] + vertices[0] == [n-1]*i):
result.append(vertices[0])
vertices=numpy.delete(vertices,[0,j],axis=0)
break
return result
def listSequences (d,l):
"""
listSequences returns the subset of {0,1}^d having precisely n 1s.
"""
return numpy.array([
r for r in itertools.product([0,1],repeat=d) if sum(r)==l
])
def listPaddedConstants (s,n):
"""
listPaddedConstants takes a sequence in {0,1}^d and returns a number in
{0..n}^sum(s) padded by s
"""
result = numpy.zeros([n**sum(s),len(s)],dtype=numpy.int)
for i,x in enumerate([list(z) for z in
itertools.product(range(n),repeat=sum(s))]):
for j in range(len(s)):
if s[j]: result[i][j] = x.pop()
return result
def listWinningVectorsForDimension(d,i,n):
"""
List the winning lines joining opposite i-facets of the hypercube.
An i-facet is defined by taking a vertex v and a sequence s, then forming
a co-ordinate C by padding v with zeroes in the positions indicated by s.
If we consider s = s_0.e_0 + s_1+e_1... where the e_j are the canonical
basis for R^d, then the formula of the i-facet is
C+x_0.s_0.e_0+x_1.s_1.e_1...
for all vectors x = (x_0,x_1...) in R^n
We know that winning lines only start at integral positions, and that the
value of a will only be needed when s_j is nonempty, so the start point S
of a winning line is in fact determined by:
+ vertex v in {0,n}^(d-i), padded by s
+ a in R^i, padded by the complement of s, s'
Having performed the following operations, the co-ordinates of the winning
lines are abs(S-k*s') for k in [0..n-1]
"""
vertices = listPairedVertices(d-i,n)
sequences = listSequences(d,i)
result = []
for s in sequences:
for v in vertices:
C = [0]*d
j = 0
for index in range(d):
if s[index]: C[index] = 0
else:
C[index] = v[j]
j+=1
result += [
[numpy.absolute(S-k*(numpy.absolute(s-1))) for k in range(n)]
for S in [C+a for a in listPaddedConstants(s,n)]
]
return result
def AllWinningLines (d,n):
"""
has the structure [[x_1,x_2,x_3],[y_1,y_2,y_3]] where each l_k is a
length-d co-ordinate
"""
result = []
for i in range(d):
result += listWinningVectorsForDimension(d,i,n)
return result
def movesAlreadyMade ():
"""
Returns a list of co-ordinates of moves already made read from STDIN
"""
parameters = raw_input()
moves = raw_input()
parameters = list(map(int,parameters.split(',')))
moves = [map(int,a.split(',')) for a in moves.split(';')] \
if moves != '' else []
return {'n':parameters[0], 'd':parameters[1], 'moves':moves}
def scoreLine (moves, line, scores, n):
"""
Gives each line a score based on whatever logic I choose
"""
myMoves = moves[0::2]
theirMoves = moves[1::2]
if len(moves)%2: myMoves, theirMoves = theirMoves, myMoves
lineHasMyMove = 0
lineHasTheirMove = 0
score = 0
for coord in line:
if coord.tolist() in myMoves:
lineHasMyMove += 1
if coord.tolist() in theirMoves: raise Exception('Move clash')
elif coord.tolist() in theirMoves: lineHasTheirMove += 1
if lineHasMyMove == len(line):
raise Exception('I have won')
elif lineHasTheirMove == len(line):
raise Exception('They have won')
elif lineHasMyMove and lineHasTheirMove:
pass
elif lineHasTheirMove == len(line)-1:
score = n**lineHasTheirMove
else:
score = n**lineHasMyMove
for coord in line:
if coord.tolist() not in moves:
scores[tuple(coord)]+=score
def main():
"""
Throw it all together
"""
data = movesAlreadyMade()
dimension = data['d']
length = data['n']
lines = AllWinningLines(dimension, length)
scores = numpy.zeros([length]*dimension, dtype=numpy.int)
try: [scoreLine(data['moves'], line, scores, length) for line in lines]
except Exception as E:
print 'ERROR: ' + E.args[0]
return
print ','.join(map(
str,numpy.unravel_index(numpy.argmax(scores),scores.shape)
))
if __name__ == "__main__": main()
편집 : I / O의 경우 논리가 추가되었습니다. 나는 이것이 마크를 할 준비가되었다고 믿는다
이 의견은 처음에는 내가 삭제하고 삭제를 취소 한 자리 표시 자였습니다.