There are 40 distinct ways of letting the die to touch each cell only once and each way having 24 different possibilities to apply. ]]>

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# the six dice faces will be enumerated in the order # Left, Front, Up, Right, Back, Down (X = illegal) L, F, U, R, B, D, X = range(7) # sides that become L, F, U, R, B, D after rolling a die on a # lower left, right, forward and backward edge respectively rolls = ((U, F, R, D, B, L), (D, F, L, U, B, R), (L, U, B, R, D, F), (L, D, F, R, U, B)) # possible die moves for each or the nine grid cells - positions # in the three grid rows are (0, 1, 2), (3, 4, 5) and (6, 7, 8) moves = ( (R, F), (L, R, F), (L, F), (B, R, F), (B, L, R, F), (B, L, F), (B, R), (B, L, R), (B, L) ) # the distance moved in the grid array for moves L, F, R and B dis = (-1, 3, X, 1, -3, X) # and the die roll data involved rol = ( rolls[0], rolls[2], X, rolls[1], rolls[3], X) # roll a die onto the nine grid squares in turn def run(path, fp, d): # if we have finished, return the score for the sequence if len(path) == 9: yield fp else: # the current position of the die on the grid cp = path[-1] # for each of the possible moves from this position for m in moves[cp]: # find the next die position on the grid np = cp + dis[m] # if this has not yet been visited if np not in path: # roll the die to move to the new position, add the score # to the running total and proceed to the next move nd = tuple(d[i] for i in rol[m]) yield from run(path + [np], fp + nd[D], nd) # given two dice faces anti-clockwise at a vertex, find the third # face at this vertex (using a western die if 'same' is True) def die_third_face(first, second, same=True): if second in (first, 7 - first): raise ValueError t, f = min(first, 7 - first), min(second, 7 - second) c1 = ((f - t) % 3 == (1 if same else 2)) c2 = (first < 4) == (second < 4) return 6 - t - f if c1 == c2 else t + f + 1 # permute a die into its 24 spatial orientations # (e.g. any of the six faces on top and then any # of the four side faces at the front) def permute_die(): for left in range(1, 7): for front in set(range(1, 7)) - set((left, 7 - left)): up = die_third_face(left, front) yield (left, front, up, 7 - left, 7 - front, 7 - up) # a set to hold the scores scores = set() # for each essentially different grid starting position for pos in (0, 1, 4): # and for each starting die orientation for die in permute_die(): # generate all sequences and add their scores to our set scores |= set(fp for fp in run([pos], die[D], die)) # find the minimum and maximum possible scores min_s, max_s = min(scores), max(scores) # find any scores that are missing between these two values missing = set(range(min_s, max_s + 1)) - scores fs = 'Scores: minimum = {}, maximum = {}, impossible: {}.' print(fs.format(min_s, max_s, tuple(sorted(missing)))) |