AdventOfCode2021/03/main.go

101 lines
2.1 KiB
Go
Raw Normal View History

2021-12-03 15:11:54 +00:00
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"time"
)
func main() {
start := time.Now()
partOne()
duration := time.Since(start)
partTwo()
duration2 := time.Since(start)
fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration)
}
func makeScanner(test bool) *bufio.Scanner {
var f *os.File
if test {
f, _ = os.Open("inputs/testinput")
} else {
f, _ = os.Open("inputs/input")
}
reader := bufio.NewReader(f)
return bufio.NewScanner(reader)
}
func partOne() {
scanner := makeScanner(false)
r := map[int]int64{} // index => count of 1s
var lines int64
for scanner.Scan() {
line := scanner.Text()
lines++
n, _ := strconv.ParseInt(line, 2, 64)
2021-12-03 23:53:09 +00:00
for i := 0; i < len(line); i++ {
2021-12-03 15:11:54 +00:00
// check if the number in the i'th column is 1, then bit-shift back to the 1s place to add it if it is
r[i] += (n & (1 << i)) >> i
}
}
var epsilon, gamma int64
for i, b := range r {
// if more than half the bits were ones, gamma gets the 1, otherwise epsilon gets the 1
// alternatively, this could have been an XOR operation, I suppose, once one or the other had been computed
if b > lines/2 {
gamma += 1 << i
} else {
epsilon += 1 << i
}
}
fmt.Println(epsilon * gamma)
}
func partTwo() {
scanner := makeScanner(false)
inputs := []int64{}
2021-12-03 23:53:09 +00:00
var oxgen, co2scrub int64
var bitlen int64
2021-12-03 15:11:54 +00:00
for scanner.Scan() {
2021-12-03 23:53:09 +00:00
line := scanner.Text()
n, _ := strconv.ParseInt(line, 2, 64)
inputs = append(inputs, n)
bitlen = int64(len(line))
2021-12-03 23:53:09 +00:00
}
// on initial loop, oxgen>>i == n>>i etc always come out to 0 == 0
2021-12-03 23:53:09 +00:00
for i := bitlen; i > 0; i-- {
var oxOnes, oxZeroes, coOnes, coZeroes int64
for _, n := range inputs {
if oxgen>>i == n>>i {
if oxgen>>(i-1)^n>>(i-1) == 1 {
oxOnes++
} else {
oxZeroes++
}
}
if co2scrub>>i == n>>i {
if co2scrub>>(i-1)^n>>(i-1) == 1 {
coOnes++
} else {
coZeroes++
}
}
}
if oxOnes >= oxZeroes {
oxgen += (1 << (i - 1))
}
if (coZeroes == 0 && coOnes != 0) || (coOnes < coZeroes && coOnes != 0) {
2021-12-03 23:53:09 +00:00
co2scrub += (1 << (i - 1))
}
2021-12-03 15:11:54 +00:00
}
2021-12-03 23:53:09 +00:00
fmt.Println(oxgen * co2scrub)
2021-12-03 15:11:54 +00:00
}