diff --git a/pyproject.toml b/pyproject.toml index 1190636..1b4a85d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,11 +31,6 @@ force_grid_wrap = 0 use_parentheses = true line_length = 79 -[tool.mypy] -pretty = true -show_traceback = true -allow_redefinition = true - [tool.black] line-length = 79 target-version = ['py38'] @@ -59,3 +54,6 @@ exclude = ''' # the root of the project ) ''' + +[tool.ruff.lint] +ignore = ["E402"] diff --git a/src/Year_2023/Day01.py b/src/Year_2023/Day01.py new file mode 100644 index 0000000..0542db1 --- /dev/null +++ b/src/Year_2023/Day01.py @@ -0,0 +1,130 @@ +# --- Day 1: Trebuchet?! --- + +# Something is wrong with global snow production, and you've been selected to +# take a look. The Elves have even given you a map; on it, they've used stars to +# mark the top fifty locations that are likely to be having problems. + +# You've been doing this long enough to know that to restore snow operations, +# you need to check all fifty stars by December 25th. + +# Collect stars by solving puzzles. Two puzzles will be made available on each +# day in the Advent calendar; the second puzzle is unlocked when you complete +# the first. Each puzzle grants one star. Good luck! + +# You try to ask why they can't just use a weather machine ("not powerful +# enough") and where they're even sending you ("the sky") and why your map looks +# mostly blank ("you sure ask a lot of questions") and hang on did you just say +# the sky ("of course, where do you think snow comes from") when you realize +# that the Elves are already loading you into a trebuchet ("please hold still, +# we need to strap you in"). + +# As they're making the final adjustments, they discover that their calibration +# document (your puzzle input) has been amended by a very young Elf who was +# apparently just excited to show off her art skills. Consequently, the Elves +# are having trouble reading the values on the document. + +# The newly-improved calibration document consists of lines of text; each line +# originally contained a specific calibration value that the Elves now need to +# recover. On each line, the calibration value can be found by combining the +# first digit and the last digit (in that order) to form a single two-digit +# number. + +# For example: + +# 1abc2 +# pqr3stu8vwx +# a1b2c3d4e5f +# treb7uchet + +# In this example, the calibration values of these four lines are 12, 38, 15, +# and 77. Adding these together produces 142. + +# Consider your entire calibration document. What is the sum of all of the +# calibration values? + +with open("files/P1.txt") as f: + calibration = [line for line in f.read().strip().split()] + + +def part_1(): + total = 0 + for value in calibration: + digits = [c for c in value if c.isdigit()] + if digits: + total += int(digits[0] + digits[-1]) + print(f"The sum of all calibration values is {total}") + + +# --- Part Two --- + +# Your calculation isn't quite right. It looks like some of the digits are +# actually spelled out with letters: one, two, three, four, five, six, seven, +# eight, and nine also count as valid "digits". + +# Equipped with this new information, you now need to find the real first and +# last digit on each line. For example: + +# two1nine +# eightwothree +# abcone2threexyz +# xtwone3four +# 4nineeightseven2 +# zoneight234 +# 7pqrstsixteen + +# In this example, the calibration values are 29, 83, 13, 24, 42, 14, and 76. +# Adding these together produces 281. + +# What is the sum of all of the calibration values? + +import re + +words_to_numbers = { + "one": "1", + "two": "2", + "three": "3", + "four": "4", + "five": "5", + "six": "6", + "seven": "7", + "eight": "8", + "nine": "9", +} + + +def is_letter(char): + return "a" <= char <= "z" + + +def extraction(value): + word = "" + digits = [] + for c in value: + if c.isdigit(): + digits.append(c) + word = "" + elif is_letter(c): + word += c + for w in words_to_numbers: + if w in word: + m = re.search(w, word) + if m: + val = m.group(0) + digits.append(words_to_numbers[str(val)]) + # keep last letter! + word = c + break + return digits + + +def part_2(): + total = 0 + for value in calibration: + digits = extraction(value) + total += int(digits[0] + digits[-1]) + print(f"The sum of all calibration values is {total}") + + +if __name__ == "__main__": + part_1() + part_2()