Add solution for day 9 part 1

master
Nick Krichevsky 2023-12-09 13:30:52 -05:00
parent 756fa3b52a
commit 587d832294
1 changed files with 100 additions and 0 deletions

100
day9/main.go Normal file
View File

@ -0,0 +1,100 @@
package main
import (
"fmt"
"io"
"os"
"strconv"
"strings"
)
func main() {
if len(os.Args) != 2 && len(os.Args) != 3 {
fmt.Fprintf(os.Stderr, "Usage: %s inputfile\n", os.Args[0])
os.Exit(1)
}
inputFilename := os.Args[1]
inputFile, err := os.Open(inputFilename)
if err != nil {
panic(fmt.Sprintf("could not open input file: %s", err))
}
defer inputFile.Close()
inputBytes, err := io.ReadAll(inputFile)
if err != nil {
panic(fmt.Sprintf("could not read input file: %s", err))
}
input := strings.TrimSpace(string(inputBytes))
inputLines := strings.Split(input, "\n")
histories, err := parseHistories(inputLines)
if err != nil {
panic(fmt.Sprintf("failed to parse histories: %s", err))
}
fmt.Printf("Part 1: %d\n", part1(histories))
}
func part1(histories [][]int) int {
total := 0
for _, history := range histories {
total += predictNextValue(history)
}
return total
}
// predictNextValue calculates the next item in the sequence by using the nth differences
func predictNextValue(history []int) int {
if allEqual(history, 0) {
return 0
}
differences := make([]int, len(history)-1)
for i := range history[1:] {
differences[i] = history[i+1] - history[i]
}
return history[len(history)-1] + predictNextValue(differences)
}
func allEqual[T comparable, S ~[]T](values S, shouldEqual T) bool {
for _, value := range values {
if value != shouldEqual {
return false
}
}
return true
}
func parseHistories(lines []string) ([][]int, error) {
histories := make([][]int, len(lines))
for i, line := range lines {
history, err := parseHistory(line)
if err != nil {
return nil, fmt.Errorf("parse history %d: %s", i, err)
}
histories[i] = history
}
return histories, nil
}
func parseHistory(line string) ([]int, error) {
rawNums := strings.Split(line, " ")
history := make([]int, len(rawNums))
for i, rawNum := range rawNums {
n, err := strconv.Atoi(rawNum)
if err != nil {
return nil, fmt.Errorf("parse item %d: %w", i, err)
}
history[i] = n
}
return history, nil
}