feat: Redo of the AoC repo starting over with 2015 and keeping up with
2025 (completed day 2 so far)
This commit is contained in:
commit
c936d7d573
BIN
15/1/__pycache__/main.cpython-313.pyc
Normal file
BIN
15/1/__pycache__/main.cpython-313.pyc
Normal file
Binary file not shown.
BIN
15/1/__pycache__/test_day1.cpython-313-pytest-8.4.2.pyc
Normal file
BIN
15/1/__pycache__/test_day1.cpython-313-pytest-8.4.2.pyc
Normal file
Binary file not shown.
BIN
15/1/__pycache__/test_day1.cpython-313-pytest-9.0.1.pyc
Normal file
BIN
15/1/__pycache__/test_day1.cpython-313-pytest-9.0.1.pyc
Normal file
Binary file not shown.
59
15/1/main.py
Normal file
59
15/1/main.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
'''Day 1 of 2015 AOC'''
|
||||||
|
|
||||||
|
def process_input_string(input_string: str) -> int:
|
||||||
|
'''Take in an input string and give back the floor number based on the instructions.
|
||||||
|
|
||||||
|
Keyword Args:
|
||||||
|
input_string (str) - String of encoded instructions
|
||||||
|
|
||||||
|
Return:
|
||||||
|
int - Floor number
|
||||||
|
'''
|
||||||
|
curr_floor = 0
|
||||||
|
|
||||||
|
for char in input_string:
|
||||||
|
if char == '(':
|
||||||
|
curr_floor += 1
|
||||||
|
elif char == ')':
|
||||||
|
curr_floor -= 1
|
||||||
|
|
||||||
|
return curr_floor
|
||||||
|
|
||||||
|
|
||||||
|
def find_the_basement(input_string: str) -> int:
|
||||||
|
'''Take in an input string of instructions and give back the position of the instruction entering the basement, or hitting floor "-1".
|
||||||
|
|
||||||
|
Keyword Args:
|
||||||
|
input_string (str) - String of encoded instructions
|
||||||
|
|
||||||
|
Return:
|
||||||
|
int - Position of instruction in the string
|
||||||
|
'''
|
||||||
|
curr_floor = 0
|
||||||
|
|
||||||
|
for index, char in enumerate(input_string):
|
||||||
|
if char == '(':
|
||||||
|
curr_floor += 1
|
||||||
|
elif char == ')':
|
||||||
|
curr_floor -= 1
|
||||||
|
|
||||||
|
if curr_floor == -1:
|
||||||
|
# Add one to give the 1s based position instead of the 0s based index
|
||||||
|
return index + 1
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
'''Entrypoint'''
|
||||||
|
with open('input.txt', encoding='utf-8') as fh:
|
||||||
|
input_string = fh.readline()
|
||||||
|
output = process_input_string(input_string)
|
||||||
|
|
||||||
|
print(f'Part 1: {output}')
|
||||||
|
|
||||||
|
output = find_the_basement(input_string)
|
||||||
|
|
||||||
|
print(f'Part 2: {output}')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
28
15/1/test_day1.py
Normal file
28
15/1/test_day1.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from main import find_the_basement, process_input_string
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('test_input, expected',
|
||||||
|
[
|
||||||
|
('(())', 0),
|
||||||
|
('()()', 0),
|
||||||
|
('(((', 3),
|
||||||
|
('(()(()(', 3),
|
||||||
|
('))(((((', 3),
|
||||||
|
('())', -1),
|
||||||
|
('))(', -1),
|
||||||
|
(')))', -3),
|
||||||
|
(')())())', -3)
|
||||||
|
])
|
||||||
|
def test_instruction_examples(test_input, expected):
|
||||||
|
assert process_input_string(test_input) == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('test_input, expected',
|
||||||
|
[
|
||||||
|
(')', 1),
|
||||||
|
('()())', 5)
|
||||||
|
])
|
||||||
|
def test_basement_instructions(test_input, expected):
|
||||||
|
assert find_the_basement(test_input) == expected
|
||||||
BIN
15/2/__pycache__/main.cpython-313.pyc
Normal file
BIN
15/2/__pycache__/main.cpython-313.pyc
Normal file
Binary file not shown.
BIN
15/2/__pycache__/test_day2.cpython-313-pytest-9.0.1.pyc
Normal file
BIN
15/2/__pycache__/test_day2.cpython-313-pytest-9.0.1.pyc
Normal file
Binary file not shown.
38
15/2/main.py
Normal file
38
15/2/main.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
'''AoC day 2'''
|
||||||
|
|
||||||
|
def get_surface_area(l: int, w: int, h: int) -> int:
|
||||||
|
'''Take the dimensions of the box and return its surface area
|
||||||
|
|
||||||
|
Keyword args:
|
||||||
|
l (int) - Length
|
||||||
|
w (int) - Width
|
||||||
|
h (int) - Height
|
||||||
|
'''
|
||||||
|
return 2*l*w + 2*w*h + 2*h*l
|
||||||
|
|
||||||
|
def get_slack_amount(l: int, w: int, h: int) -> int:
|
||||||
|
'''Take dimensions and return the value of the smallest'''
|
||||||
|
return min([l*w, w*h, h*l])
|
||||||
|
|
||||||
|
def get_ribbon_amount(l: int, w: int, h: int) -> int:
|
||||||
|
return min([2*h + 2*w, 2*l + 2*w, 2*h + 2*l]) + (l*w*h)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
'''Entrypoint'''
|
||||||
|
# Surface area for wrapping paper
|
||||||
|
with open('input.txt', encoding='utf-8') as fh:
|
||||||
|
sum = 0
|
||||||
|
r_sum = 0
|
||||||
|
|
||||||
|
for line in fh:
|
||||||
|
l, w, h = [int(x) for x in line.split('x')]
|
||||||
|
# print(f'{l} {w} {h}')
|
||||||
|
sum += get_surface_area(l, w, h)
|
||||||
|
sum += get_slack_amount(l, w, h)
|
||||||
|
r_sum += get_ribbon_amount(l, w, h)
|
||||||
|
|
||||||
|
print(f'Part 1, sum of wrapping paper: {sum}')
|
||||||
|
print(f'Part 2, sum of ribbon: {r_sum}')
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
27
15/2/test_day2.py
Normal file
27
15/2/test_day2.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from main import get_slack_amount, get_surface_area, get_ribbon_amount
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('l, w, h, expected',
|
||||||
|
[
|
||||||
|
(2, 3, 4, 52),
|
||||||
|
(1, 1, 10, 42)
|
||||||
|
])
|
||||||
|
def test_surface_area(l, w, h, expected):
|
||||||
|
assert get_surface_area(l, w, h) == expected
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('l, w, h, expected',
|
||||||
|
[
|
||||||
|
(2, 3, 4, 6),
|
||||||
|
(1, 1, 10, 1)
|
||||||
|
])
|
||||||
|
def test_slack_amount(l, w, h, expected):
|
||||||
|
assert get_slack_amount(l, w, h) == expected
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('l, w, h, expected',
|
||||||
|
[
|
||||||
|
(2, 3, 4, 34),
|
||||||
|
(1, 1, 10, 14)
|
||||||
|
])
|
||||||
|
def test_ribbon_amount(l, w, h, expected):
|
||||||
|
assert get_ribbon_amount(l, w, h) == expected
|
||||||
BIN
15/3/__pycache__/main.cpython-313.pyc
Normal file
BIN
15/3/__pycache__/main.cpython-313.pyc
Normal file
Binary file not shown.
BIN
15/3/__pycache__/test_day3.cpython-313-pytest-9.0.1.pyc
Normal file
BIN
15/3/__pycache__/test_day3.cpython-313-pytest-9.0.1.pyc
Normal file
Binary file not shown.
66
15/3/main.py
Normal file
66
15/3/main.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
'''AoC day 2'''
|
||||||
|
|
||||||
|
def get_new_pos(curr_pos, instruction):
|
||||||
|
if instruction == '<':
|
||||||
|
new_pos = (curr_pos[0] - 1, curr_pos[1])
|
||||||
|
elif instruction == '>':
|
||||||
|
new_pos = (curr_pos[0] + 1, curr_pos[1])
|
||||||
|
elif instruction == '^':
|
||||||
|
new_pos = (curr_pos[0], curr_pos[1] + 1)
|
||||||
|
elif instruction == 'v':
|
||||||
|
new_pos = (curr_pos[0], curr_pos[1] - 1)
|
||||||
|
else:
|
||||||
|
new_pos = (0, 0)
|
||||||
|
|
||||||
|
return new_pos
|
||||||
|
|
||||||
|
|
||||||
|
def process_instructions(instruction_set: str) -> int:
|
||||||
|
'''Run through a set of instructions to return the number of unique houses visited
|
||||||
|
|
||||||
|
Keyword args:
|
||||||
|
instruction_set (str) - Directional arrow instruction string giving moves to new locations
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int - Number of unique houses visited
|
||||||
|
'''
|
||||||
|
visited_house_coordinates = {(0,0)}
|
||||||
|
curr_pos = (0, 0)
|
||||||
|
|
||||||
|
for instruction in instruction_set:
|
||||||
|
curr_pos = get_new_pos(curr_pos, instruction)
|
||||||
|
|
||||||
|
visited_house_coordinates.add(curr_pos)
|
||||||
|
|
||||||
|
return len(visited_house_coordinates)
|
||||||
|
|
||||||
|
def process_robo_instructions(instruction_set: str) -> int:
|
||||||
|
visited_house_coordinates = {(0,0)}
|
||||||
|
santa_pos = (0,0)
|
||||||
|
robot_pos = (0,0)
|
||||||
|
|
||||||
|
for index, instruction in enumerate(instruction_set):
|
||||||
|
if index % 2 == 0:
|
||||||
|
santa_pos = get_new_pos(santa_pos, instruction)
|
||||||
|
visited_house_coordinates.add(santa_pos)
|
||||||
|
else:
|
||||||
|
robot_pos = get_new_pos(robot_pos, instruction)
|
||||||
|
visited_house_coordinates.add(robot_pos)
|
||||||
|
|
||||||
|
return len(visited_house_coordinates)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
'''Entrypoint'''
|
||||||
|
with open('input.txt', encoding='utf-8') as fh:
|
||||||
|
instruction_set = fh.readline()
|
||||||
|
unique_houses = process_instructions(instruction_set)
|
||||||
|
|
||||||
|
print(f'Part1: {unique_houses}')
|
||||||
|
|
||||||
|
robo_houses = process_robo_instructions(instruction_set)
|
||||||
|
|
||||||
|
print(f'Part2: {robo_houses}')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
20
15/3/test_day3.py
Normal file
20
15/3/test_day3.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from main import process_instructions, process_robo_instructions
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('given, expected',
|
||||||
|
[
|
||||||
|
('>', 2),
|
||||||
|
('^>v<', 4),
|
||||||
|
('^v^v^v^v^v', 2)
|
||||||
|
])
|
||||||
|
def test_instructions(given, expected):
|
||||||
|
assert process_instructions(given) == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('given, expected',
|
||||||
|
[
|
||||||
|
('^v', 3)
|
||||||
|
])
|
||||||
|
def test_part2_instructions(given, expected):
|
||||||
|
assert process_robo_instructions(given) == expected
|
||||||
BIN
15/4/__pycache__/main.cpython-313.pyc
Normal file
BIN
15/4/__pycache__/main.cpython-313.pyc
Normal file
Binary file not shown.
BIN
15/4/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc
Normal file
BIN
15/4/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc
Normal file
Binary file not shown.
26
15/4/main.py
Normal file
26
15/4/main.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import hashlib
|
||||||
|
|
||||||
|
def search_hashes(secret: str, match_str: str) -> int:
|
||||||
|
num = 1
|
||||||
|
|
||||||
|
while True:
|
||||||
|
search_string_bytes = (secret + str(num)).encode()
|
||||||
|
|
||||||
|
hash_string = hashlib.md5(search_string_bytes).hexdigest()
|
||||||
|
|
||||||
|
if hash_string.startswith(match_str):
|
||||||
|
return num
|
||||||
|
|
||||||
|
num += 1
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
num = search_hashes('ckczppom', '00000')
|
||||||
|
print(f'Part1: {num}')
|
||||||
|
|
||||||
|
num = search_hashes('ckczppom', '000000')
|
||||||
|
print(f'Part2: {num}')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
11
15/4/test_main.py
Normal file
11
15/4/test_main.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from main import search_hashes
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('given, match, expected',
|
||||||
|
[
|
||||||
|
('abcdef', '00000', 609043),
|
||||||
|
('pqrstuv', '00000', 1048970)
|
||||||
|
])
|
||||||
|
def test_searching(given, match, expected):
|
||||||
|
assert search_hashes(given, match) == expected
|
||||||
BIN
15/5/__pycache__/main.cpython-313.pyc
Normal file
BIN
15/5/__pycache__/main.cpython-313.pyc
Normal file
Binary file not shown.
BIN
15/5/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc
Normal file
BIN
15/5/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc
Normal file
Binary file not shown.
81
15/5/main.py
Normal file
81
15/5/main.py
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
def check_contains_no_bad_chars(test: str) -> bool:
|
||||||
|
bad_chars = ['ab', 'cd', 'pq', 'xy']
|
||||||
|
|
||||||
|
if any(el in test for el in bad_chars):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def check_doubled_char(input: str) -> bool:
|
||||||
|
for index, letter in enumerate(input):
|
||||||
|
if index - 1 > 0 and input[index - 1] == letter:
|
||||||
|
return True
|
||||||
|
if index + 1 < len(input) and input[index + 1] == letter:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_vowel_count(input: str) -> bool:
|
||||||
|
'''Give a count of vowels in a string
|
||||||
|
|
||||||
|
Keyword args:
|
||||||
|
input (str) - String to search to vowels
|
||||||
|
|
||||||
|
Return:
|
||||||
|
int - The number of found vowels
|
||||||
|
'''
|
||||||
|
sum = 0
|
||||||
|
|
||||||
|
for letter in input:
|
||||||
|
if letter in 'aeiou':
|
||||||
|
sum += 1
|
||||||
|
|
||||||
|
if sum > 2:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def check_if_nice(test: str) -> bool:
|
||||||
|
if check_contains_no_bad_chars(test) and check_doubled_char(test) and check_vowel_count(test):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_nonoverlapping_repeats(test: str) -> bool:
|
||||||
|
splitup = [test[i:i+2] for i in range(0, len(test), 2)]
|
||||||
|
|
||||||
|
for el in splitup:
|
||||||
|
check = splitup.pop()
|
||||||
|
if check in splitup:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def check_repeat_everyother(test: str) -> bool:
|
||||||
|
for index, letter in enumerate(test):
|
||||||
|
if index + 2 < len(test) and test[index+2] == letter:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def check_if_nice_part2(test: str) -> bool:
|
||||||
|
return check_nonoverlapping_repeats(test) and check_repeat_everyother(test)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
with open('input.txt', encoding='utf-8') as fh:
|
||||||
|
total = 0
|
||||||
|
|
||||||
|
for line in fh:
|
||||||
|
# print(line.strip())
|
||||||
|
|
||||||
|
if check_if_nice(line.strip()):
|
||||||
|
total += 1
|
||||||
|
|
||||||
|
print(f'Part1: {total}')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
77
15/5/test_main.py
Normal file
77
15/5/test_main.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from main import check_contains_no_bad_chars, check_doubled_char, check_vowel_count, check_if_nice, check_nonoverlapping_repeats, check_repeat_everyother, check_if_nice_part2
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('given, expected',
|
||||||
|
[
|
||||||
|
('aei', True),
|
||||||
|
('xazegov', True),
|
||||||
|
('aeiouaeiouaeiou', True),
|
||||||
|
('mnqpcbt', False)
|
||||||
|
])
|
||||||
|
def test_vowel_counting(given, expected):
|
||||||
|
assert check_vowel_count(given) == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('given, expected',
|
||||||
|
[
|
||||||
|
('aabbccdd', True),
|
||||||
|
('whythisword', False),
|
||||||
|
('hegwjzuvuyypxyu', True)
|
||||||
|
])
|
||||||
|
def test_double_counting(given, expected):
|
||||||
|
assert check_doubled_char(given) == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('given, expected',
|
||||||
|
[
|
||||||
|
('aabbccdd', False),
|
||||||
|
('whythisword', True)
|
||||||
|
])
|
||||||
|
def test_bad_chars(given, expected):
|
||||||
|
assert check_contains_no_bad_chars(given) == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('given, expected',
|
||||||
|
[
|
||||||
|
('ugknbfddgicrmopn', True),
|
||||||
|
('aaa', True),
|
||||||
|
('jchzalrnumimnmhp', False),
|
||||||
|
('haegwjzuvuyypxyu', False),
|
||||||
|
('dvszwmarrgswjxmb', False)
|
||||||
|
])
|
||||||
|
def test_examples(given, expected):
|
||||||
|
assert check_if_nice(given) == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('given, expected',
|
||||||
|
[
|
||||||
|
('xyxy', True),
|
||||||
|
('xxyxx', True),
|
||||||
|
('aaa', False)
|
||||||
|
])
|
||||||
|
def test_nonopverlapping(given, expected):
|
||||||
|
assert check_nonoverlapping_repeats(given) == expected
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('given, expected',
|
||||||
|
[
|
||||||
|
('xyx', True),
|
||||||
|
('xxyxx', True),
|
||||||
|
('abcdefeghi', True),
|
||||||
|
('aaa', True),
|
||||||
|
('blargh', False)
|
||||||
|
])
|
||||||
|
def test_repeat_everyother(given, expected):
|
||||||
|
assert check_repeat_everyother(given) == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('given, expected',
|
||||||
|
[
|
||||||
|
('qjhvhtzxzqqjkmpb', True),
|
||||||
|
('xxyxx', True),
|
||||||
|
('uurcxstgmygtbstg', False),
|
||||||
|
('ieodomkazucvgmuy', False)
|
||||||
|
])
|
||||||
|
def test_part2_examples(given, expected):
|
||||||
|
assert check_if_nice_part2(given) == expected
|
||||||
BIN
25/1/__pycache__/main.cpython-313.pyc
Normal file
BIN
25/1/__pycache__/main.cpython-313.pyc
Normal file
Binary file not shown.
BIN
25/1/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc
Normal file
BIN
25/1/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc
Normal file
Binary file not shown.
59
25/1/main.py
Normal file
59
25/1/main.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
'''AoC 2025 Day 1'''
|
||||||
|
import math
|
||||||
|
|
||||||
|
def turn_dial(curr_pos: int, instruction: str) -> int:
|
||||||
|
'''Turn dial from current position to the new one'''
|
||||||
|
direction, amount = process_instruction(instruction)
|
||||||
|
|
||||||
|
new_pos = (curr_pos + (direction * amount)) % 100
|
||||||
|
|
||||||
|
return new_pos
|
||||||
|
|
||||||
|
|
||||||
|
def check_cross_zero(curr_pos: int, instruction: str) -> int:
|
||||||
|
'''Check for if the instruction crosses 0 and lands on it'''
|
||||||
|
direction, amount = process_instruction(instruction)
|
||||||
|
|
||||||
|
total_zeros = 0
|
||||||
|
|
||||||
|
if direction == 1 and curr_pos + amount >= 100:
|
||||||
|
total_zeros += math.floor((curr_pos + amount) / 100)
|
||||||
|
if direction == -1 and curr_pos - amount <= 0:
|
||||||
|
total_zeros += math.floor(abs((curr_pos - amount) / 100))
|
||||||
|
if curr_pos != 0:
|
||||||
|
total_zeros += 1
|
||||||
|
|
||||||
|
return total_zeros
|
||||||
|
|
||||||
|
|
||||||
|
def process_instruction(instruction: str) -> (int, int):
|
||||||
|
'''Returns the direction and amount of the turn'''
|
||||||
|
direction = -1 if instruction[0] == 'L' else 1
|
||||||
|
amount = int(instruction[1:])
|
||||||
|
|
||||||
|
return direction, amount
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
'''Entrypoint'''
|
||||||
|
curr_pos = 50
|
||||||
|
|
||||||
|
num_zero = 0
|
||||||
|
crossing_zero = 0
|
||||||
|
|
||||||
|
with open('input.txt', encoding='utf-8') as fh:
|
||||||
|
for line in fh:
|
||||||
|
crossing_zero += check_cross_zero(curr_pos, line.strip())
|
||||||
|
|
||||||
|
curr_pos = turn_dial(curr_pos, line.strip())
|
||||||
|
|
||||||
|
if curr_pos == 0:
|
||||||
|
num_zero += 1
|
||||||
|
|
||||||
|
print(f'Part1: {num_zero}')
|
||||||
|
|
||||||
|
print(f'Part2: {crossing_zero}')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
41
25/1/test_main.py
Normal file
41
25/1/test_main.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
'''testing'''
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from main import turn_dial, check_cross_zero
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('current, given, expected',
|
||||||
|
[
|
||||||
|
(50, 'L68', 82),
|
||||||
|
(82, 'L30', 52),
|
||||||
|
(52, 'R48', 0),
|
||||||
|
(0, 'L5', 95),
|
||||||
|
(95, 'R60', 55),
|
||||||
|
(55, 'L55', 0),
|
||||||
|
(0, 'L1', 99),
|
||||||
|
(99, 'L99', 0),
|
||||||
|
(0, 'R14', 14),
|
||||||
|
(14, 'L82', 32),
|
||||||
|
(50, 'R1000', 50),
|
||||||
|
(50, 'L1000', 50)
|
||||||
|
])
|
||||||
|
def test_matching_zero(current, given, expected):
|
||||||
|
assert turn_dial(current, given) == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('current, given, expected',
|
||||||
|
[
|
||||||
|
(50, 'L68', 1),
|
||||||
|
(82, 'L30', 0),
|
||||||
|
(52, 'R48', 1),
|
||||||
|
(0, 'L5', 0),
|
||||||
|
(95, 'R60', 1),
|
||||||
|
(55, 'L55', 1),
|
||||||
|
(0, 'L1', 0),
|
||||||
|
(99, 'L99', 1),
|
||||||
|
(0, 'R14', 0),
|
||||||
|
(14, 'L82', 1),
|
||||||
|
(50, 'R1000', 10),
|
||||||
|
(50, 'L1000', 10)
|
||||||
|
])
|
||||||
|
def test_crossing_zero(current, given, expected):
|
||||||
|
assert check_cross_zero(current, given) == expected
|
||||||
BIN
25/2/__pycache__/main.cpython-313.pyc
Normal file
BIN
25/2/__pycache__/main.cpython-313.pyc
Normal file
Binary file not shown.
BIN
25/2/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc
Normal file
BIN
25/2/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc
Normal file
Binary file not shown.
48
25/2/main.py
Normal file
48
25/2/main.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
'''AoC Day 2'''
|
||||||
|
import re
|
||||||
|
|
||||||
|
def part1(range_list: list) -> int:
|
||||||
|
'''Part 1'''
|
||||||
|
total = 0
|
||||||
|
|
||||||
|
for id_range in range_list:
|
||||||
|
for x in range(int(id_range[0]), int(id_range[1]) + 1):
|
||||||
|
if not check_valid_id(str(x)):
|
||||||
|
total += x
|
||||||
|
|
||||||
|
return total
|
||||||
|
|
||||||
|
def part2(range_list: list) -> int:
|
||||||
|
'''Part 2'''
|
||||||
|
total = 0
|
||||||
|
|
||||||
|
for id_range in range_list:
|
||||||
|
for x in range(int(id_range[0]), int(id_range[1]) + 1):
|
||||||
|
if not check_extended_id(str(x)):
|
||||||
|
total += x
|
||||||
|
|
||||||
|
return total
|
||||||
|
|
||||||
|
def check_valid_id(id: str) -> bool:
|
||||||
|
'''Checks a given ID for validity using the silly rules'''
|
||||||
|
return re.fullmatch(r'(.*?)\1', id) is None
|
||||||
|
|
||||||
|
def check_extended_id(id: str) -> bool:
|
||||||
|
'''Checks for extended rule checking, at least two repeats'''
|
||||||
|
return re.fullmatch(r'(.*?)\1+', id) is None
|
||||||
|
|
||||||
|
def main():
|
||||||
|
'''Entrypoint'''
|
||||||
|
with open('input.txt', encoding='utf-8') as fh:
|
||||||
|
range_list = [(y[0].strip(), y[1].strip()) for y in (x.split('-') for x in fh.readline().split(','))]
|
||||||
|
|
||||||
|
total = part1(range_list)
|
||||||
|
|
||||||
|
print(f'Part1: {total}')
|
||||||
|
|
||||||
|
total2 = part2(range_list)
|
||||||
|
|
||||||
|
print(f'Part2: {total2}')
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
87
25/2/test_main.py
Normal file
87
25/2/test_main.py
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from main import check_valid_id, check_extended_id, part1, part2
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('given, expected',
|
||||||
|
[
|
||||||
|
('1', True),
|
||||||
|
('11', False),
|
||||||
|
('12', True),
|
||||||
|
('22', False),
|
||||||
|
('1010', False),
|
||||||
|
('1012', True),
|
||||||
|
('1188511885', False),
|
||||||
|
('222222', False),
|
||||||
|
('446446', False),
|
||||||
|
('565656', True),
|
||||||
|
('446447', True),
|
||||||
|
('38593859', False),
|
||||||
|
('385385385', True)
|
||||||
|
])
|
||||||
|
def test_check_valid_id(given, expected):
|
||||||
|
assert check_valid_id(given) == expected
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('given, expected',
|
||||||
|
[
|
||||||
|
('1', True),
|
||||||
|
('12', True),
|
||||||
|
('1012', True),
|
||||||
|
('446447', True),
|
||||||
|
('11', False),
|
||||||
|
('22', False),
|
||||||
|
('99', False),
|
||||||
|
('111', False),
|
||||||
|
('999', False),
|
||||||
|
('1010', False),
|
||||||
|
('1188511885', False),
|
||||||
|
('222222', False),
|
||||||
|
('446446', False),
|
||||||
|
('565656', False),
|
||||||
|
('38593859', False),
|
||||||
|
('385385385', False),
|
||||||
|
('824824824', False),
|
||||||
|
('2121212121', False)
|
||||||
|
])
|
||||||
|
def test_extended_valid_id(given, expected):
|
||||||
|
assert check_extended_id(given) == expected
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('given, expected',
|
||||||
|
[
|
||||||
|
(
|
||||||
|
[
|
||||||
|
('11', '22'),
|
||||||
|
('95', '115'),
|
||||||
|
('998', '1012'),
|
||||||
|
('1188511880', '1188511890'),
|
||||||
|
('222220', '222224'),
|
||||||
|
('1698522', '1698528'),
|
||||||
|
('446443', '446449'),
|
||||||
|
('38593856', '38593862')
|
||||||
|
],
|
||||||
|
1227775554
|
||||||
|
)
|
||||||
|
])
|
||||||
|
def test_part1_examples(given, expected):
|
||||||
|
assert part1(given) == expected
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('given, expected',
|
||||||
|
[
|
||||||
|
(
|
||||||
|
[
|
||||||
|
('11', '22'),
|
||||||
|
('95', '115'),
|
||||||
|
('998', '1012'),
|
||||||
|
('1188511880', '1188511890'),
|
||||||
|
('222220', '222224'),
|
||||||
|
('1698522', '1698528'),
|
||||||
|
('446443', '446449'),
|
||||||
|
('38593856', '38593862'),
|
||||||
|
('565653', '565659'),
|
||||||
|
('824824821', '824824827'),
|
||||||
|
('2121212118', '2121212124')
|
||||||
|
],
|
||||||
|
4174379265
|
||||||
|
)
|
||||||
|
])
|
||||||
|
def test_part2_examples(given, expected):
|
||||||
|
assert part2(given) == expected
|
||||||
Loading…
x
Reference in New Issue
Block a user