|
Packit Service |
99d393 |
# The Computer Language Benchmarks Game
|
|
Packit Service |
99d393 |
# http://shootout.alioth.debian.org/
|
|
Packit Service |
99d393 |
#
|
|
Packit Service |
99d393 |
# contributed by Daniel Nanz, 2008-08-21
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
import optparse
|
|
Packit Service |
99d393 |
import time
|
|
Packit Service |
99d393 |
from bisect import bisect
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
import util
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
w, h = 5, 10
|
|
Packit Service |
99d393 |
dir_no = 6
|
|
Packit Service |
99d393 |
S, E = w * h, 2
|
|
Packit Service |
99d393 |
SE = S + (E / 2)
|
|
Packit Service |
99d393 |
SW = SE - E
|
|
Packit Service |
99d393 |
W, NW, NE = -E, -SE, -SW
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
def rotate(ido, rd={E: NE, NE: NW, NW: W, W: SW, SW: SE, SE: E}):
|
|
Packit Service |
99d393 |
return [rd[o] for o in ido]
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
def flip(ido, fd={E: E, NE: SE, NW: SW, W: W, SW: NW, SE: NE}):
|
|
Packit Service |
99d393 |
return [fd[o] for o in ido]
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
def permute(ido, r_ido):
|
|
Packit Service |
99d393 |
ps = [ido]
|
|
Packit Service |
99d393 |
for r in range(dir_no - 1):
|
|
Packit Service |
99d393 |
ps.append(rotate(ps[-1]))
|
|
Packit Service |
99d393 |
if ido == r_ido: # C2-symmetry
|
|
Packit Service |
99d393 |
ps = ps[0:dir_no//2]
|
|
Packit Service |
99d393 |
for pp in ps[:]:
|
|
Packit Service |
99d393 |
ps.append(flip(pp))
|
|
Packit Service |
99d393 |
return ps
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
def convert(ido):
|
|
Packit Service |
99d393 |
'''incremental direction offsets -> "coordinate offsets" '''
|
|
Packit Service |
99d393 |
out = [0]
|
|
Packit Service |
99d393 |
for o in ido:
|
|
Packit Service |
99d393 |
out.append(out[-1] + o)
|
|
Packit Service |
99d393 |
return list(set(out))
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
def get_footprints(board, cti, pieces):
|
|
Packit Service |
99d393 |
fps = [[[] for p in range(len(pieces))] for ci in range(len(board))]
|
|
Packit Service |
99d393 |
for c in board:
|
|
Packit Service |
99d393 |
for pi, p in enumerate(pieces):
|
|
Packit Service |
99d393 |
for pp in p:
|
|
Packit Service |
99d393 |
fp = frozenset([cti[c + o] for o in pp if (c + o) in cti])
|
|
Packit Service |
99d393 |
if len(fp) == 5:
|
|
Packit Service |
99d393 |
fps[min(fp)][pi].append(fp)
|
|
Packit Service |
99d393 |
return fps
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
def get_senh(board, cti):
|
|
Packit Service |
99d393 |
'''-> south-east neighborhood'''
|
|
Packit Service |
99d393 |
se_nh = []
|
|
Packit Service |
99d393 |
nh = [E, SW, SE]
|
|
Packit Service |
99d393 |
for c in board:
|
|
Packit Service |
99d393 |
se_nh.append(frozenset([cti[c + o] for o in nh if (c + o) in cti]))
|
|
Packit Service |
99d393 |
return se_nh
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
def get_puzzle(w=w, h=h):
|
|
Packit Service |
99d393 |
board = [E*x + S*y + (y%2) for y in range(h) for x in range(w)]
|
|
Packit Service |
99d393 |
cti = dict((board[i], i) for i in range(len(board)))
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
idos = [[E, E, E, SE], # incremental direction offsets
|
|
Packit Service |
99d393 |
[SE, SW, W, SW],
|
|
Packit Service |
99d393 |
[W, W, SW, SE],
|
|
Packit Service |
99d393 |
[E, E, SW, SE],
|
|
Packit Service |
99d393 |
[NW, W, NW, SE, SW],
|
|
Packit Service |
99d393 |
[E, E, NE, W],
|
|
Packit Service |
99d393 |
[NW, NE, NE, W],
|
|
Packit Service |
99d393 |
[NE, SE, E, NE],
|
|
Packit Service |
99d393 |
[SE, SE, E, SE],
|
|
Packit Service |
99d393 |
[E, NW, NW, NW]]
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
perms = (permute(p, idos[3]) for p in idos) # restrict piece 4
|
|
Packit Service |
99d393 |
pieces = [[convert(pp) for pp in p] for p in perms]
|
|
Packit Service |
99d393 |
return (board, cti, pieces)
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
def print_board(board, w=w, h=h):
|
|
Packit Service |
99d393 |
for y in range(h):
|
|
Packit Service |
99d393 |
for x in range(w):
|
|
Packit Service |
99d393 |
print(board[x + y * w])
|
|
Packit Service |
99d393 |
print('')
|
|
Packit Service |
99d393 |
if y % 2 == 0:
|
|
Packit Service |
99d393 |
print('')
|
|
Packit Service |
99d393 |
print()
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
board, cti, pieces = get_puzzle()
|
|
Packit Service |
99d393 |
fps = get_footprints(board, cti, pieces)
|
|
Packit Service |
99d393 |
se_nh = get_senh(board, cti)
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
def solve(n, i_min, free, curr_board, pieces_left, solutions,
|
|
Packit Service |
99d393 |
fps=fps, se_nh=se_nh, bisect=bisect):
|
|
Packit Service |
99d393 |
fp_i_cands = fps[i_min]
|
|
Packit Service |
99d393 |
for p in pieces_left:
|
|
Packit Service |
99d393 |
fp_cands = fp_i_cands[p]
|
|
Packit Service |
99d393 |
for fp in fp_cands:
|
|
Packit Service |
99d393 |
if fp <= free:
|
|
Packit Service |
99d393 |
n_curr_board = curr_board[:]
|
|
Packit Service |
99d393 |
for ci in fp:
|
|
Packit Service |
99d393 |
n_curr_board[ci] = p
|
|
Packit Service |
99d393 |
if len(pieces_left) > 1:
|
|
Packit Service |
99d393 |
n_free = free - fp
|
|
Packit Service |
99d393 |
n_i_min = min(n_free)
|
|
Packit Service |
99d393 |
if len(n_free & se_nh[n_i_min]) > 0:
|
|
Packit Service |
99d393 |
n_pieces_left = pieces_left[:]
|
|
Packit Service |
99d393 |
n_pieces_left.remove(p)
|
|
Packit Service |
99d393 |
solve(n, n_i_min, n_free, n_curr_board,
|
|
Packit Service |
99d393 |
n_pieces_left, solutions)
|
|
Packit Service |
99d393 |
else:
|
|
Packit Service |
99d393 |
s = ''.join(map(str, n_curr_board))
|
|
Packit Service |
99d393 |
solutions.insert(bisect(solutions, s), s)
|
|
Packit Service |
99d393 |
rs = s[::-1]
|
|
Packit Service |
99d393 |
solutions.insert(bisect(solutions, rs), rs)
|
|
Packit Service |
99d393 |
if len(solutions) >= n:
|
|
Packit Service |
99d393 |
return
|
|
Packit Service |
99d393 |
if len(solutions) >= n:
|
|
Packit Service |
99d393 |
return
|
|
Packit Service |
99d393 |
return
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
SOLVE_ARG = 60
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
def main(n):
|
|
Packit Service |
99d393 |
times = []
|
|
Packit Service |
99d393 |
for i in range(n):
|
|
Packit Service |
99d393 |
t0 = time.time()
|
|
Packit Service |
99d393 |
free = frozenset(range(len(board)))
|
|
Packit Service |
99d393 |
curr_board = [-1] * len(board)
|
|
Packit Service |
99d393 |
pieces_left = list(range(len(pieces)))
|
|
Packit Service |
99d393 |
solutions = []
|
|
Packit Service |
99d393 |
solve(SOLVE_ARG, 0, free, curr_board, pieces_left, solutions)
|
|
Packit Service |
99d393 |
#print len(solutions), 'solutions found\n'
|
|
Packit Service |
99d393 |
#for i in (0, -1): print_board(solutions[i])
|
|
Packit Service |
99d393 |
tk = time.time()
|
|
Packit Service |
99d393 |
times.append(tk - t0)
|
|
Packit Service |
99d393 |
return times
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
if __name__ == "__main__":
|
|
Packit Service |
99d393 |
parser = optparse.OptionParser(
|
|
Packit Service |
99d393 |
usage="%prog [options]",
|
|
Packit Service |
99d393 |
description="Test the performance of the Float benchmark")
|
|
Packit Service |
99d393 |
util.add_standard_options_to(parser)
|
|
Packit Service |
99d393 |
options, args = parser.parse_args()
|
|
Packit Service |
99d393 |
|
|
Packit Service |
99d393 |
util.run_benchmark(options, options.num_runs, main)
|
|
Packit Service |
99d393 |
|