You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
1.6 KiB
Go
94 lines
1.6 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"sort"
|
|
"strconv"
|
|
)
|
|
|
|
const bitSize = 12
|
|
|
|
func bitComplement(num uint64) uint64 {
|
|
return ^num & (1<<bitSize - 1)
|
|
}
|
|
|
|
func partOne(counts *[bitSize]int, total *int) (uint64, uint64) {
|
|
averageThreshold := *total / 2
|
|
|
|
var gammaRate uint64 = 0
|
|
|
|
for index, count := range counts {
|
|
if count > 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()
|
|
}
|