147 lines
2.5 KiB
Go
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)
|
|
}
|