diff --git a/src/Year_2015/P12.py b/src/Year_2015/P12.py new file mode 100644 index 0000000..0f61e86 --- /dev/null +++ b/src/Year_2015/P12.py @@ -0,0 +1,67 @@ +# --- Day 12: JSAbacusFramework.io --- + +# Santa's Accounting-Elves need help balancing the books after a recent order. +# Unfortunately, their accounting software uses a peculiar storage format. +# That's where you come in. + +# They have a JSON document which contains a variety of things: arrays +# ([1,2,3]), objects ({"a":1, "b":2}), numbers, and strings. Your first job is +# to simply find all of the numbers throughout the document and add them +# together. + +# For example: + +# [1,2,3] and {"a":2,"b":4} both have a sum of 6. +# [[[3]]] and {"a":{"b":4},"c":-1} both have a sum of 3. +# {"a":[-1,1]} and [-1,{"a":1}] both have a sum of 0. +# [] and {} both have a sum of 0. + +# You will not encounter any strings containing numbers. + +# What is the sum of all numbers in the document? + +import json +import re + +with open("files/P12.txt") as f: + doc = f.read() + +digits = r"[\d-]+" + + +def part_1() -> None: + ans = sum(map(int, re.findall(digits, doc))) + print(f"The sum of all numbers is {ans}") + + +# --- Part Two --- + +# Uh oh - the Accounting-Elves have realized that they double-counted +# everything red. + +# Ignore any object (and all of its children) which has any property with the +# value "red". Do this only for objects ({...}), not arrays ([...]). + +# [1,2,3] still has a sum of 6. +# [1,{"c":"red","b":2},3] now has a sum of 4, because the middle object is +# ignored. +# {"d":"red","e":[1,2,3,4],"f":5} now has a sum of 0, because the entire +# structure is ignored. +# [1,"red",5] has a sum of 6, because "red" in an array has no effect. + + +def ignore_red(dic: dict[str, int]) -> dict[str, int]: + return {} if "red" in dic.values() else dic + + +def part_2() -> None: + # use the object_hook from the json library + doc2 = str(json.loads(doc, object_hook=ignore_red)) + + ans = sum(map(int, re.findall(digits, doc2))) + print(f"The corrected sum of all numbers is {ans}") + + +if __name__ == "__main__": + part_1() + part_2()