137 lines
2.5 KiB
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))
|
|
}
|