Day 03
This commit is contained in:
parent
0d8a41e58c
commit
44c1c2b173
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,120 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"math"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/thoas/go-funk"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
inputBytes, _ := os.ReadFile("input.txt")
|
||||||
|
inputs := strings.Split(string(inputBytes), "\n")
|
||||||
|
|
||||||
|
log.Println("Puzzle 1:", puzzle1(inputs))
|
||||||
|
log.Println("Puzzle 2:", puzzle2(inputs))
|
||||||
|
}
|
||||||
|
|
||||||
|
func puzzle1(input []string) int {
|
||||||
|
// Each bit in the gamma rate can be determined by finding the most common bit in the corresponding position of all numbers in the diagnostic report.
|
||||||
|
// The epsilon rate is calculated in a similar way; rather than use the most common bit, the least common bit from each position is used.
|
||||||
|
zeros := make([]int, len(input[0]))
|
||||||
|
ones := make([]int, len(input[0]))
|
||||||
|
for _, line := range input {
|
||||||
|
for i, c := range line {
|
||||||
|
if c == '0' {
|
||||||
|
zeros[i]++
|
||||||
|
} else if c == '1' {
|
||||||
|
ones[i]++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Get most and least common
|
||||||
|
mostCommon := make([]int, len(input[0]))
|
||||||
|
leastCommon := make([]int, len(input[0]))
|
||||||
|
for i, z := range zeros {
|
||||||
|
if z > ones[i] {
|
||||||
|
mostCommon[i] = 0
|
||||||
|
leastCommon[i] = 1
|
||||||
|
} else {
|
||||||
|
mostCommon[i] = 1
|
||||||
|
leastCommon[i] = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Convert mostCommon and leastCommon from bits to ints
|
||||||
|
gammaRate := 0
|
||||||
|
for i, c := range funk.ReverseInt(mostCommon) {
|
||||||
|
gammaRate += c * int(math.Pow(2, float64(i)))
|
||||||
|
}
|
||||||
|
epsilonRate := 0
|
||||||
|
for i, c := range funk.ReverseInt(leastCommon) {
|
||||||
|
epsilonRate += c * int(math.Pow(2, float64(i)))
|
||||||
|
}
|
||||||
|
// Return the product of the two rates, the power consumption
|
||||||
|
return gammaRate * epsilonRate
|
||||||
|
}
|
||||||
|
|
||||||
|
func puzzle2(input []string) int {
|
||||||
|
// Most common bit on position
|
||||||
|
mostCommon := func(input []string, position int, whenEqual int) int {
|
||||||
|
zeros := 0
|
||||||
|
ones := 0
|
||||||
|
for _, line := range input {
|
||||||
|
if line[position] == '0' {
|
||||||
|
zeros++
|
||||||
|
} else if line[position] == '1' {
|
||||||
|
ones++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if zeros > ones {
|
||||||
|
return 0
|
||||||
|
} else if ones > zeros {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return whenEqual
|
||||||
|
}
|
||||||
|
// Filter inputs
|
||||||
|
inputLen := len(input[0])
|
||||||
|
oxygen := input
|
||||||
|
for i := 0; i < inputLen; i++ {
|
||||||
|
if len(oxygen) < 2 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
most := mostCommon(oxygen, i, 1)
|
||||||
|
oxygen = funk.FilterString(oxygen, func(s string) bool {
|
||||||
|
if most == 1 {
|
||||||
|
return s[i] == '1'
|
||||||
|
} else {
|
||||||
|
return s[i] == '0'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
co2 := input
|
||||||
|
for i := 0; i < inputLen; i++ {
|
||||||
|
if len(co2) < 2 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
least := 1 - mostCommon(co2, i, 1)
|
||||||
|
co2 = funk.FilterString(co2, func(s string) bool {
|
||||||
|
if least == 1 {
|
||||||
|
return s[i] == '1'
|
||||||
|
} else {
|
||||||
|
return s[i] == '0'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// Convert first string in oxygen from bits to int
|
||||||
|
oxygenRating := 0
|
||||||
|
for i, c := range funk.ReverseString(oxygen[0]) {
|
||||||
|
oxygenRating += int(c-'0') * int(math.Pow(2, float64(i)))
|
||||||
|
}
|
||||||
|
// Convert first string in co2 from bits to int
|
||||||
|
co2Rating := 0
|
||||||
|
for i, c := range funk.ReverseString(co2[0]) {
|
||||||
|
co2Rating += int(c-'0') * int(math.Pow(2, float64(i)))
|
||||||
|
}
|
||||||
|
// Return the product of the two rates, the life support rating
|
||||||
|
return oxygenRating * co2Rating
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test(t *testing.T) {
|
||||||
|
input := `00100,11110,10110,10111,10101,01111,00111,11100,10000,11001,00010,01010`
|
||||||
|
assert.Equal(t, 198, puzzle1(strings.Split(input, ",")))
|
||||||
|
assert.Equal(t, 230, puzzle2(strings.Split(input, ",")))
|
||||||
|
}
|
Reference in New Issue