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"], ]) )