aoc/2021/3/improved.go
2021-12-04 20:51:14 +01:00

131 lines
2.1 KiB
Go

package main
import (
aoc "AoC/2021/common"
"bufio"
"log"
"strconv"
)
func count(entries []string, width int) [2][]int {
counts := [2][]int{make([]int, width), make([]int, width)}
for _, entry := range entries {
for i, c := range entry {
if string(c) == "0" {
counts[0][i]++
} else if string(c) == "1" {
counts[1][i]++
} else {
log.Fatalf("Unknown character '%s'\n", string(c))
}
}
}
return counts
}
func filter(entries []string, i int, value string) []string {
n := 0
for _, num := range entries {
if string(num[i]) == value {
entries[n] = num
n++
}
}
return entries[:n]
}
func process(input *bufio.Scanner) ([]string, int) {
var numbers []string
width := 0
for i :=0; input.Scan(); i++ {
line := input.Text()
numbers = append(numbers, line)
if len(line) > width {
width = len(line)
}
}
return numbers, width
}
func main() {
aoc := aoc.New(2021, 3)
aoc.Test(`
00100
11110
10110
10111
10101
01111
00111
11100
10000
11001
00010
01010
`, []int{198, 230})
aoc.Solution(1, func (input *bufio.Scanner) int {
entries, width := process(input)
counts := count(entries, width)
gamma := 0
epsilon := 0
for i := 0; i < width; i++ {
if counts[0][i] > counts[1][i] {
epsilon += 1 << (width - 1 - i)
} else {
gamma += 1 << (width - 1 - i)
}
}
return gamma * epsilon
})
aoc.Solution(2, func (input *bufio.Scanner) int {
oxygen, width := process(input)
oxygenCounts := count(oxygen, width)
co2 := make([]string, len(oxygen)); copy(co2, oxygen)
co2Counts := count(co2, width)
for i := 0; i < width; i++ {
f1 := "1"
if oxygenCounts[0][i] > oxygenCounts[1][i] {
f1 = "0"
}
if len(oxygen) > 1 {
oxygen = filter(oxygen, i, f1)
oxygenCounts = count(oxygen, width)
}
f2 := "0"
if co2Counts[0][i] > co2Counts[1][i] {
f2 = "1"
}
if len(co2) > 1 {
co2 = filter(co2, i, f2)
co2Counts = count(co2, width)
}
}
oxygenNum, err := strconv.ParseInt(oxygen[0], 2, 0)
if err != nil {
panic(err)
}
co2Num, err := strconv.ParseInt(co2[0], 2, 0)
if err != nil {
panic(err)
}
return int(oxygenNum) * int(co2Num)
})
}