day3
This commit is contained in:
parent
c5ab5e785a
commit
6ad529cd31
3 changed files with 351 additions and 0 deletions
147
day3/main.go
Normal file
147
day3/main.go
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
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)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue