Spoiler alert

This is a full solution for Advent of Code 2025, day 3 puzzles with explanations.

If you want to try to solve it yourself first, head over to https://adventofcode.com/2025/day/3 and give it a go and then come back and compare notes.

You can find the full code at https://github.com/Hamatti/adventofcode-2025/blob/main/src/day_3.py

Elevators are out of power in the North Pole and that’s stopping us from descending into the depths of Santa’s realm.

Read input

This time, we’re provided information on available battery banks:

987654321111111
811111111111119
234234234234278
818181911112111

Each line in the input is a battery bank and each digit represents a single battery and its joltage rating.

from typing import List
 
type BatteryBank = List[int]
 
def mapper(line: str) -> BatteryBank:
    """Turn string of digits into a list of integers"""
    return [int(num) for num in line]

Since we need to be calculating with those digits, let’s turn each line into a list of integers. Here I’m using a type alias to tell that we’re dealing with BatteryBanks that are actually lists of integers in a trenchcoat.

When dealing with types, I like to use aliases that tell the reader of the code (the computer doesn’t care about them really) what they represent.

Part 1

In the first part of the task, we need to find out which two batteries we need to turn on to get the maximum joltage out of a battery bank. The joltage of a battery bank is calculated as the first battery banks value concatenated to the second.

So if we turn batteries with joltage values of 9 and 4, we get 94 jolts.

def calculate_max_joltage(bank: BatteryBank) -> int:
    """Calculates the highest possible joltage
    of a battery bank when exactly 2 batteries
    are turned on.
 
    A joltage is the combined value of the joltages
    of those batteries.
 
    For example, turning on batteries with joltages
    of 9 and 4 gives total joltage of 94.
    """
    first = max(bank[:-1])
    first_index = bank.index(first)
    second = max(bank[first_index+1:])
    return int(f'{first}{second}')

To find the first value, we take a look at everything but the last number (because we eventually need to have two of them). To exclude the last number, we use negative index slicing:

bank = [1,2,3,4]
bank[:-1] # [1, 2, 3]
bank[:-2] # [1, 2]
bank[:-3] # [1]

and then use max function that takes an iterable and finds the largest value in it.

To get the second joltage, we find the first value’s location in the list with index function and only look at the values from there onwards (+1 added so we don’t include the max value itself).

Finally, we turn those two integers into a two-digit string and convert that back to an integer.

Part 2

In the second part, we need more juice so instead of turning on two batteries, we turn on 12.

The main idea is the same: we look at the available pool of batteries (while leaving enough out from the end to make sure we’ll always end up with 12) and find the largest there.

Let me illustrate this a bit. Let’s say we are looking for 4 instead of 12 to make it easier to see:

our bank: 2 3 4 2 3 4 2 3 4 2 3 4 2 7 8

For the first one, we need to make sure we leave the last 3 out so we don’t drive ourselves to a corner where we need 3 more batteries and only have two left

2 3 4 2 3 4 2 3 4 2 3 4 | 2 7 8

Now, we find the first largest number in the portion left to our divider (|) which is 4.

2 3 [4] 2 3 4 2 3 4 2 3 4 | 2 7 8

We then ignore everything up and including that value in our next iteration and this time we leave out the last two:

2 3 [4] 2 3 4 2 3 4 2 | 7 8

and so on

2 3 4 2 3 4 2 [7] | 8

until we finally have one spot to fill and we look at all the remaining batteries and choose the largest

[8]

In code, with 12 batteries, it looks like this

def calculate_12_joltage(bank: BatteryBank) -> int:
    """Calculates the highest possible joltage
    of a battery bank when exactly 12 batteries
    are turned on.
 
    A joltage is the combined value of the joltages
    of those batteries.
 
    For example, turning on batteries with joltages
    of 9 and 4 gives total joltage of 94.
    """
    joltage = ''
    for i in range(11, 0, -1):
        next_largest_battery = max(bank[:-i])
        next_index = bank.index(next_largest_battery)
        bank = bank[next_index+1:]
        joltage += str(next_largest_battery)
 
    # And one more for good measure
    joltage += str(max(bank))
 
    return int(joltage)

We start by finding the first 11 batteries in a for loop. On each iteration, we do what we did in the first part: find the largest available ([:-i] makes sure there’s always enough at the end of the pool for the rest) battery and this time I keep discarding the early parts of the battery bank so our index function finds the correct battery.

list.index(value) will always find the first index for a given value.

Once we have found the first 11, we then add one more: the largest of the remaining items.

And that gives us our two ⭐️s of day 3. This was a really fun puzzle!

Get in touch

If you want to comment on these solutions, I share them in Mastodon where you can look for the post for the right date or you can start a discussion over email with juhamattisantala@gmail.com.

Follow via RSS

I have created a custom RSS feed for these solutions so you can follow along and not miss any of them!