I'm really proud of my solution to part 2. When I first read it, I was freaking stumped, I had no idea how to approach it. I was wondering if I was going to wind up resorting to brute forcing it in factorial time. But then I had an idea on the way home, and I one shotted it! (Got a few tests on the example but first try on the actual input)
from day3_p1 import get_input, get_banks, sample
def turn_on_batteries(bank: string, num_on: int):
bank_size = len(bank)
l = 0
r = bank_size - num_on + 1
on_bats = []
while r <= bank_size:
index_batt_list = list(enumerate(bank))
index, batt = max(index_batt_list[l:r], key=lambda x: x[1])
on_bats.append(batt)
old_l = l
l = index + 1
r += 1
return int("".join(on_bats))
actual = get_input("input")
if __name__ == "__main__":
all_banks = get_banks(actual, "\n")
res = 0
for bank in all_banks:
res += turn_on_batteries(bank, 12)
print(res)
Part 1 for completeness:
def get_input(path: str) -> str:
with open("input") as f:
data = f.read()
return data.strip()
def get_banks(data: str, sep=" ") -> list[str]:
return data.split(sep)
def find_max_battery(bank: str, heap_size=2) -> int:
batteries = list(enumerate([int(c) for c in bank]))
first_digit = max(batteries, key=lambda x: x[1])
if first_digit[0] == len(bank) - 1:
first_digit = max(batteries[:-1], key=lambda x: x[1])
second_digit = max(batteries[first_digit[0]+1:], key=lambda x: x[1])
return first_digit[1] * 10 + second_digit[1]
sample = "987654321111111 811111111111119 234234234234278 818181911112111"
actual = get_input("input")
DATA = actual
if __name__ == "__main__":
all_banks = get_banks(DATA, "\n")
res = 0
for bank in all_banks:
res += find_max_battery(bank)
print(res)