2021 - Day 16
This commit is contained in:
parent
381496366f
commit
81bfde00b4
9
2021/16/go.mod
Normal file
9
2021/16/go.mod
Normal file
|
@ -0,0 +1,9 @@
|
|||
module AoC/2021/16
|
||||
|
||||
require AoC/2021/common v0.0.0
|
||||
|
||||
require github.com/joho/godotenv v1.4.0 // indirect
|
||||
|
||||
replace AoC/2021/common v0.0.0 => ../common
|
||||
|
||||
go 1.17
|
2
2021/16/go.sum
Normal file
2
2021/16/go.sum
Normal file
|
@ -0,0 +1,2 @@
|
|||
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
|
||||
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
182
2021/16/main.go
Normal file
182
2021/16/main.go
Normal file
|
@ -0,0 +1,182 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"AoC/2021/common"
|
||||
"bufio"
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
// Also implements a special operator -1, this operator will sum the versions of all (sub)packages
|
||||
func parsePackage(data []int, offset int, operator int, numberOfPackets int, lengthOfPackets int) (int, int) {
|
||||
total := 0
|
||||
// If we are going to multiply we need to start with 1
|
||||
if operator == 1 {
|
||||
total = 1
|
||||
}
|
||||
|
||||
start := offset
|
||||
for packetNumber := 0; (packetNumber < numberOfPackets || lengthOfPackets > offset - start); packetNumber++ {
|
||||
version := 0
|
||||
for i := 0; i < 3; i++ {
|
||||
version <<= 1
|
||||
version += data[offset + i]
|
||||
}
|
||||
offset += 3
|
||||
|
||||
typeID := 0
|
||||
for i := 0; i < 3; i++ {
|
||||
typeID <<= 1
|
||||
typeID += data[offset + i]
|
||||
}
|
||||
offset += 3
|
||||
|
||||
value := 0
|
||||
if typeID == 4 {
|
||||
done := false
|
||||
for !done {
|
||||
done = data[offset + 0] == 0
|
||||
offset++
|
||||
for i := 0; i < 4; i++ {
|
||||
value <<= 1
|
||||
value += data[offset + i]
|
||||
}
|
||||
offset += 4
|
||||
}
|
||||
|
||||
if operator == -1 {
|
||||
value = version
|
||||
}
|
||||
} else {
|
||||
lengthTypeID := data[offset + 0]
|
||||
offset++
|
||||
|
||||
lop := 0
|
||||
nop := 0
|
||||
if lengthTypeID == 0 {
|
||||
for i := 0; i < 15; i++ {
|
||||
lop <<= 1
|
||||
lop += data[offset + i]
|
||||
}
|
||||
offset += 15
|
||||
} else if lengthTypeID == 1 {
|
||||
for i := 0; i < 11; i++ {
|
||||
nop <<= 1
|
||||
nop += data[offset + i]
|
||||
}
|
||||
offset += 11
|
||||
} else {
|
||||
panic("Unknown lengthTypeID")
|
||||
}
|
||||
|
||||
if operator == -1 {
|
||||
typeID = -1
|
||||
}
|
||||
|
||||
offset, value = parsePackage(data, offset, typeID, nop, lop)
|
||||
|
||||
if operator == -1 {
|
||||
value += version
|
||||
}
|
||||
}
|
||||
|
||||
switch operator {
|
||||
case -1, 0:
|
||||
total += value
|
||||
case 1:
|
||||
total *= value
|
||||
case 2:
|
||||
if value < total || packetNumber == 0 {
|
||||
total = value
|
||||
}
|
||||
case 3:
|
||||
if value > total || packetNumber == 0 {
|
||||
total = value
|
||||
}
|
||||
case 5:
|
||||
if packetNumber == 0 {
|
||||
total = value
|
||||
} else if packetNumber == 1 {
|
||||
if total > value {
|
||||
total = 1
|
||||
} else {
|
||||
total = 0
|
||||
}
|
||||
} else {
|
||||
panic("To many sub packets for 'greater than' operator")
|
||||
}
|
||||
case 6:
|
||||
if packetNumber == 0 {
|
||||
total = value
|
||||
} else if packetNumber == 1 {
|
||||
if total < value {
|
||||
total = 1
|
||||
} else {
|
||||
total = 0
|
||||
}
|
||||
} else {
|
||||
panic("To many sub packets for 'less than' operator")
|
||||
}
|
||||
case 7:
|
||||
if packetNumber == 0 {
|
||||
total = value
|
||||
} else if packetNumber == 1 {
|
||||
if total == value {
|
||||
total = 1
|
||||
} else {
|
||||
total = 0
|
||||
}
|
||||
} else {
|
||||
panic("To many sub packets for 'equal to' operator")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return offset, total
|
||||
}
|
||||
|
||||
func parseInput(input *bufio.Scanner) []int {
|
||||
input.Scan()
|
||||
in, _ := hex.DecodeString(input.Text())
|
||||
|
||||
var data []int
|
||||
for _, b := range in {
|
||||
for i := 7; i >= 0; i-- {
|
||||
data = append(data, int((b >> i) & 1))
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func main() {
|
||||
challenge := aoc.New(2021, 16)
|
||||
|
||||
challenge.Test(`D2FE28`, []int{6, -2})
|
||||
challenge.Test(`8A004A801A8002F478`, []int{16, -2})
|
||||
challenge.Test(`620080001611562C8802118E34`, []int{12, -2})
|
||||
challenge.Test(`C0015000016115A2E0802F182340`, []int{23, -2})
|
||||
challenge.Test(`A0016C880162017C3686B18A3D4780`, []int{31, -2})
|
||||
|
||||
challenge.Test(`C200B40A82`, []int{-2, 3})
|
||||
challenge.Test(`04005AC33890`, []int{-2, 54})
|
||||
challenge.Test(`880086C3E88112`, []int{-2, 7})
|
||||
challenge.Test(`CE00C43D881120`, []int{-2, 9})
|
||||
challenge.Test(`D8005AC2A8F0`, []int{-2, 1})
|
||||
challenge.Test(`F600BC2D8F`, []int{-2, 0})
|
||||
challenge.Test(`9C005AC2F8F0`, []int{-2, 0})
|
||||
challenge.Test(`9C0141080250320F1802104A08`, []int{-2, 1})
|
||||
|
||||
challenge.Solution(1, func (input *bufio.Scanner) int {
|
||||
data := parseInput(input)
|
||||
_, sum := parsePackage(data, 0, -1, 1, 0)
|
||||
|
||||
return sum
|
||||
})
|
||||
|
||||
challenge.Solution(2, func (input *bufio.Scanner) int {
|
||||
data := parseInput(input)
|
||||
_, sum := parsePackage(data, 0, 0, 1, 0)
|
||||
|
||||
return sum
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue
Block a user