From c13f4ca2361f342306d51cc54f7b36c8d820b43f Mon Sep 17 00:00:00 2001 From: Jeremy Kaplan Date: Thu, 2 Dec 2021 21:48:37 -0800 Subject: [PATCH] 2021 Day 3 --- 2021/aoc/aoc.go | 20 ++++++++++ 2021/day3/main.go | 93 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 2021/aoc/aoc.go create mode 100644 2021/day3/main.go diff --git a/2021/aoc/aoc.go b/2021/aoc/aoc.go new file mode 100644 index 0000000..78b46b6 --- /dev/null +++ b/2021/aoc/aoc.go @@ -0,0 +1,20 @@ +package aoc + +import ( + "bufio" + "os" +) + +func ReadLines(path string) (lines []string) { + f, err := os.Open(path) + if err != nil { + panic(err) + } + defer f.Close() + + scanner := bufio.NewScanner(f) + for scanner.Scan() { + lines = append(lines, scanner.Text()) + } + return lines +} diff --git a/2021/day3/main.go b/2021/day3/main.go new file mode 100644 index 0000000..3891928 --- /dev/null +++ b/2021/day3/main.go @@ -0,0 +1,93 @@ +package main + +import ( + "fmt" + "strconv" + + "github.com/jdkaplan/advent-of-code/aoc" +) + +const bits = 12 + +func part1(lines []string) uint { + var count [bits]int + for _, line := range lines { + for i, char := range line { + // Fix the index to be from the right + i := bits - i - 1 + switch char { + case '0': + count[i]-- + case '1': + count[i]++ + default: + panic(char) + } + } + } + + var gamma uint + var epsilon uint + for i, c := range count { + mask := uint(1 << i) + if c > 0 { + gamma |= mask + epsilon &= ^mask + } else { + gamma &= ^mask + epsilon |= mask + } + } + + return gamma * epsilon +} + +func partition(lines []string, idx int) (zeros []string, ones []string) { + for _, line := range lines { + char := line[idx] + switch char { + case '0': + zeros = append(zeros, line) + case '1': + ones = append(ones, line) + default: + panic(char) + } + } + return +} + +func mustBin(s string) uint { + u, err := strconv.ParseUint(s, 2, 0) + if err != nil { + panic(err) + } + return uint(u) +} + +func part2(lines []string) int { + oxy, co2 := lines, lines + for i := 0; i < bits && len(oxy) > 1; i++ { + zeros, ones := partition(oxy, i) + if len(ones) >= len(zeros) { + oxy = ones + } else { + oxy = zeros + } + } + for i := 0; i < bits && len(co2) > 1; i++ { + zeros, ones := partition(co2, i) + if len(ones) >= len(zeros) { + co2 = zeros + } else { + co2 = ones + } + } + return int(mustBin(oxy[0]) * mustBin(co2[0])) +} + +func main() { + lines := aoc.ReadLines("./input/day3.txt") + fmt.Println(part1(lines)) + fmt.Println(part2(lines)) +}