From 04f29cdb4d9450f86c207a890f3f661c3abbb990 Mon Sep 17 00:00:00 2001 From: Anna Wiggins Date: Tue, 8 Dec 2020 09:09:09 +0000 Subject: [PATCH] Started AOC 2020 - solved the first 4.5 days. --- 2020/.gitignore | 1 + 2020/Makefile | 8 ++ 2020/day01.go | 35 ++++++++ 2020/day02.go | 60 +++++++++++++ 2020/day03.go | 44 +++++++++ 2020/day04.go | 153 ++++++++++++++++++++++++++++++++ 2020/day05.go | 46 ++++++++++ 2020/go.mod | 3 + 2020/lib/fileutils/fileutils.go | 39 ++++++++ 9 files changed, 389 insertions(+) create mode 100644 2020/.gitignore create mode 100644 2020/Makefile create mode 100644 2020/day01.go create mode 100644 2020/day02.go create mode 100644 2020/day03.go create mode 100644 2020/day04.go create mode 100644 2020/day05.go create mode 100644 2020/go.mod create mode 100644 2020/lib/fileutils/fileutils.go diff --git a/2020/.gitignore b/2020/.gitignore new file mode 100644 index 0000000..567609b --- /dev/null +++ b/2020/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/2020/Makefile b/2020/Makefile new file mode 100644 index 0000000..bfb606f --- /dev/null +++ b/2020/Makefile @@ -0,0 +1,8 @@ +all: + +%: %.go + mkdir -p build/ + go build -o build/$@ $< + +clean: + rm -rf build/ diff --git a/2020/day01.go b/2020/day01.go new file mode 100644 index 0000000..239e828 --- /dev/null +++ b/2020/day01.go @@ -0,0 +1,35 @@ +package main + +import ( + "fmt" + "os" + + "git.annabunch.es/annabunches/adventofcode/2020/lib/fileutils" +) + +func main() { + step := os.Args[1] + values := fileutils.InputParserIntMap(os.Args[2]) + + switch step { + case "1": + for x, _ := range values { + if _, ok := values[2020-x]; ok { + answer := x * (2020 - x) + fmt.Println("The answer is:", answer) + return + } + } + case "2": + for x, _ := range values { + target := 2020 - x + for y, _ := range values { + if _, ok := values[target-y]; ok { + answer := x * y * (target - y) + fmt.Println("The answer is:", answer) + return + } + } + } + } +} diff --git a/2020/day02.go b/2020/day02.go new file mode 100644 index 0000000..ce8a02d --- /dev/null +++ b/2020/day02.go @@ -0,0 +1,60 @@ +package main + +import ( + "fmt" + "log" + "os" + "strconv" + "strings" + + "git.annabunch.es/annabunches/adventofcode/2020/lib/fileutils" +) + +func checkLine(line string, step string) int { + if line == "" { + return 0 + } + + data := strings.Split(line, " ") + minMaxData := strings.Split(data[0], "-") + + min, err := strconv.Atoi(minMaxData[0]) + if err != nil { + log.Panicf(err.Error()) + } + max, err := strconv.Atoi(minMaxData[1]) + if err != nil { + log.Panicf(err.Error()) + } + char := strings.TrimSuffix(data[1], ":") + + switch step { + case "1": + count := strings.Count(data[2], char) + + if count >= min && count <= max { + return 1 + } + return 0 + case "2": + bchar := char[0] + if (data[2][min-1] == bchar || data[2][max-1] == bchar) && + !(data[2][min-1] == bchar && data[2][max-1] == bchar) { + return 1 + } + return 0 + } + + return 0 +} + +func main() { + step := os.Args[1] + values := fileutils.InputParserStrings(os.Args[2]) + + total := 0 + for _, line := range values { + total += checkLine(line, step) + } + fmt.Println("Valid passwords:", total) +} diff --git a/2020/day03.go b/2020/day03.go new file mode 100644 index 0000000..b5c6f15 --- /dev/null +++ b/2020/day03.go @@ -0,0 +1,44 @@ +package main + +import ( + "fmt" + "os" + + "git.annabunch.es/annabunches/adventofcode/2020/lib/fileutils" +) + +func countTrees(input []string, right, down int) int { + x := 0 + total := 0 + for y, line := range input { + if y == 0 || len(line) == 0 || y%down != 0 { + continue + } + + x = (x + right) % len(line) + if line[x] == '#' { + total += 1 + } + } + + return total +} + +func main() { + step := os.Args[1] + values := fileutils.InputParserStrings(os.Args[2]) + + switch step { + case "1": + total := countTrees(values, 3, 1) + fmt.Println("Trees:", total) + case "2": + total := countTrees(values, 1, 1) + total *= countTrees(values, 3, 1) + total *= countTrees(values, 5, 1) + total *= countTrees(values, 7, 1) + total *= countTrees(values, 1, 2) + fmt.Println("Tree Product:", total) + } + +} diff --git a/2020/day04.go b/2020/day04.go new file mode 100644 index 0000000..dc234f2 --- /dev/null +++ b/2020/day04.go @@ -0,0 +1,153 @@ +package main + +import ( + "fmt" + "log" + "os" + "regexp" + "strconv" + "strings" + + "git.annabunch.es/annabunches/adventofcode/2020/lib/fileutils" +) + +func splitPassports(input []string) []string { + converted := []string{} + + current := "" + for _, line := range input { + if line == "" { + converted = append(converted, current) + current = "" + continue + } + + current += " " + line + } + + return converted +} + +func countValidPassports(input []string, step string) int { + total := 0 + for _, line := range input { + if strings.Contains(line, "byr:") && + strings.Contains(line, "iyr:") && + strings.Contains(line, "eyr:") && + strings.Contains(line, "hgt:") && + strings.Contains(line, "hcl:") && + strings.Contains(line, "ecl:") && + strings.Contains(line, "pid:") { + if step == "1" { + total += 1 + continue + } + + i := validatePassport(line) + if i == 0 { + log.Printf("Failed: %s", line) + } else { + log.Printf("Passed: %s", line) + } + + total += i + } + } + + return total +} + +func validatePassport(input string) int { + fields := strings.Split(input, " ") + for _, field := range fields { + if field == "" { + continue + } + + subFields := strings.Split(field, ":") + if len(subFields) != 2 { + log.Panicf("Failed to split subfields on '%s'", field) + } + name := subFields[0] + value := subFields[1] + + switch name { + case "byr": + ivalue := makeInt(value) + if ivalue < 1920 || ivalue > 2002 { + return 0 + } + case "iyr": + ivalue := makeInt(value) + if ivalue < 2010 || ivalue > 2020 { + return 0 + } + case "eyr": + ivalue := makeInt(value) + if ivalue < 2020 || ivalue > 2030 { + return 0 + } + case "hgt": + if strings.HasSuffix(value, "cm") { + ivalue := makeInt(strings.TrimSuffix(value, "cm")) + if ivalue < 150 || ivalue > 193 { + return 0 + } + } else if strings.HasSuffix(value, "in") { + ivalue := makeInt(strings.TrimSuffix(value, "in")) + if ivalue < 59 || ivalue > 76 { + return 0 + } + } else { + return 0 + } + case "hcl": + match, err := regexp.MatchString("^#[0-9a-f]{6}$", value) + if err != nil { + log.Panicf(err.Error()) + } + if !match { + return 0 + } + case "ecl": + if value != "amb" && + value != "blu" && + value != "brn" && + value != "gry" && + value != "grn" && + value != "hzl" && + value != "oth" { + return 0 + } + case "pid": + match, err := regexp.MatchString("^[0-9]{9}$", value) + if err != nil { + log.Panicf(err.Error()) + } + if !match { + return 0 + } + case "cid": + default: + log.Panicf("Got bad field data: ") + } + } + + return 1 +} + +func makeInt(input string) int { + i, err := strconv.Atoi(input) + if err != nil { + log.Panicf(err.Error()) + } + return i +} + +func main() { + step := os.Args[1] + values := fileutils.InputParserStrings(os.Args[2]) + values = splitPassports(values) + + fmt.Println("Valid Passports:", countValidPassports(values, step)) +} diff --git a/2020/day05.go b/2020/day05.go new file mode 100644 index 0000000..3917a62 --- /dev/null +++ b/2020/day05.go @@ -0,0 +1,46 @@ +package main + +import ( + "fmt" + "log" + "os" + "strconv" + "strings" + + "git.annabunch.es/annabunches/adventofcode/2020/lib/fileutils" +) + +func calculateSeatNumber(input string) int { + if input == "" { + return 0 + } + + row, err := strconv.ParseInt(strings.ReplaceAll(strings.ReplaceAll(input[0:7], "F", "0"), "B", "1"), 2, 32) + if err != nil { + log.Panicf(err.Error()) + } + col, err := strconv.ParseInt(strings.ReplaceAll(strings.ReplaceAll(input[7:10], "L", "0"), "R", "1"), 2, 32) + if err != nil { + log.Panicf(err.Error()) + } + return int((row * 8) + col) +} + +func main() { + step := os.Args[1] + values := fileutils.InputParserStrings(os.Args[2]) + + switch step { + case "1": + max := 0 + for _, line := range values { + seatNumber := calculateSeatNumber(line) + if seatNumber > max { + max = seatNumber + } + } + fmt.Println("Highest Seat Number:", max) + case "2": + // build a map of all seat numbers then just print the ones between 0 and 1024 that don't exist + } +} diff --git a/2020/go.mod b/2020/go.mod new file mode 100644 index 0000000..3011a85 --- /dev/null +++ b/2020/go.mod @@ -0,0 +1,3 @@ +module git.annabunch.es/annabunches/adventofcode/2020 + +go 1.15 diff --git a/2020/lib/fileutils/fileutils.go b/2020/lib/fileutils/fileutils.go new file mode 100644 index 0000000..6a56caa --- /dev/null +++ b/2020/lib/fileutils/fileutils.go @@ -0,0 +1,39 @@ +package fileutils + +import ( + "bufio" + "io/ioutil" + "log" + "os" + "strconv" + "strings" +) + +func InputParserIntMap(filename string) map[int]bool { + file, err := os.Open(filename) + defer file.Close() + + if err != nil { + log.Panicf(err.Error()) + } + + values := make(map[int]bool) + scanner := bufio.NewScanner(file) + for scanner.Scan() { + x, err := strconv.Atoi(scanner.Text()) + if err != nil { + log.Panicf(err.Error()) + } + values[x] = true + } + + return values +} + +func InputParserStrings(filename string) []string { + data, err := ioutil.ReadFile(filename) + if err != nil { + log.Panicf(err.Error()) + } + return strings.Split(string(data), "\n") +}