import logging import re from functools import reduce from itertools import pairwise from sys import stdout # It seems like the goal of the program is just to multiply some numbers. # It does that with instructions like mul(X,Y), where X and Y are each 1-3 # digit numbers. For instance, mul(44,46) multiplies 44 by 46 to get a # result of 2024. Similarly, mul(123,4) would multiply 123 by 4. # However, because the program's memory has been corrupted, there are also # many invalid characters that should be ignored, even if they look like # part of a mul instruction. Sequences like mul(4*, mul(6,9!, ?(12,34), or # mul ( 2 , 4 ) do nothing. # For example, consider the following section of corrupted memory: # xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5)) # Adding up the result of each real instruction produces 161 # (2*4 + 5*5 + 11*8 + 8*5). LOG_FILENAME = "./day03-1.log" INPUT_FILENAME = "./input03.txt" logger = logging.Logger(__name__) formatter = logging.Formatter('[%(asctime)s][%(levelname)s] %(message)s') sh = logging.StreamHandler(stdout) sh.setLevel(logging.INFO) sh.setFormatter(formatter) fh = logging.FileHandler(LOG_FILENAME, mode="w", encoding="utf-8") fh.setLevel(logging.DEBUG) fh.setFormatter(formatter) logger.addHandler(sh) logger.addHandler(fh) def multiply_pair(s): pair = [int(x) for x in s[4:-1].split(",")] return reduce(lambda x,y: x*y, pair, 1) def main(): with open(INPUT_FILENAME, "r") as f: line = "".join(f.readlines()) MUL_REGEX = r"mul\(\d{1,3},\d{1,3}\)" matches = re.findall(MUL_REGEX, line) total_sum = reduce(lambda x,y: x+y, map(multiply_pair, matches)) print(f"Total sum: {total_sum}") if __name__ == "__main__": main()