Advent of Code 2025 in Charly
Day 3
This article is part of my series on implementing each Advent of Code 2025 challenge in my own programming language Charly.
Today’s task was determining which batteries to turn on to reach the
highest possible joltage. Batteries were grouped together
into a bank.
For example: 987654321111111 is a battery bank that
consists of 15 batteries, each with a lower
joltage rating than the one before it. The total output
joltage of a bank is equal to the number formed by the
joltage ratings of each battery that is turned on.
For example, if you have a bank like 12345 and you turn
on battery 2 and 4, you get a total of
24 jolts.
Part 1 of the puzzle required finding the largest possible
joltage achievable by turning on exactly two batteries.
Part 2 modified the task by instead requiring 12 batteries
to be turned on.
I solved the task by determining which battery, when turned on, would
result in the largest possible joltage for the entire bank,
and then repeating this as many times as required.
Interestingly, parallelizing the computation via the
List::parallelMap method I added yesterday actually
resulted in a noticeable speedup of around 4x. 😁
#!/usr/local/bin/charly
if ARGV.length < 2 {
print("Missing filepath")
exit(1)
}
const input_path = ARGV[1]
const input = readfile(input_path)
const amountOfBatteriesToTurnOn = 12
func applyActivationRecord(bank, record) {
assert bank.length == record.length
const activatedBatteries = bank.filter(->(e, i) record[i])
const finalNumber = activatedBatteries.join("").to_number()
return finalNumber
}
const banks = input
.split("\n")
.map(->(bank) {
bank.split("").map(->(battery) battery.to_number())
})
.parallelMap(->(bank) {
const activationRecord = List.create(bank.length, false)
amountOfBatteriesToTurnOn.times(->{
const potentialFlips = activationRecord.mapNotNull(->(s, i) {
if s return null
const newRecord = activationRecord.copy()
newRecord[i] = true
const newNumber = applyActivationRecord(bank, newRecord)
return (newNumber, i)
})
const (newNumber, flipIndex) = potentialFlips.findMaxBy(->(e) e[0])
activationRecord[flipIndex] = true
})
applyActivationRecord(bank, activationRecord)
})
const finalJoltage = banks.sum()
print(finalJoltage)Changes to the stdlib / VM
No changes to the VM itself had to be made, but I did add a good amount of new functionality to the standard library.
9fd4ac3Add Number::max and Number::min165d6fdAdd default callback for Int::collectUpToc486987Add List::mapNotNulle464b51Add List::sublist9dfd78eAdd List::sumc8acbf5Add List::join7de6f7eAdd List::findMax and List::findMaxBy
Links
Copyright © 2024 - 2025 Leonard Schütz | Attributions This post was written by a human and reviewed and proof-read by LLMs