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) for i := 0; i < len(line); i++ { // 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) var lines int inputs := map[int]int64{} var oxgen, co2scrub int64 var totalOnes, bitlen int64 for scanner.Scan() { line := scanner.Text() n, _ := strconv.ParseInt(line, 2, 64) inputs[lines] = n bitlen = int64(len(line)) - 1 totalOnes += n >> (bitlen) lines++ } // make initial check if totalOnes >= int64(lines)/2 { oxgen += (1 << bitlen) } else { co2scrub += (1 << bitlen) } 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 { co2scrub += (1 << (i - 1)) } else if coZeroes != 0 && coOnes == 0 { co2scrub += (0 << (i - 1)) } else if coOnes < coZeroes { co2scrub += (1 << (i - 1)) } } fmt.Println(oxgen * co2scrub) }