2021 Day 16 Complete

This commit is contained in:
Brian Buller 2021-12-16 10:02:14 -06:00
parent 5aaf7163dc
commit e91157fca7
12 changed files with 251 additions and 0 deletions

1
2021/day16/input Normal file
View File

@ -0,0 +1 @@
E0529D18025800ABCA6996534CB22E4C00FB48E233BAEC947A8AA010CE1249DB51A02CC7DB67EF33D4002AE6ACDC40101CF0449AE4D9E4C071802D400F84BD21CAF3C8F2C35295EF3E0A600848F77893360066C200F476841040401C88908A19B001FD35CCF0B40012992AC81E3B980553659366736653A931018027C87332011E2771FFC3CEEC0630A80126007B0152E2005280186004101060C03C0200DA66006B8018200538012C01F3300660401433801A6007380132DD993100A4DC01AB0803B1FE2343500042E24C338B33F5852C3E002749803B0422EC782004221A41A8CE600EC2F8F11FD0037196CF19A67AA926892D2C643675A0C013C00CC0401F82F1BA168803510E3942E969C389C40193CFD27C32E005F271CE4B95906C151003A7BD229300362D1802727056C00556769101921F200AC74015960E97EC3F2D03C2430046C0119A3E9A3F95FD3AFE40132CEC52F4017995D9993A90060729EFCA52D3168021223F2236600ECC874E10CC1F9802F3A71C00964EC46E6580402291FE59E0FCF2B4EC31C9C7A6860094B2C4D2E880592F1AD7782992D204A82C954EA5A52E8030064D02A6C1E4EA852FE83D49CB4AE4020CD80272D3B4AA552D3B4AA5B356F77BF1630056C0119FF16C5192901CEDFB77A200E9E65EAC01693C0BCA76FEBE73487CC64DEC804659274A00CDC401F8B51CE3F8803B05217C2E40041A72E2516A663F119AC72250A00F44A98893C453005E57415A00BCD5F1DD66F3448D2600AC66F005246500C9194039C01986B317CDB10890C94BF68E6DF950C0802B09496E8A3600BCB15CA44425279539B089EB7774DDA33642012DA6B1E15B005C0010C8C917A2B880391160944D30074401D845172180803D1AA3045F00042630C5B866200CC2A9A5091C43BBD964D7F5D8914B46F040

240
2021/day16/main.go Normal file
View File

@ -0,0 +1,240 @@
package main
import (
"fmt"
"os"
h "git.bullercodeworks.com/brian/adventofcode/helpers"
)
func main() {
inp := h.StdinToString()
var arg string
if len(os.Args) > 1 {
arg = os.Args[1]
}
p := ParsePacket(inp)
if arg == "--json" {
fmt.Println(p.Json())
} else {
fmt.Println("# Part 1")
fmt.Println("Version Sum:", CalculateVersionSum(p))
fmt.Println()
fmt.Println("# Part 2")
fmt.Println("Value:", p.value)
}
}
func CalculateVersionSum(p *Packet) int {
sum := p.version
for s := range p.packets {
sum += CalculateVersionSum(p.packets[s])
}
return sum
}
const (
PacketTypeSum = iota
PacketTypeProduct
PacketTypeMin
PacketTypeMax
PacketTypeLiteral
PacketTypeGreater
PacketTypeLess
PacketTypeEqual
LengthTypeBits = 0
LengthTypeSubPackets = 1
)
type Packet struct {
version int
packetType int
value int
// Operator
lengthTypeId int
subLength int
// Sub-packets
packets []*Packet
binaryString string
}
func ParsePacket(inp string) *Packet {
var bin string
for i := 0; i < len(inp); i += 2 {
if len(inp) >= i+2 {
bin += fmt.Sprintf("%08b", HexToByte(inp[i:i+2]))
}
}
return ParseBinaryPacket(bin)
}
func ParseBinaryPacket(inp string) *Packet {
p := Packet{
binaryString: inp,
}
// Parse the version
for i := 0; i < 3; i++ {
p.version = p.version << 1
if p.binaryString[i] == '1' {
p.version |= 1
}
}
for i := 3; i < 6; i++ {
p.packetType = p.packetType << 1
if p.binaryString[i] == '1' {
p.packetType |= 1
}
}
if p.packetType == PacketTypeLiteral {
p.parseLiteral()
} else {
p.parseOperator()
}
return &p
}
func (p *Packet) parseLiteral() {
// The bits for the literal start at bit 7
// Every 5 bits is a chunk of the literal
ptr := 6
more := true
for more {
more = (p.binaryString[ptr] == '1')
ptr++
for i := 0; i < 4; i++ {
p.value = p.value << 1
if p.binaryString[ptr] == '1' {
p.value |= 1
}
ptr++
}
}
p.binaryString = p.binaryString[:ptr]
}
func (p *Packet) parseOperator() {
ptr := 6
p.lengthTypeId = int(p.binaryString[ptr] - '0')
ptr++
if p.lengthTypeId == LengthTypeBits {
for i := 0; i < 15; i++ {
p.subLength = p.subLength << 1
if p.binaryString[ptr] == '1' {
p.subLength |= 1
}
ptr++
}
length := p.subLength
for length > 0 {
sp := ParseBinaryPacket(p.binaryString[ptr:])
p.packets = append(p.packets, sp)
ptr += len(sp.binaryString)
length -= len(sp.binaryString)
}
p.binaryString = p.binaryString[:ptr]
} else if p.lengthTypeId == LengthTypeSubPackets {
for i := 0; i < 11; i++ {
p.subLength = p.subLength << 1
if p.binaryString[ptr] == '1' {
p.subLength |= 1
}
ptr++
}
length := p.subLength
for length > 0 {
sp := ParseBinaryPacket(p.binaryString[ptr:])
p.packets = append(p.packets, sp)
ptr += len(sp.binaryString)
length--
}
p.binaryString = p.binaryString[:ptr]
}
switch p.packetType {
case PacketTypeSum:
for _, sp := range p.packets {
p.value += sp.value
}
case PacketTypeProduct:
p.value = 1
for _, sp := range p.packets {
p.value *= sp.value
}
case PacketTypeMin:
p.value = h.MAX_INT
for _, sp := range p.packets {
if sp.value < p.value {
p.value = sp.value
}
}
case PacketTypeMax:
p.value = h.MIN_INT
for _, sp := range p.packets {
if sp.value > p.value {
p.value = sp.value
}
}
case PacketTypeGreater:
if len(p.packets) == 2 && (p.packets[0].value > p.packets[1].value) {
p.value = 1
} else {
p.value = 0
}
case PacketTypeLess:
if len(p.packets) == 2 && (p.packets[0].value < p.packets[1].value) {
p.value = 1
} else {
p.value = 0
}
case PacketTypeEqual:
if len(p.packets) == 2 && (p.packets[0].value == p.packets[1].value) {
p.value = 1
} else {
p.value = 0
}
}
}
func (p Packet) Json() string {
ret := fmt.Sprintf("{\"version\":%d, \"type\":%d, \"value\":%d,", p.version, p.packetType, p.value)
ret += "\"packets\":["
for i := range p.packets {
ret += fmt.Sprintf("%s", p.packets[i].String())
if i < len(p.packets)-1 {
ret += ","
}
}
ret += fmt.Sprintf("],\"binary\":\"%s\"}", p.binaryString)
return ret
}
func (p Packet) String() string {
if p.packetType == PacketTypeLiteral {
return fmt.Sprintf("%d", p.value)
} else {
return p.Json()
}
}
func HexToByte(h string) byte {
var b byte
for i := range h {
var wrk byte
if h[i] >= '0' && h[i] <= '9' {
wrk = byte(h[i] - '0')
} else if h[i] >= 'A' && h[i] <= 'F' {
wrk = byte(h[i]-'A') + 10
}
if i == 0 {
b = wrk << 4
} else {
b |= wrk
}
}
return b
}

View File

@ -0,0 +1 @@
D2FE28

View File

@ -0,0 +1 @@
D2FE28FEDCBA987654321

View File

@ -0,0 +1 @@
38006F45291200

View File

@ -0,0 +1 @@
38006F45291200FEDCBA0987654321

View File

@ -0,0 +1 @@
EE00D40C823060

1
2021/day16/test.json Normal file
View File

@ -0,0 +1 @@
{"version":0, "type":1, "binary":"00000100000000000101101011000011001110001001",'packets':[6,9]}

1
2021/day16/testinput1 Normal file
View File

@ -0,0 +1 @@
8A004A801A8002F478

1
2021/day16/testinput2 Normal file
View File

@ -0,0 +1 @@
620080001611562C8802118E34

1
2021/day16/testinput3 Normal file
View File

@ -0,0 +1 @@
C0015000016115A2E0802F182340

1
2021/day16/testinput4 Normal file
View File

@ -0,0 +1 @@
A0016C880162017C3686B18A3D4780