Skip to content

migrate 2024 code, refactor #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,000 changes: 1,000 additions & 0 deletions inputs/year_2024/01.dat

Large diffs are not rendered by default.

1,000 changes: 1,000 additions & 0 deletions inputs/year_2024/02.dat

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions inputs/year_2024/03.dat

Large diffs are not rendered by default.

18 changes: 5 additions & 13 deletions scripts/generate_new_day_skeleton_files_from_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import argparse


TEMPLATES_PATH = os.path.join(".", "src", "advent_of_code", "scripts", "templates")
TEMPLATES_PATH = os.path.join("scripts", "templates")


def parse_input_args():
Expand Down Expand Up @@ -45,26 +45,18 @@ def generate_file(template_file_path, input_day, input_year, output_file_path):

if __name__ == "__main__":
args = parse_input_args()
input_day = args.day
input_day_raw = args.day
input_year = args.year
input_day = str(input_day_raw).zfill(2)

day_file_dest = os.path.join(
"src", "advent_of_code", f"year_{input_year}", f"days/{input_day}.py"
"src", "advent_of_code", f"year_{input_year}", f"day_{input_day}.py"
)
template_path = os.path.join(TEMPLATES_PATH, "days_template.txt")
generate_file(template_path, input_day, input_year, day_file_dest)

solvers_file_dest = os.path.join(
"src",
"advent_of_code",
f"year_{input_year}",
f"solvers/day_{input_day}_solvers.py",
)
template_path = os.path.join(TEMPLATES_PATH, "solvers_template.txt")
generate_file(template_path, input_day, input_year, solvers_file_dest)

tests_file_dest = os.path.join(
"tests", f"year_{input_year}", f"test_day_{input_day}_solvers.py"
"tests", f"year_{input_year}", f"test_day_{input_day}.py"
)
template_path = os.path.join(TEMPLATES_PATH, "tests_template.txt")
generate_file(template_path, input_day, input_year, tests_file_dest)
16 changes: 8 additions & 8 deletions scripts/templates/days_template.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from advent_of_code.year_{year}.solvers.day_{day}_solvers import (
solve_day_{day},
)
from advent_of_code.utils.input_handling import read_input, parse_args
from advent_of_code.utils.input_handling import read_input


def main():
args = parse_args()
input = read_input(args.input_file)
result_part_1, result_part_2 = solve_day_{day}(input)
def solve(input):
return (None, None)


def main(input_file):
input = read_input(input_file)
(result_part_1, result_part_2) = solve(input)
print(
f"Day {day}: "
f" Result for part 1 is {result_part_1}. "
Expand Down
3 changes: 0 additions & 3 deletions scripts/templates/solvers_template.txt

This file was deleted.

4 changes: 2 additions & 2 deletions scripts/templates/tests_template.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest
from advent_of_code.year_{year}.solvers.day_{day}_solvers import (
solve_day_{day},
from advent_of_code.year_{year}.day_{day} import (
solve,
)


Expand Down
9 changes: 9 additions & 0 deletions src/advent_of_code/utils/input_handling.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,12 @@ def parse_args():
parser.add_argument("--part", type=int)
args = parser.parse_args()
return args


def read_side_by_side_list_format(data):
list1, list2 = [], []
for line in data:
list1.append(int(line.split()[0]))
list2.append(int(line.split()[1]))

return (list1, list2)
54 changes: 54 additions & 0 deletions src/advent_of_code/year_2024/day_01.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from advent_of_code.utils.input_handling import read_input, read_side_by_side_list_format

def compute_distance(i, j):
return abs(i - j)


def solve_part_1(parsed_input):
(list1, list2) = parsed_input
list1_ordered = list(sorted(list1))
list2_ordered = list(sorted(list2))

total_distance = 0

for i, j in zip(list1_ordered, list2_ordered):
total_distance += compute_distance(i, j)

return total_distance


def compute_similarity(i, lst):
return i * lst.count(i)


def solve_part_2(parsed_input):
(list1, list2) = parsed_input

total_similarity_score = 0

for element in list1:
total_similarity_score += compute_similarity(element, list2)

return total_similarity_score



def solve(input):
parsed_input = read_side_by_side_list_format(input)
part_1_solution = solve_part_1(parsed_input)
part_2_solution = solve_part_2(parsed_input)
return (part_1_solution, part_2_solution)


def main(input_file):
input = read_input(input_file)
(result_part_1, result_part_2) = solve(input)
print(
f"Day 01: "
f" Result for part 1 is {result_part_1}. "
f" Result for part 2 is {result_part_2}. "
)


if __name__ == "__main__":
main()
62 changes: 62 additions & 0 deletions src/advent_of_code/year_2024/day_02.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from advent_of_code.utils.input_handling import read_input

def is_report_safe(report,):
if not ((report==sorted(report)) or (report==sorted(report,reverse=True))):
return False

differences = [abs(report[i+1] - report[i]) for i in range(len(report) - 1)]
if ((max(differences) > 3) or (min(differences)<1)):
return False

return True


def solve_part_1(input):
safe_report_count = 0
for report in input:
if is_report_safe(report):
safe_report_count += 1
return safe_report_count


def solve_part_2(input,):

safe_report_count = 0

for report in input:
if is_report_safe(report):
safe_report_count += 1
else:
for idx, _ in enumerate(report):
tmp_report = report[:]
del tmp_report[idx]
if is_report_safe(tmp_report,):
safe_report_count += 1
break
return safe_report_count


def solve(input):
part_1_solution = solve_part_1(input)
part_2_solution = solve_part_2(input)
return (part_1_solution, part_2_solution)


def parse_input(input_data,dtype=int):
data = [list(map(dtype, line.rstrip("\n").split())) for line in input_data]
return data


def main(input_file):
unparsed_input = read_input(input_file)
parsed_input = parse_input(unparsed_input)
(result_part_1, result_part_2) = solve(parsed_input)
print(
f"Day 02: "
f" Result for part 1 is {result_part_1}. "
f" Result for part 2 is {result_part_2}. "
)


if __name__ == "__main__":
main()
60 changes: 60 additions & 0 deletions src/advent_of_code/year_2024/day_03.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

import re
import math

DO_SUBSTR = 'do()'
DONT_SUBSTR = 'don\'t()'

def find_valid_substrings(s, match_str=r'mul\(\d+,\d+\)'):
return re.findall(match_str, s)

def find_and_multiply_valid_muls_in_string(input_string):
string_score = 0
valid_muls = find_valid_substrings(input_string)
for m in valid_muls:
found_ints = find_valid_substrings(m, match_str=r'\d+')
string_score += math.prod(map(int, found_ints))
return string_score

def instruction_compute(instruction, use_do_dont_rule=False):

if not use_do_dont_rule:
instruction_score = find_and_multiply_valid_muls_in_string(instruction)
else:
instruction_score=0
padded_instruction = DO_SUBSTR+instruction.strip("\n")+DONT_SUBSTR
valid_subs = find_valid_substrings(
padded_instruction,
match_str=r"mul\((\d+),(\d+)\)|(do\(\))|(don't\(\))"
)
counting_active = False
for (i, j, do, dont) in valid_subs:
if do:
counting_active = True
elif dont:
counting_active = False
else:
if counting_active:
instruction_score += int(i)*int(j)
return instruction_score

def solve(input):

part_1_solution, part_2_solution = 0, 0
part_1_solution = instruction_compute(input, False)
part_2_solution = instruction_compute(input, True)
return (part_1_solution, part_2_solution)


def main(input_file):
input = input = open(input_file).read()
(result_part_1, result_part_2) = solve(input)
print(
f"Day 03: "
f" Result for part 1 is {result_part_1}. "
f" Result for part 2 is {result_part_2}. "
)


if __name__ == "__main__":
main()
26 changes: 26 additions & 0 deletions tests/year_2024/test_day_01.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import pytest
from advent_of_code.year_2024.day_01 import (
solve,
)


@pytest.fixture
def day_01_test_input():
return [
"3 4",
"4 3",
"2 5",
"1 3",
"3 9",
"3 3",
]


@pytest.fixture
def day_01_expected_output():
return (11, 31)


def test_solver(day_01_test_input, day_01_expected_output):
result = solve(day_01_test_input)
assert result == day_01_expected_output
28 changes: 28 additions & 0 deletions tests/year_2024/test_day_02.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import pytest
from advent_of_code.year_2024.day_02 import (
solve,
parse_input,
)


@pytest.fixture
def day_02_test_input():
return [
"7 6 4 2 1",
"1 2 7 8 9",
"9 7 6 2 1",
"1 3 2 4 5",
"8 6 4 4 1",
"1 3 6 7 9",
]


@pytest.fixture
def day_02_expected_output():
return (2,4)


def test_solver(day_02_test_input, day_02_expected_output):
day_02_test_input_parsed = parse_input(day_02_test_input)
result = solve(day_02_test_input_parsed)
assert result == day_02_expected_output
18 changes: 18 additions & 0 deletions tests/year_2024/test_day_03.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import pytest
from advent_of_code.year_2024.day_03 import (
instruction_compute,
)

@pytest.mark.parametrize("input, use_do_dont_rule, expected", [
["xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))", False, 161],
["xmul(2,4)", False, 8],
["%&mul[3,7]!@^do_not_mul(5,5)", False, 25],
["mul(11,8)mul(8,5)", False, 128],
["xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))", True, 48],
])
def test_instruction_compute(input, use_do_dont_rule, expected):
result = instruction_compute(input, use_do_dont_rule=use_do_dont_rule)
print(result)
assert result == expected


Loading