jlelse
/
aoc21
Archived
1
Fork 0
This commit is contained in:
Jan-Lukas Else 2021-12-03 13:43:28 +01:00
parent 0d8a41e58c
commit 44c1c2b173
3 changed files with 1134 additions and 0 deletions

1000
03/input.txt Normal file

File diff suppressed because it is too large Load Diff

120
03/main.go Normal file
View File

@ -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
}

14
03/main_test.go Normal file
View File

@ -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, ",")))
}