diff --git a/python/e336.py b/python/e336.py new file mode 100644 index 0000000..d13cd5e --- /dev/null +++ b/python/e336.py @@ -0,0 +1,67 @@ +from itertools import permutations +from string import ascii_uppercase +from functools import cache + + +@cache +def count(xst: tuple) -> int: + expected = 0 + for i in range(len(xst)): + if xst[i] == expected: + expected += 1 + else: + # Carriage i is not the correct one + break + else: + # Train is fully sorted + return 0 + + # Find out where Simple Simon would split next; there are two cases. + xs = list(xst) + + # If the next expected carriage is at the end of the list, Simon can just + # reverse from where we currently are. + if xs[-1] == expected: + xs[i:] = xs[i:][::-1] + return 1 + count(tuple(xs)) + + for j in range(i + 1, len(xst)): + if xst[j] == expected: + xs[j:] = xs[j:][::-1] + return 1 + count(tuple(xs)) + + assert False, "should not get here" + + +def get_maximix_arrangements(n: int) -> list: + x = [i for i in range(n)] + xs = permutations(x) + max_xs = [] + max_xs_count = 0 + for x in xs: + if x[0] == 0 or x[-1] == 0: + continue + c = count(x) + if c == max_xs_count: + max_xs.append(x) + elif c > max_xs_count: + max_xs = [x] + max_xs_count = c + return sorted(map(to_ascii, max_xs)) + + +def to_ascii(x) -> str: + return "".join([ascii_uppercase[d] for d in x]) + + +def euler_336(): + xs = get_maximix_arrangements(6) + assert len(xs) == 24 + assert xs[10 - 1] == "DFAECB" + return get_maximix_arrangements(11)[2011 - 1] + + +if __name__ == "__main__": + solution = euler_336() + print(f"e336.py: {solution}") + assert solution == "CAGBIHEFJDK"