adventofcode/2021/day03/main.go

137 lines
2.5 KiB
Go

package main
import (
"fmt"
h "git.bullercodeworks.com/brian/adventofcode/helpers"
)
func main() {
inp := h.StdinToStringSlice()
part1(inp)
part2(inp)
}
func binStrToUint64(inp string) uint64 {
var res uint64
for i := range inp {
if inp[i] == '0' {
res = res << 1
} else {
res = (res << 1) | 1
}
}
return res
}
type Pair struct {
zero int
one int
}
func (p Pair) MostByte(fallback byte) byte {
if p.zero == p.one {
return fallback
} else if p.zero > p.one {
return '0'
}
return '1'
}
func (p Pair) LeastByte(fallback byte) byte {
if p.zero == p.one {
return fallback
} else if p.zero < p.one {
return '0'
}
return '1'
}
func buildReport(inp []string) map[int]Pair {
totals := make(map[int]Pair)
for k := range inp {
for i := range inp[k] {
var p Pair
var ok bool
if p, ok = totals[i]; !ok {
p = Pair{zero: 0, one: 0}
}
if inp[k][i] == '0' {
p.zero++
} else {
p.one++
}
totals[i] = p
}
}
return totals
}
func part1(inp []string) {
totals := buildReport(inp)
var gamma uint64
var epsilon uint64
var gammaStr string
var epsilonStr string
for i := 0; i <= len(inp[0]); i++ {
p, ok := totals[i]
if ok {
if p.zero > p.one {
//gamma = gamma << 1
//epsilon = (epsilon << 1) | 1
gammaStr = gammaStr + "0"
epsilonStr = epsilonStr + "1"
} else {
//gamma = (gamma << 1) | 1
//epsilon = epsilon << 1
gammaStr = gammaStr + "1"
epsilonStr = epsilonStr + "0"
}
}
}
gamma = binStrToUint64(gammaStr)
epsilon = binStrToUint64(epsilonStr)
fmt.Println("# Part 1")
fmt.Println("gamma:", gammaStr, gamma)
fmt.Println("epsilon:", epsilonStr, epsilon)
fmt.Println("power consumption:", (gamma * epsilon))
fmt.Println("")
}
func part2(inp []string) {
fmt.Println("# Part 2")
bldOx := make([]string, len(inp))
copy(bldOx, inp)
idx := 0
for len(bldOx) > 1 && idx < len(inp[0]) {
totals := buildReport(bldOx)
var next []string
for i := range bldOx {
if bldOx[i][idx] == totals[idx].MostByte('1') {
next = append(next, bldOx[i])
}
}
bldOx = next
idx++
}
oxV := binStrToUint64(bldOx[0])
fmt.Println("Oxygen Rating:", bldOx, oxV)
co2 := make([]string, len(inp))
copy(co2, inp)
idx = 0
for len(co2) > 1 && idx < len(inp[0]) {
totals := buildReport(co2)
var next []string
for i := range co2 {
if co2[i][idx] == totals[idx].LeastByte('0') {
next = append(next, co2[i])
}
}
co2 = next
idx++
}
co2V := binStrToUint64(co2[0])
fmt.Println("CO2 Rating:", co2, co2V)
fmt.Println("Life Support Rating:", (oxV * co2V))
}