feat: Actually day 4 of '25
This commit is contained in:
parent
66b413afd9
commit
79c8fe048a
@ -26,9 +26,8 @@ def get_highest_dynamic(bank_size: int, input: str) -> int:
|
|||||||
for i in range(bank_size, 0, -1):
|
for i in range(bank_size, 0, -1):
|
||||||
curr_highest = 0
|
curr_highest = 0
|
||||||
highest_index = 0
|
highest_index = 0
|
||||||
limit = len(input) - i + 1
|
|
||||||
|
|
||||||
for j in range(curr_index, limit):
|
for j in range(curr_index, len(input) - i + 1):
|
||||||
found = int(input[j])
|
found = int(input[j])
|
||||||
|
|
||||||
if found > curr_highest:
|
if found > curr_highest:
|
||||||
|
|||||||
78
25/4/main.py
Normal file
78
25/4/main.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
def num_neighbours(lines: [], line_index: int, pos_index: int, num_lines: int, line_length: int) -> int:
|
||||||
|
'''Check surrounding and current row neighbours of a given position.
|
||||||
|
Does not operate on 2d coords directly, but on index and current versus prev/next lines.
|
||||||
|
'''
|
||||||
|
total = 0
|
||||||
|
|
||||||
|
for ii in range(max(0, line_index - 1), min(num_lines, line_index + 2)):
|
||||||
|
for jj in range(max(0, pos_index - 1), min(line_length, pos_index + 2)):
|
||||||
|
if ii == line_index and jj == pos_index:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if lines[ii][jj] == '@':
|
||||||
|
total += 1
|
||||||
|
|
||||||
|
return total
|
||||||
|
|
||||||
|
def process_line(lines: []) -> int:
|
||||||
|
'''Iterate through all lines in the map and determine which can be removed this time around'''
|
||||||
|
total = 0
|
||||||
|
|
||||||
|
for line_index, line in enumerate(lines):
|
||||||
|
for index, char in enumerate(line):
|
||||||
|
if char == '@':
|
||||||
|
total_neighbours = num_neighbours(lines, line_index, index, len(lines), len(line))
|
||||||
|
|
||||||
|
if total_neighbours < 4:
|
||||||
|
total += 1
|
||||||
|
|
||||||
|
return total
|
||||||
|
|
||||||
|
|
||||||
|
def find_all_accessible_rolls(lines: []) -> int:
|
||||||
|
'''Recursively iterate through removing paper rolls and see how many are opened up for removal after each pass until none can be removed'''
|
||||||
|
total = 0
|
||||||
|
|
||||||
|
# Copy the map to note which have been removed without affecting the current checks
|
||||||
|
lines_copy = lines
|
||||||
|
|
||||||
|
for line_index, line in enumerate(lines):
|
||||||
|
for index, char in enumerate(line):
|
||||||
|
if char == '@':
|
||||||
|
total_neighbours = 0
|
||||||
|
|
||||||
|
for ii in range(max(0, line_index - 1), min(len(lines), line_index + 2)):
|
||||||
|
for jj in range(max(0, index - 1), min(len(line), index + 2)):
|
||||||
|
if ii == line_index and jj == index:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if lines[ii][jj] == '@':
|
||||||
|
total_neighbours += 1
|
||||||
|
|
||||||
|
if total_neighbours < 4:
|
||||||
|
total += 1
|
||||||
|
temp_line = list(lines_copy[line_index])
|
||||||
|
temp_line[index] = '.'
|
||||||
|
lines_copy[line_index] = ''.join(temp_line)
|
||||||
|
|
||||||
|
if total != 0:
|
||||||
|
return total + find_all_accessible_rolls(lines_copy)
|
||||||
|
|
||||||
|
return total
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
'''Entrypoint'''
|
||||||
|
with open('input.txt', encoding='utf-8') as fh:
|
||||||
|
all_lines = fh.readlines()
|
||||||
|
part1_total = process_line(all_lines)
|
||||||
|
|
||||||
|
print(f'Part 1: {part1_total}')
|
||||||
|
|
||||||
|
part2_total = find_all_accessible_rolls(all_lines)
|
||||||
|
|
||||||
|
print(f'Part 2: {part2_total}')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
40
25/4/test_main.py
Normal file
40
25/4/test_main.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from main import process_line, find_all_accessible_rolls
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('lines, expected',
|
||||||
|
[
|
||||||
|
([
|
||||||
|
'..@@.@@@@.',
|
||||||
|
'@@@.@.@.@@',
|
||||||
|
'@@@@@.@.@@',
|
||||||
|
'@.@@@@..@.',
|
||||||
|
'@@.@@@@.@@',
|
||||||
|
'.@@@@@@@.@',
|
||||||
|
'.@.@.@.@@@',
|
||||||
|
'@.@@@.@@@@',
|
||||||
|
'.@@@@@@@@.',
|
||||||
|
'@.@.@@@.@.'
|
||||||
|
], 13),
|
||||||
|
])
|
||||||
|
def test_process_line(lines, expected):
|
||||||
|
assert process_line(lines) == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('lines, expected',
|
||||||
|
[
|
||||||
|
([
|
||||||
|
'..@@.@@@@.',
|
||||||
|
'@@@.@.@.@@',
|
||||||
|
'@@@@@.@.@@',
|
||||||
|
'@.@@@@..@.',
|
||||||
|
'@@.@@@@.@@',
|
||||||
|
'.@@@@@@@.@',
|
||||||
|
'.@.@.@.@@@',
|
||||||
|
'@.@@@.@@@@',
|
||||||
|
'.@@@@@@@@.',
|
||||||
|
'@.@.@@@.@.'
|
||||||
|
], 43),
|
||||||
|
])
|
||||||
|
def test_iterative_processing(lines, expected):
|
||||||
|
assert find_all_accessible_rolls(lines) == expected
|
||||||
Loading…
x
Reference in New Issue
Block a user