aoc2025/day3/main.go
2025-12-06 11:29:00 -05:00

147 lines
2.5 KiB
Go

package main
import (
"fmt"
"os"
"strings"
)
func readLines(filename string) []string {
raw, err := os.ReadFile(filename)
if err != nil {
panic(err)
}
return strings.Split(string(raw), "\n")
}
type bank struct {
batteries []uint8
}
func parseLine(line string) (bank, error) {
b := bank{
batteries: make([]uint8, len(line)),
}
for i, c := range line {
var battery uint8
switch c {
case '1':
battery = 1
case '2':
battery = 2
case '3':
battery = 3
case '4':
battery = 4
case '5':
battery = 5
case '6':
battery = 6
case '7':
battery = 7
case '8':
battery = 8
case '9':
battery = 9
default:
return b, fmt.Errorf("Invalid battery")
}
b.batteries[i] = battery
}
return b, nil
}
func (b bank) findLargestJoltage() uint8 {
if len(b.batteries) < 2 {
return 0
}
var first, second uint8
for _, battery := range b.batteries {
if first == 0 {
first = battery
continue
}
if second == 0 {
second = battery
continue
}
if second > first {
first = second
second = battery
continue
}
if battery > second {
second = battery
continue
}
}
return first*10 + second
}
// Functionally, append the candidate to the batteries, then
// remove the first battery preceding an increase in values.
func addBatteryToMax(batteries []uint8, candidate uint8) {
n := uint8(len(batteries))
if n == 0 {
return
}
last := batteries[0]
for i := uint8(1); i < n; i++ {
current := batteries[i]
if current > last {
// i-1 = current
// i:n-2 <- i+1:n-1
// n-1 = candidate
batteries[i-1] = current
for j := i; j <= n-2; j++ {
batteries[j] = batteries[j+1]
}
batteries[n-1] = candidate
return
}
last = current
}
if candidate > batteries[n-1] {
batteries[n-1] = candidate
}
}
func (b bank) findMaximumJoltage(n uint8) uint64 {
if len(b.batteries) < int(n) || n == 0 {
return 0
}
max := make([]uint8, n)
for i := range n {
max[i] = b.batteries[i]
}
for i := n; i < uint8(len(b.batteries)); i++ {
addBatteryToMax(max, b.batteries[i])
}
joltage := uint64(0)
for _, battery := range max {
joltage = joltage*10 + uint64(battery)
}
return joltage
}
func main() {
filename := "input0.txt"
if len(os.Args) > 1 {
filename = os.Args[1]
}
lines := readLines(filename)
var total uint
var max uint64
for _, line := range lines {
bank, err := parseLine(line)
if err != nil {
panic(err)
}
total += uint(bank.findLargestJoltage())
max += bank.findMaximumJoltage(12)
}
fmt.Printf("%v\n", total)
fmt.Printf("%v\n", max)
}