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) }