package main import ( "bufio" "fmt" "log" "os" "sort" "strconv" ) const bitSize = 12 func bitComplement(num uint64) uint64 { return ^num & (1< averageThreshold { var add uint64 = 1 << (bitSize - 1 - index) gammaRate += add } } epsilonRate := bitComplement(gammaRate) return gammaRate, epsilonRate } func reduce(slice []string, depth int, max bool) int64 { var s []string half := len(slice) / 2 if half == 0 { ret, _ := strconv.ParseInt(slice[0], 2, 64) return ret } maxDigit := slice[half][depth] for _, str := range slice { if max && str[depth] == maxDigit { s = append(s, str) } if !max && str[depth] != maxDigit { s = append(s, str) } } return reduce(s, depth+1, max) } func partTwo(s []string) (int64, int64) { sort.Strings(s) return reduce(s, 0, true), reduce(s, 0, false) } func solve() { file, err := os.Open("input.txt") if err != nil { log.Fatal(err) } defer file.Close() scanner := bufio.NewScanner(file) scanner.Split(bufio.ScanLines) var counts [bitSize]int var s []string total := 0 for scanner.Scan() { line := scanner.Text() for index, character := range line { if character == '1' { counts[index]++ } } s = append(s, line) total++ } gamma, epsilon := partOne(&counts, &total) fmt.Println(int64(gamma) * int64(epsilon)) o2, co2 := partTwo(s) fmt.Println(o2 * co2) } func main() { solve() }