From 81bfde00b4c0b16b0ec8cac9bfe8e943841e0d5e Mon Sep 17 00:00:00 2001 From: Dreaded_X Date: Thu, 16 Dec 2021 18:42:41 +0100 Subject: [PATCH] 2021 - Day 16 --- 2021/16/go.mod | 9 +++ 2021/16/go.sum | 2 + 2021/16/main.go | 182 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 2021/16/go.mod create mode 100644 2021/16/go.sum create mode 100644 2021/16/main.go diff --git a/2021/16/go.mod b/2021/16/go.mod new file mode 100644 index 0000000..5c17eb2 --- /dev/null +++ b/2021/16/go.mod @@ -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 diff --git a/2021/16/go.sum b/2021/16/go.sum new file mode 100644 index 0000000..8c9f290 --- /dev/null +++ b/2021/16/go.sum @@ -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= diff --git a/2021/16/main.go b/2021/16/main.go new file mode 100644 index 0000000..1f6953f --- /dev/null +++ b/2021/16/main.go @@ -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 + }) +}