69 lines
1.6 KiB
Python
69 lines
1.6 KiB
Python
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
|