Actual solution for day 16!

This commit is contained in:
2021-12-18 18:34:45 +00:00
parent 719c895220
commit 5c0b7a3b09
4 changed files with 231 additions and 22 deletions

View File

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

View File

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

View File

@@ -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()
} }
} }
@@ -126,7 +129,7 @@ func Test_operator2(t *testing.T) {
} }
if b.subpackets[1].content != 2 { if b.subpackets[1].content != 2 {
t.Logf("Expected second packet to be 2, found %d", b.subpackets[2].content) t.Logf("Expected second packet to be 2, found %d", b.subpackets[2].content)
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()
}
}

View File

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