#!/usr/bin/env python3 # Mainly used for problem development # Run as full.py --full to generate 10 different instances that aren't impossible # and that kill the greedy solution # Add --q to generate instance that kill solutions who ignore that Q is weird import random import sys letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' def before(a, b): if a == "Q": return b >= "U" return a <= b def ignore_q(a, b): return a <= b def solve(lines, comparator=before): front = lines[0] sides: list[set[str]] = [set() for _ in range(16)] for line in lines[1:5]: for i, l in enumerate(line): sides[i].add(l) back = lines[-1] # best[c] = smallest number or rotations to sort the # current prefix such that it ends in c. If this is impossible, None. best = [ (0, front[0]), (2, back[0]) ] + [(1, letter) for letter in sides[0] if letter != front[0]] for i in range(1, 16): new_best = [] for letter, delta in [(front[i], 0)] + [(side, 1) for side in sides[i]] + [(back[i], 2)]: for turns, prefix in best: if comparator(prefix[-1], letter): new_best.append((turns + delta, prefix + letter)) best = new_best if best: return(min(best)) else: return('impossible') def greedy(lines): prefix = '@' # '@' < 'A' turns = 0 for i in range(16): vals = [(0, lines[0][i])] + [(2, lines[5][i])] + [(1, lines[j][i]) for j in [1,2,3,4]] filtered_vals = list(t[::-1] for t in vals if t[1] >= prefix[-1]) if not filtered_vals: return 'impossible' c, t = min(filtered_vals) prefix += c turns += t return turns, prefix dice = [list(faces) for faces in ( "AACIOT", "ABILTY", "ABJMOQ", "ACDEMP", "ACELRS", "ADENVZ", "AHMORS", "BIFORX", "DENOSW", "DKNOTU", "EEFHIY", "EGKLUY", "EGINTV", "EHINPS", "ELPSTU", "GILRUW", ) ] if '--full' in sys.argv: random.seed(0) for i in range(10): while True: random.shuffle(dice) for i in range(16): random.shuffle(dice[i]) lines = [] for i in range(6): lines.append(''.join(dice[j][i] for j in range(16))) res = solve(lines) res_ignore = solve(lines, ignore_q) greedy_res = greedy(lines) if res != 'impossible' and greedy_res[0] != res[0] and res[0] != res_ignore[0]: if 'Q' in res[1] or '--q' not in sys.argv: break print(*lines, sep='\n') print(res) print(res_ignore) print(greedy(lines)) else: res = solve([input() for _ in range(6)]) if isinstance(res, str): print(res) else: print(res[0])