Non-transitive dice: Difference between revisions

→‎{{header|Python}}: some cleanup; one bug fix to prevent sub loops in longer sequences that's not possible in examples required by task
(→‎{{header|Python}}: supersede with faster solution)
(→‎{{header|Python}}: some cleanup; one bug fix to prevent sub loops in longer sequences that's not possible in examples required by task)
Line 1,928:
 
=={{header|Python}}==
Trivial rotations of the same loop are not shown. It should not be difficult to mentally picture them.
<lang python>from itertools import combinations_with_replacement as cmbr
from time import time
 
def dice_gen(n, faces, m):
dice = list(cmbr(faces, n))
 
succ = [set(j for j, b in enumerate(dice)
if j != i and sum((x>y) - (x<y) for x in a for y in b) > 0)
for i, a in enumerate(dice)]
def loops(seq):
s = yield succ[seq[-1]]
 
def loops if len(seq,) s,== depth)m:
if notseq[0] depthin s: yield seq
if seq[0] in s:return
yield seq
else:
for d in (x for x in s if x > seq[0]):
yield from loops(seq + (d,), succ[d], depth - 1)
 
for d in (x for x in s if x > seq[0] and not x in seq):
yield from loops(seq + (d,), succ[d], depth - 1)
yield from (tuple(''.join(dice[s]) for s in x)
for i, v in enumerate(succ)
for x in loops((i,), v, m - 1))
 
t = time()
for n, faces, loop_len in [(4, '1234', 3), (4, '1234', 4), (6, '123456', 3), (6, '1234567', 3)]:
for i, x in enumerate(dice_gen(n, faces, loop_len)): pass
 
print(f'{n}-sided, markings {faces}, loop length {loop_len}:')
print(f'\t{i + 1}*{loop_len} solutions, e.g. {" > ".join(x)} > [loop]')