Actual solution for day 16!
This commit is contained in:
@@ -170,7 +170,6 @@ The total risk of the least risky path is 2864
|
|||||||
```sh
|
```sh
|
||||||
$ ./aoc2021 --sixteen
|
$ ./aoc2021 --sixteen
|
||||||
The solution for "sixteen" is:
|
The solution for "sixteen" is:
|
||||||
sixteen part 1 answer for bits
|
The sum of the version numbers is 1012
|
||||||
sixteen part 2 answer for bits
|
The output of the encoded input is 2223947372407
|
||||||
```
|
```
|
||||||
|
|
||||||
|
110
sixteen/bits.go
110
sixteen/bits.go
@@ -50,6 +50,87 @@ func (p *packet) versionSum() int {
|
|||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *packet) sum() int {
|
||||||
|
sum := 0
|
||||||
|
for _, p := range p.subpackets {
|
||||||
|
sum += p.value()
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *packet) product() int {
|
||||||
|
product := 1
|
||||||
|
for _, p := range p.subpackets {
|
||||||
|
product *= p.value()
|
||||||
|
}
|
||||||
|
return product
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *packet) min() int {
|
||||||
|
min := 0
|
||||||
|
for i, p := range p.subpackets {
|
||||||
|
if i == 0 || p.content < min {
|
||||||
|
min = p.value()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return min
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *packet) max() int {
|
||||||
|
max := 0
|
||||||
|
for i, p := range p.subpackets {
|
||||||
|
if i == 0 || p.content > max {
|
||||||
|
max = p.value()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *packet) greaterThan() int {
|
||||||
|
result := 0
|
||||||
|
if p.subpackets[0].value() > p.subpackets[1].value() {
|
||||||
|
result = 1
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *packet) lessThan() int {
|
||||||
|
result := 0
|
||||||
|
if p.subpackets[0].value() < p.subpackets[1].value() {
|
||||||
|
result = 1
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *packet) equalTo() int {
|
||||||
|
result := 0
|
||||||
|
if p.subpackets[0].value() == p.subpackets[1].value() {
|
||||||
|
result = 1
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *packet) value() int {
|
||||||
|
switch p.typeID {
|
||||||
|
case 0:
|
||||||
|
return p.sum()
|
||||||
|
case 1:
|
||||||
|
return p.product()
|
||||||
|
case 2:
|
||||||
|
return p.min()
|
||||||
|
case 3:
|
||||||
|
return p.max()
|
||||||
|
case 5:
|
||||||
|
return p.greaterThan()
|
||||||
|
case 6:
|
||||||
|
return p.lessThan()
|
||||||
|
case 7:
|
||||||
|
return p.equalTo()
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.content
|
||||||
|
}
|
||||||
|
|
||||||
func hexToBinary(input string) string {
|
func hexToBinary(input string) string {
|
||||||
output := ""
|
output := ""
|
||||||
for _, r := range input {
|
for _, r := range input {
|
||||||
@@ -124,7 +205,11 @@ func parsePackets(input string) []packet {
|
|||||||
default:
|
default:
|
||||||
l := 0
|
l := 0
|
||||||
p.subpackets, l = parseOperator(remaining[6:])
|
p.subpackets, l = parseOperator(remaining[6:])
|
||||||
remaining = remaining[l+7:]
|
if len(remaining) == l+6 {
|
||||||
|
remaining = ""
|
||||||
|
} else {
|
||||||
|
remaining = remaining[l+6:]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
packets = append(packets, p)
|
packets = append(packets, p)
|
||||||
@@ -146,16 +231,21 @@ func parseNPackets(input string, count int) ([]packet, int) {
|
|||||||
typeID: typeID,
|
typeID: typeID,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parsedLength := 0
|
||||||
switch p.typeID {
|
switch p.typeID {
|
||||||
case literalType:
|
case literalType:
|
||||||
value, length := parseLiteral(remaining[6:])
|
value := 0
|
||||||
|
value, parsedLength = parseLiteral(remaining[6:])
|
||||||
p.content = value
|
p.content = value
|
||||||
p.packet = remaining[:length+6]
|
p.packet = remaining[:parsedLength+6]
|
||||||
remaining = remaining[length+6:]
|
|
||||||
default:
|
default:
|
||||||
l := 0
|
p.subpackets, parsedLength = parseOperator(remaining[6:])
|
||||||
p.subpackets, l = parseOperator(remaining[6:])
|
}
|
||||||
remaining = remaining[l+7:]
|
|
||||||
|
if len(remaining) == parsedLength+6 {
|
||||||
|
remaining = ""
|
||||||
|
} else {
|
||||||
|
remaining = remaining[parsedLength+6:]
|
||||||
}
|
}
|
||||||
|
|
||||||
packets = append(packets, p)
|
packets = append(packets, p)
|
||||||
@@ -165,7 +255,7 @@ func parseNPackets(input string, count int) ([]packet, int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func parseOperator(input string) ([]packet, int) {
|
func parseOperator(input string) ([]packet, int) {
|
||||||
length := 0
|
length := 1
|
||||||
subPackets := []packet{}
|
subPackets := []packet{}
|
||||||
var lType int
|
var lType int
|
||||||
var remainder string
|
var remainder string
|
||||||
@@ -179,12 +269,12 @@ func parseOperator(input string) ([]packet, int) {
|
|||||||
lengthBits, _ := strconv.ParseInt(string(remainder[:15]), 2, 64)
|
lengthBits, _ := strconv.ParseInt(string(remainder[:15]), 2, 64)
|
||||||
subs := parsePackets(remainder[15 : 15+lengthBits])
|
subs := parsePackets(remainder[15 : 15+lengthBits])
|
||||||
subPackets = append(subPackets, subs...)
|
subPackets = append(subPackets, subs...)
|
||||||
length = 15 + int(lengthBits)
|
length += 15 + int(lengthBits)
|
||||||
case lengthType11:
|
case lengthType11:
|
||||||
lengthBits, _ := strconv.ParseInt(string(remainder[:11]), 2, 64)
|
lengthBits, _ := strconv.ParseInt(string(remainder[:11]), 2, 64)
|
||||||
subs, l := parseNPackets(remainder[11:], int(lengthBits))
|
subs, l := parseNPackets(remainder[11:], int(lengthBits))
|
||||||
subPackets = append(subPackets, subs...)
|
subPackets = append(subPackets, subs...)
|
||||||
length = l
|
length += 11 + l
|
||||||
}
|
}
|
||||||
|
|
||||||
return subPackets, length
|
return subPackets, length
|
||||||
|
@@ -1,6 +1,9 @@
|
|||||||
package sixteen
|
package sixteen
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
func Test_hex(t *testing.T) {
|
func Test_hex(t *testing.T) {
|
||||||
original := "8A004A801A8002F478"
|
original := "8A004A801A8002F478"
|
||||||
@@ -50,7 +53,7 @@ func Test_hex4(t *testing.T) {
|
|||||||
|
|
||||||
if vSum != expected {
|
if vSum != expected {
|
||||||
t.Logf("Expected %d, found %d", expected, vSum)
|
t.Logf("Expected %d, found %d", expected, vSum)
|
||||||
// t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,3 +138,121 @@ func Test_operator2(t *testing.T) {
|
|||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_sum(t *testing.T) {
|
||||||
|
original := "C200B40A82"
|
||||||
|
expected := 3
|
||||||
|
|
||||||
|
p := parseHex(original)
|
||||||
|
fmt.Println(p)
|
||||||
|
v := p.value()
|
||||||
|
|
||||||
|
if v != expected {
|
||||||
|
t.Logf("Expected %d, found %d", expected, v)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_product(t *testing.T) {
|
||||||
|
original := "04005AC33890"
|
||||||
|
expected := 54
|
||||||
|
|
||||||
|
p := parseHex(original)
|
||||||
|
v := p.value()
|
||||||
|
|
||||||
|
if v != expected {
|
||||||
|
t.Logf("Expected %d, found %d", expected, v)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_min(t *testing.T) {
|
||||||
|
original := "880086C3E88112"
|
||||||
|
expected := 7
|
||||||
|
|
||||||
|
p := parseHex(original)
|
||||||
|
v := p.value()
|
||||||
|
|
||||||
|
if v != expected {
|
||||||
|
t.Logf("Expected %d, found %d", expected, v)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_max(t *testing.T) {
|
||||||
|
original := "CE00C43D881120"
|
||||||
|
expected := 9
|
||||||
|
|
||||||
|
p := parseHex(original)
|
||||||
|
v := p.value()
|
||||||
|
|
||||||
|
if v != expected {
|
||||||
|
t.Logf("Expected %d, found %d", expected, v)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_less(t *testing.T) {
|
||||||
|
original := "D8005AC2A8F0"
|
||||||
|
expected := 1
|
||||||
|
|
||||||
|
p := parseHex(original)
|
||||||
|
v := p.value()
|
||||||
|
|
||||||
|
if v != expected {
|
||||||
|
t.Logf("Expected %d, found %d", expected, v)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_more(t *testing.T) {
|
||||||
|
original := "F600BC2D8F"
|
||||||
|
expected := 0
|
||||||
|
|
||||||
|
p := parseHex(original)
|
||||||
|
v := p.value()
|
||||||
|
|
||||||
|
if v != expected {
|
||||||
|
t.Logf("Expected %d, found %d", expected, v)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_equal(t *testing.T) {
|
||||||
|
original := "9C005AC2F8F0"
|
||||||
|
expected := 0
|
||||||
|
|
||||||
|
p := parseHex(original)
|
||||||
|
v := p.value()
|
||||||
|
|
||||||
|
if v != expected {
|
||||||
|
t.Logf("Expected %d, found %d", expected, v)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_combo(t *testing.T) {
|
||||||
|
original := "9C0141080250320F1802104A08"
|
||||||
|
expected := 1
|
||||||
|
|
||||||
|
p := parseHex(original)
|
||||||
|
v := p.value()
|
||||||
|
|
||||||
|
if v != expected {
|
||||||
|
t.Logf("Expected %d, found %d", expected, v)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_input(t *testing.T) {
|
||||||
|
expected := 531986792411
|
||||||
|
|
||||||
|
p := load("input.txt")
|
||||||
|
|
||||||
|
v := p.value()
|
||||||
|
|
||||||
|
if v == expected {
|
||||||
|
t.Logf("Expected to not get %d, got %d", expected, v)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
@@ -3,23 +3,22 @@ package sixteen
|
|||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
type Sixteen struct {
|
type Sixteen struct {
|
||||||
bits packet
|
packet packet
|
||||||
}
|
}
|
||||||
|
|
||||||
func Init(filepath string) *Sixteen {
|
func Init(filepath string) *Sixteen {
|
||||||
sixteen := &Sixteen{
|
sixteen := &Sixteen{
|
||||||
bits: packet{},
|
packet: packet{},
|
||||||
}
|
}
|
||||||
|
|
||||||
sixteen.bits = load(filepath)
|
sixteen.packet = load(filepath)
|
||||||
return sixteen
|
return sixteen
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Sixteen) Answer() string {
|
func (d *Sixteen) Answer() string {
|
||||||
return fmt.Sprintf("The sum of the version numbers is %d", d.bits.versionSum())
|
return fmt.Sprintf("The sum of the version numbers is %d", d.packet.versionSum())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Sixteen) FollowUp() string {
|
func (d *Sixteen) FollowUp() string {
|
||||||
return "sixteen part 2 answer for bits"
|
return fmt.Sprintf("The output of the encoded input is %d", d.packet.value())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user