Python 3 , (0,397 n + 3,58) etapas
Regressão polinomial de 1000 pontos por numpy.polyfit
.
- Número de etapas para a versão 1: 0.0546 n² + 2.80 n - 221
- Número de etapas para a versão 2: 0.0235 n² + 0.965 n - 74
- Número de etapas para a versão 3: 0.00965 n² + 2,35 n - 111
- Número de etapas para a versão 4: 1.08 n - 36.3
- Número de etapas para a versão 5: 0.397 n + 3.58
- Pontuação secreta do caso de teste para a versão 1: 14468
- Pontuação secreta do caso de teste para a versão 2: 5349
- Pontuação secreta do caso de teste para a versão 3: 4143
- Pontuação secreta do caso de teste para a versão 4: 450
- Pontuação secreta do caso de teste para a versão 5: 205
def partite(L):
endgame5 = [9,9,1,9,0,0,1,9,
0,1,0,1,0,1,1,9,
0,0,1,0,0,0,1,0,
0,0,0,1,0,0,0,9]
endgame6 = [9,9,2,9,1,1,2,9,0,2,0,0,1,2,2,9,
0,1,2,1,0,1,2,1,0,1,0,2,1,1,0,9,
0,0,1,0,1,0,1,1,0,0,0,0,1,1,1,1,
0,0,2,2,0,0,2,2,0,0,0,0,0,0,0,9]
endgame = [9,9,3,9,2,2,3,9,1,0,3,0,2,0,3,9,0,1,3,3,2,2,3,0,1,0,1,0,2,1,0,9,
0,0,2,1,0,0,2,2,1,0,1,2,0,0,0,2,0,1,3,3,3,3,3,0,1,1,1,1,1,3,0,9,
0,0,0,0,1,0,1,1,1,0,3,0,1,0,1,0,0,1,0,0,1,1,0,0,1,0,0,0,2,0,1,0,
0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,3,0,3,0,3,0,3,0,2,3,3,0,0,9]
offset = 1
steps = []
def update(L,steps,ind):
steps.append(offset + ind)
if 0 <= ind and ind+3 < len(L):
return (steps,L[:ind]+L[ind+3:]+L[ind:ind+3])
else:
print(offset,ind,L)
raise
if len(L) == 5:
while endgame5[L[0]*16+L[1]*8+L[2]*4+L[3]*2+L[4]] != 9:
steps, L = update(L,steps,endgame5[L[0]*16+L[1]*8+L[2]*4+L[3]*2+L[4]])
return steps
if len(L) == 6:
while endgame6[L[0]*32+L[1]*16+L[2]*8+L[3]*4+L[4]*2+L[5]] != 9:
steps, L = update(L,steps,endgame6[L[0]*32+L[1]*16+L[2]*8+L[3]*4+L[4]*2+L[5]])
return steps
if 1 not in L:
return []
while len(L) > 7 and 0 in L:
wf_check = len(L)
while L[0] != 0:
pos = [-1]
wf_check2 = -1
while True:
i = pos[-1]+1
while i < len(L):
if L[i] == 0:
pos.append(i)
i += 1
else:
i += 3
assert len(pos) > wf_check2
wf_check2 = len(pos)
space = (pos[-1]-len(L)+1)%3
ind = -1
tail = pos.pop()
i = len(L)-1
while i >= 0:
if tail == i:
while tail == i:
i -= 1
tail = pos.pop() if pos else -1
i -= 2
elif i < len(L)-3 and L[i+space] == 0:
ind = i
break
else:
i -= 1
if ind == -1:
break
steps, L = update(L, steps, ind)
pos = pos or [-1]
if L[0] == 0:
break
pos = [-1]
while L[0] != 0:
pos = [-1]
found = False
for i in range(1,len(L)):
if L[i] == 0:
if i%3 == (pos[-1]+1)%3:
pos.append(i)
else:
found = found or i
if found > len(L)-4:
found = False
if not found:
break
triple = []
for i in range(1,len(L)-1):
if L[i-1] == 1 and L[i] == 1 and L[i+1] == 1:
triple.append(i)
if len(triple) > 3:
break
space = (pos[-1]-len(L)+1)%3
if space == 0:
if found >= 2 and found-2 not in pos and found-1 not in pos:
# ... _ 1 _ [0] 0 ...
if found-2 in triple:
triple.remove(found-2)
if found-3 in triple:
triple.remove(found-3)
if L[-1] == 1:
steps, L = update(L, steps, found-2)
steps, L = update(L, steps, len(L)-4)
steps, L = update(L, steps, len(L)-4)
elif triple:
steps, L = update(L, steps, found-2)
if found < triple[0]:
triple[0] -= 3
steps, L = update(L, steps, triple[0]-1)
steps, L = update(L, steps, len(L)-4)
else:
break
assert L[-3] == 0
elif found >= 1 and found-1 not in pos and found+1 not in pos:
# ... _ 1 [0] _ 0 ...
if found-2 in triple:
triple.remove(found-2)
if L[-2] == 1 and L[-1] == 1:
steps, L = update(L, steps, found-1)
steps, L = update(L, steps, len(L)-5)
steps, L = update(L, steps, len(L)-5)
elif triple:
steps, L = update(L, steps, found-1)
if found < triple[0]:
triple[0] -= 3
steps, L = update(L, steps, triple[0]-1)
steps, L = update(L, steps, len(L)-5)
elif L[-1] == 1:
steps, L = update(L, steps, found-1)
steps, L = update(L, steps, len(L)-4)
steps, L = update(L, steps, len(L)-4)
steps, L = update(L, steps, len(L)-4)
else:
break
assert L[-3] == 0
else:
break
elif space == 1:
# ... 1 1 [0] 0 ...
if found >= 2 and found-2 not in pos and found-1 not in pos:
if found-2 in triple:
triple.remove(found-2)
if found-3 in triple:
triple.remove(found-3)
if triple:
steps, L = update(L, steps, found-2)
if found < triple[0]:
triple[0] -= 3
steps, L = update(L, steps, triple[0]-1)
steps, L = update(L, steps, len(L)-5)
elif L[-2] == 1 and L[-1] == 1:
steps, L = update(L, steps, found-2)
steps, L = update(L, steps, len(L)-4)
steps, L = update(L, steps, len(L)-5)
else:
break
assert L[-2] == 0
else:
break
else:
if found+1 not in pos and found+2 not in pos:
# ... 0 [0] _ 1 _ ...
if found+2 in triple:
triple.remove(found+2)
if found+3 in triple:
triple.remove(found+3)
if L[-2] == 1 and L[-1] == 1:
steps, L = update(L, steps, found)
steps, L = update(L, steps, len(L)-5)
elif L[-1] == 1:
steps, L = update(L, steps, found)
steps, L = update(L, steps, len(L)-4)
steps, L = update(L, steps, len(L)-4)
elif triple:
steps, L = update(L, steps, triple[0]-1)
if triple[0] < found:
found -= 3
steps, L = update(L, steps, found)
steps, L = update(L, steps, len(L)-5)
else:
break
assert L[-1] == 0
elif found >= 1 and found-1 not in pos and found+1 not in pos:
# ... 0 _ [0] 1 _ ...
if found+2 in triple:
triple.remove(found+2)
if L[-1] == 1:
steps, L = update(L, steps, found-1)
steps, L = update(L, steps, len(L)-4)
elif triple:
steps, L = update(L, steps, triple[0]-1)
if triple[0] < found:
found -= 3
steps, L = update(L, steps, found-1)
steps, L = update(L, steps, len(L)-4)
else:
break
assert L[-1] == 0
else:
break
if L[0] == 0:
break
if 0 in L[::3]:
assert L[::3].index(0) < wf_check
wf_check = L[::3].index(0)
steps, L = update(L, steps, 0)
assert L[0] == 0
offset += L.index(1)
del L[:L.index(1)]
continue
if 0 in L:
offset -= 7-len(L)
L = [0]*(7-len(L))+L
assert(len(L) == 7)
while endgame[L[0]*64+L[1]*32+L[2]*16+L[3]*8+L[4]*4+L[5]*2+L[6]] != 9:
steps, L = update(L,steps,endgame[L[0]*64+L[1]*32+L[2]*16+L[3]*8+L[4]*4+L[5]*2+L[6]])
return steps
Experimente online!