Advent of Code 2022 day 20
Relatively straightforward, aside from using % (len(data) - 1). Part 2 wasn’t
a great deal more complicated.
Part 1
with open("20.txt") as f:
data = [
{"number": int(x), "pos": i}
for i, x in enumerate(f.read().splitlines())
]
def print_data(l):
print([(x["number"], x["pos"]) for x in l])
new_data = data.copy()
for i in range(len(data)):
x = data[i]
number = x["number"]
pos = x["pos"]
to = (pos+number) % (len(data) - 1)
if to == 0:
to = len(data) - 1
x["pos"] = to
if to < pos:
new_data = new_data[:to] + [x] + new_data[to:pos] + new_data[pos+1:]
for a in new_data[to+1:pos+1]:
a["pos"] += 1
elif to > pos:
new_data = (
new_data[:pos] + new_data[pos+1:to+1] + [x] + new_data[to+1:]
)
for a in new_data[pos:to]:
a["pos"] -= 1
else:
new_data = new_data
zero_at = min(i for i, x in enumerate(new_data) if x["number"] == 0)
print(
sum([
new_data[(1000+zero_at) % len(new_data)]["number"],
new_data[(2000+zero_at) % len(new_data)]["number"],
new_data[(3000+zero_at) % len(new_data)]["number"],
])
)
Part 2
with open("20.txt") as f:
data = [
{"number": int(x)*811589153, "pos": i}
for i, x in enumerate(f.read().splitlines())
]
def print_data(l):
print([(x["number"], x["pos"]) for x in l])
new_data = data.copy()
for _ in range(10):
for i in range(len(data)):
x = data[i]
number = x["number"]
pos = x["pos"]
to = (pos+number) % (len(data) - 1)
if to == 0:
to = len(data) - 1
x["pos"] = to
if to < pos:
new_data = new_data[:to] + [x] + new_data[to:pos] + new_data[pos+1:]
for a in new_data[to+1:pos+1]:
a["pos"] += 1
elif to > pos:
new_data = (
new_data[:pos] + new_data[pos+1:to+1] + [x] + new_data[to+1:]
)
for a in new_data[pos:to]:
a["pos"] -= 1
else:
new_data = new_data
zero_at = min(i for i, x in enumerate(new_data) if x["number"] == 0)
print(
sum([
new_data[(1000+zero_at) % len(new_data)]["number"],
new_data[(2000+zero_at) % len(new_data)]["number"],
new_data[(3000+zero_at) % len(new_data)]["number"],
])
)