package main import ( "cmp" "flag" "fmt" "log" "math" "os" ) func main() { debug := flag.Bool("debug", false, "Debug.") flag.Parse() f := os.Stdin if flag.NArg() > 0 { var err error f, err = os.Open(flag.Arg(0)) if err != nil { log.Fatal(err) } defer f.Close() } banks, err := readBatteries(f) if err != nil { log.Fatal(err) } var sum1, sum2 uint for _, bank := range banks { power1 := bestPowerPart1(bank) power2 := bestPowerPart2(bank) if *debug { for _, b := range bank { fmt.Print(b) } fmt.Println(":", power1, power2) } sum1 += power1 sum2 += power2 } fmt.Println("sum (part 1):", sum1) fmt.Println("sum (part 2):", sum2) } func bestPowerPart1(bank []uint8) uint { // i := maxIndex(bank[:len(bank)-1]) // j := maxIndex(bank[i+1:]) + i + 1 // return uint(bank[i])*10 + uint(bank[j]) return bestPower(bank, 2) } func bestPowerPart2(bank []uint8) uint { return bestPower(bank, 12) } func bestPower(bank []uint8, batteries int) uint { if len(bank) < batteries { panic(fmt.Sprintf("bank (%d) is smaller than requested batteries (%d)", len(bank), batteries)) } var joltage uint var i int for j := batteries - 1; j >= 0; j-- { k := maxIndex(bank[i : len(bank)-j]) k += i i = k + 1 joltage += uint(bank[k]) * uint(math.Pow10(j)) } return joltage } func maxIndex[S ~[]E, E cmp.Ordered](x S) int { if len(x) < 1 { panic("maxIndex: empty list") } i := 0 for j := 1; j < len(x); j++ { if x[j] > x[i] { i = j } } return i }