advent_of_code_2021

My attempts to work through the 2021 Advent of Code problems.
git clone https://git.eamoncaddigan.net/advent_of_code_2021.git
Log | Files | Refs | README | LICENSE

commit 56752f87bdf5006fee61ebbaadeb1c2d50b4b42e
parent dbeaa80a09e9536763b9d43aec12634492148d3f
Author: Eamon Caddigan <eamon.caddigan@gmail.com>
Date:   Thu, 16 Dec 2021 16:10:56 -0500

Solution to day 2, part 2

Diffstat:
Mday16_classes.py | 49++++++++++++++++++++++++++++++++++++++++++++++++-
Aday16_part2.py | 31+++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/day16_classes.py b/day16_classes.py @@ -1,7 +1,9 @@ """Class definitions for day 16 problems (and maybe other days, we'll see)""" # I'm finally breaking down and doing OOP. -from typing import List, Union +from typing import List, Union, cast +from functools import reduce +from operator import mul class BitReader: """BitReader objects facilitate reading bits a few at a time from a stream @@ -85,3 +87,48 @@ class Packet: children packets (if there are any)""" return self.version + \ sum([p.version_sum() for p in self.contents if isinstance(p, Packet)]) + + def operation_result(self) -> int: + """Perform the operation encoded in the current packet and return its + result""" + result: int = 0 + + if self.type_id == 4: + # Literal value packet: return the value + result = cast(int, self.contents[0]) + + else: + # We'll process all of this operator packet's children + child_results = [p.operation_result() for p in self.contents \ + if isinstance(p, Packet)] + + if self.type_id == 0: + # sum Packet: return the sum of all subpackets + result = sum(child_results) + + elif self.type_id == 1: + # product Packet + result = reduce(mul, child_results) + + elif self.type_id == 2: + # minimum Packet + result = min(child_results) + + elif self.type_id == 3: + # maximum Packet + result = max(child_results) + + elif self.type_id == 5: + # greater than Packet: 1 if the first subpacket is greater than + # the second, otherwise 0 + result = int(child_results[0] > child_results[1]) + + elif self.type_id == 6: + # less than Packet + result = int(child_results[0] < child_results[1]) + + else: + # equal Packet + result = int(child_results[0] == child_results[1]) + + return result diff --git a/day16_part2.py b/day16_part2.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +"""Advent of Code 2021, day 16 (part 2): Packet Decoder +Processing packets using the Buoyancy Interchange Transmission System (BITS)""" + +# Not only am I defining classes for the first time, I'm also allowing myself +# to change part 1 code in order to complete part 2 (I had a feeling I'd be +# adding features to my Packet class) + +from day16_classes import BitReader, Packet +from utils import get_puzzle_input + +def solve_puzzle(input_string: str) -> int: + """Return the numeric solution to the puzzle""" + return Packet(BitReader(input_string)).operation_result() + +def main() -> None: + """Run when the file is called as a script""" + assert solve_puzzle("C200B40A82") == 3 + assert solve_puzzle("04005AC33890") == 54 + assert solve_puzzle("880086C3E88112") == 7 + assert solve_puzzle("CE00C43D881120") == 9 + assert solve_puzzle("D8005AC2A8F0") == 1 + assert solve_puzzle("F600BC2D8F") == 0 + assert solve_puzzle("9C005AC2F8F0") == 0 + assert solve_puzzle("9C0141080250320F1802104A08") == 1 + + print("Packet expression result:", + solve_puzzle(get_puzzle_input(16))) + +if __name__ == "__main__": + main()