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)) }