From 4e10039bfb84e74e6f7f3871692281eea6c2ca1d Mon Sep 17 00:00:00 2001 From: Anna Wiggins Date: Fri, 11 Dec 2020 10:00:29 +0000 Subject: [PATCH] Day 9 solution. --- 2020/day09.go | 121 ++++++++++++++++++++++++++++++++ 2020/lib/fileutils/fileutils.go | 21 ++++++ 2 files changed, 142 insertions(+) create mode 100644 2020/day09.go diff --git a/2020/day09.go b/2020/day09.go new file mode 100644 index 0000000..7e0308b --- /dev/null +++ b/2020/day09.go @@ -0,0 +1,121 @@ +package main + +import ( + "fmt" + "log" + "os" + + "git.annabunch.es/annabunches/adventofcode/2020/lib/fileutils" +) + +type SumTracker map[int][]Tuple + +type Tuple struct { + First, Second int +} + +func checkValue(sumMap SumTracker, value int) bool { + _, ok := sumMap[value] + return ok +} + +func addSums(sumMap SumTracker, values []int, index int) { + for i := index - 25; i < index; i++ { + sum := values[i] + values[index] + sumMap[sum] = append(sumMap[sum], Tuple{First: i, Second: index}) + } +} + +func removeSums(sumMap SumTracker, index int) { + for sum, tupleList := range sumMap { + newList := make([]Tuple, 0) + + for _, tuple := range tupleList { + if !(tuple.First == index || tuple.Second == index) { + newList = append(newList, tuple) + } + } + sumMap[sum] = newList + if len(sumMap[sum]) == 0 { + delete(sumMap, sum) + } + } +} + +// find and return the slice of values that sums to sum +func findListSum(values []int, sum int) []int { + i := 0 + j := 0 + total := 0 + for total != sum { + for total < sum { + if j >= len(values) { + log.Panicf("Couldn't find a match.") + } + + total += values[j] + j++ + } + + for total > sum { + total -= values[i] + i++ + } + } + + return values[i:j] +} + +func sumMinMax(values []int) int { + min := values[0] + max := values[0] + + for _, x := range values { + if x < min { + min = x + } + + if x > max { + max = x + } + } + + return min + max +} + +func main() { + step := os.Args[1] + values := fileutils.InputParserInts(os.Args[2]) + + var badValue int + sumMap := make(SumTracker) + + // build up the preamble + for i := 0; i < 25; i++ { + for j := i + 1; j < 25; j++ { + sum := values[i] + values[j] + if _, ok := sumMap[sum]; !ok { + sumMap[sum] = make([]Tuple, 0) + } + + sumMap[sum] = append(sumMap[sum], Tuple{First: i, Second: j}) + } + } + + for i := 25; i < len(values); i++ { + if !checkValue(sumMap, values[i]) { + badValue = values[i] + break + } + addSums(sumMap, values, i) + removeSums(sumMap, i-25) + } + + switch step { + case "1": + fmt.Println(badValue) + case "2": + sumValues := findListSum(values, badValue) + fmt.Println(sumMinMax(sumValues)) + } +} diff --git a/2020/lib/fileutils/fileutils.go b/2020/lib/fileutils/fileutils.go index 6a56caa..8da287d 100644 --- a/2020/lib/fileutils/fileutils.go +++ b/2020/lib/fileutils/fileutils.go @@ -9,6 +9,27 @@ import ( "strings" ) +func InputParserInts(filename string) []int { + file, err := os.Open(filename) + defer file.Close() + + if err != nil { + log.Panicf(err.Error()) + } + + values := make([]int, 0) + scanner := bufio.NewScanner(file) + for scanner.Scan() { + x, err := strconv.Atoi(scanner.Text()) + if err != nil { + log.Panicf(err.Error()) + } + values = append(values, x) + } + + return values +} + func InputParserIntMap(filename string) map[int]bool { file, err := os.Open(filename) defer file.Close()