2021 - Day 3 (Improved implementation)
This commit is contained in:
parent
36608f4e15
commit
ebcee1aa14
154
2021/3/improved.go
Normal file
154
2021/3/improved.go
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
aoc "AoC/2021/common"
|
||||||
|
"bufio"
|
||||||
|
"log"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
part1()
|
||||||
|
part2()
|
||||||
|
}
|
||||||
|
|
||||||
|
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 part1() {
|
||||||
|
aoc := aoc.New(2021, 3)
|
||||||
|
|
||||||
|
aoc.Test(`
|
||||||
|
00100
|
||||||
|
11110
|
||||||
|
10110
|
||||||
|
10111
|
||||||
|
10101
|
||||||
|
01111
|
||||||
|
00111
|
||||||
|
11100
|
||||||
|
10000
|
||||||
|
11001
|
||||||
|
00010
|
||||||
|
01010
|
||||||
|
`, 198)
|
||||||
|
|
||||||
|
aoc.Solution(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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func part2() {
|
||||||
|
aoc := aoc.New(2021, 3)
|
||||||
|
|
||||||
|
aoc.Test(`
|
||||||
|
00100
|
||||||
|
11110
|
||||||
|
10110
|
||||||
|
10111
|
||||||
|
10101
|
||||||
|
01111
|
||||||
|
00111
|
||||||
|
11100
|
||||||
|
10000
|
||||||
|
11001
|
||||||
|
00010
|
||||||
|
01010
|
||||||
|
`, 230)
|
||||||
|
|
||||||
|
aoc.Solution(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)
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user