-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
105 lines (84 loc) · 2.01 KB
/
main.go
File metadata and controls
105 lines (84 loc) · 2.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package main
import (
"bytes"
"fmt"
"io"
"os"
"path"
"strings"
)
func input() *os.File {
input, err := os.Open(path.Join("2021", "3", "input.txt"))
if err != nil {
panic(err)
}
return input
}
func solve(r io.Reader) {
raw, err := io.ReadAll(r)
if err != nil {
panic(err)
}
nums := strings.Split(string(bytes.TrimSpace(raw)), "\n")
count := bitCount(nums)
width := len(nums[0])
gammaBits := bitsByIndexFunc(count, mostCommonBit, width)
gammaRate := constructIntFromBits(gammaBits, width)
// epsilon is always the negation of gamma because the least common bit
// is by definition the opposite of the most common bit
epsilonRate := constructIntFromBits(negate(gammaBits), width)
fmt.Println(gammaRate, epsilonRate, gammaRate*epsilonRate)
}
func negate(bits []int) []int {
result := make([]int, len(bits))
for i, b := range bits {
if b == 0 {
result[i] = 1
}
}
return result
}
func bitsByIndexFunc(count []int, bitAtIndex func(count int) int, width int) []int {
result := make([]int, width)
for i := 0; i < width; i++ {
result[i] = bitAtIndex(count[i])
}
return result
}
func constructIntFromBits(bits []int, width int) int {
value := 0
for i := 0; i < width; i++ {
value += bits[i] << (width - i - 1)
}
return value
}
// bitCount returns a slice of bits where the value at position i is
// - positive if the most common bit in nums at position i is 1
// - 0 if 0s and 1s are equally common in nums at position i
// - negative if the most common bit in nums at position i is 0
func bitCount(nums []string) []int {
var count []int
for i := 0; i < len(nums[0]); i++ {
count = append(count, 0)
}
for _, num := range nums {
for index, character := range num {
if character == '0' {
count[index] -= 1
} else {
count[index] += 1
}
}
}
return count
}
func mostCommonBit(count int) int {
if count >= 0 {
return 1
}
return 0
}
func main() {
solve(strings.NewReader("00100\n11110\n10110\n10111\n10101\n01111\n00111\n11100\n10000\n11001\n00010\n01010"))
solve(input())
}