def is_valid(circle, seen, n): if len(circle) < n: return True end = tuple(circle[-n:]) if end in seen: return False seen.add(end) return True def overlap_valid(circle, seen, n): for i in range(1, n): end = tuple(circle[-i:] + circle[: n - i]) if end in seen: return False seen.add(end) return True def align(circle, n): needle = [0 for _ in range(n)] for i in range(len(circle) - n): if circle[i : i + n] == needle: return circle[i:] + circle[:i] return [] def s(n): length = 2**n circles = [[[], set()]] for i in range(length): new_circles = [] for circle, seen in circles: for d in [0, 1]: new_circle = circle + [d] new_seen = seen.copy() if is_valid(new_circle, new_seen, n): new_circles.append([new_circle, new_seen]) circles = new_circles valid_circles = [] valid_seen = set() for circle, seen in circles: if overlap_valid(circle, seen, n): aligned = align(circle, n) aligned_tuple = tuple(aligned) if aligned and aligned_tuple not in valid_seen: valid_circles.append(aligned) valid_seen.add(aligned_tuple) t = 0 for circle in valid_circles: s = int("".join(map(str, circle)), 2) print(circle, s) t += s return t def euler_265(): assert s(3) == 52 return s(5) if __name__ == "__main__": solution = euler_265() print(f"e265.py: {solution}") assert solution == 209110240768