Clean up python helpers and day9
This commit is contained in:
parent
2b99e3c864
commit
2bdc480651
|
@ -1,39 +1,25 @@
|
||||||
import numpy as np
|
from helpers import *
|
||||||
with open('input/09', 'r') as file:
|
lines = read_day(9).split('\n')
|
||||||
lines = file.read().strip().split('\n')
|
|
||||||
dtype = np.int32
|
|
||||||
|
|
||||||
directions_array = np.array([[1,0], [-1,0], [0,1], [0,-1]], dtype=dtype)
|
def move_tail(rope: ArrayLike):
|
||||||
directions_dict = {'R': directions_array[0], 'L': directions_array[1], 'D': directions_array[2], 'U': directions_array[3]} # Positive down for visualization
|
|
||||||
|
|
||||||
def move_tail(rope: np.array):
|
|
||||||
for i in range(1, rope.shape[0]):
|
for i in range(1, rope.shape[0]):
|
||||||
dx, dy = rope[i-1,:] - rope[i,:]
|
delta = rope[i-1] - rope[i]
|
||||||
if abs(dx) > 1 and dy == 0:
|
abs_delta = abs(delta)
|
||||||
rope[i,0] += 1 if dx > 0 else -1
|
if (abs_delta.max() > 1 and abs_delta.min() == 0) or (sum(abs_delta) > 2):
|
||||||
elif abs(dy) > 1 and dx == 0:
|
rope[i] += np.sign(delta)
|
||||||
rope[i,1] += 1 if dy > 0 else -1
|
|
||||||
elif abs(dx) + abs(dy) > 2:
|
|
||||||
rope[i,0] += 1 if dx > 0 else -1
|
|
||||||
rope[i,1] += 1 if dy > 0 else -1
|
|
||||||
|
|
||||||
def simulate_rope_drag(length: int, lines: list[str]):
|
def simulate_rope_drag(length: int, lines: list[str]):
|
||||||
rope = np.zeros([length,2], dtype=dtype)
|
rope = np.zeros([length,2], dtype=dtype)
|
||||||
visited = {(rope[-1,0], rope[-1,1])}
|
visited = {tuple(rope[-1])}
|
||||||
for line in lines:
|
for line in lines:
|
||||||
dir_vector = directions_dict[line[0]]
|
dir_vector = directions_dict[line[0]]
|
||||||
amount = int(line[2:])
|
amount = int(line[2:])
|
||||||
for i in range(amount):
|
for i in range(amount):
|
||||||
rope[0,:] += dir_vector
|
rope[0] += dir_vector
|
||||||
move_tail(rope)
|
move_tail(rope)
|
||||||
visited.add((rope[-1,0], rope[-1,1]))
|
visited.add(tuple(rope[-1]))
|
||||||
return visited
|
return visited
|
||||||
|
|
||||||
def visualise_cells(visited: set, size=20):
|
|
||||||
vis_lol = [['#' if (x,y) in visited else '.' for x in range(-size, size)] for y in range(-size, size)]
|
|
||||||
vis_str = '\n'.join(''.join(line) for line in vis_lol)
|
|
||||||
print(vis_str)
|
|
||||||
|
|
||||||
|
|
||||||
visited_part_1 = simulate_rope_drag(2, lines)
|
visited_part_1 = simulate_rope_drag(2, lines)
|
||||||
print(f'Part 1: String length of 2 - tail visits {len(visited_part_1)} cells')
|
print(f'Part 1: String length of 2 - tail visits {len(visited_part_1)} cells')
|
||||||
|
@ -41,7 +27,7 @@ visited_part_2 = simulate_rope_drag(10, lines)
|
||||||
print(f'Part 2: String length of 10 - tail visits {len(visited_part_2)} cells')
|
print(f'Part 2: String length of 10 - tail visits {len(visited_part_2)} cells')
|
||||||
|
|
||||||
if input('Visualise part 1 cells? [y/N]: ').lower() == 'y':
|
if input('Visualise part 1 cells? [y/N]: ').lower() == 'y':
|
||||||
visualise_cells(visited_part_1, 70)
|
visualise_sparse_cells_set(visited_part_1, 70)
|
||||||
print()
|
print()
|
||||||
if input('Visualise part 2 cells? [y/N]: ').lower() == 'y':
|
if input('Visualise part 2 cells? [y/N]: ').lower() == 'y':
|
||||||
visualise_cells(visited_part_2, 70)
|
visualise_sparse_cells_set(visited_part_2, 70)
|
||||||
|
|
|
@ -1,11 +1,27 @@
|
||||||
|
import numpy as np
|
||||||
|
from numpy.typing import ArrayLike
|
||||||
import re
|
import re
|
||||||
numbers_pattern = re.compile(r'((?:(?<!\d)-)?\d+)')
|
numbers_pattern = re.compile(r'((?:(?<!\d)-)?\d+)')
|
||||||
|
|
||||||
def line_to_numbers(line):
|
def line_to_numbers(line):
|
||||||
return [int(x) for x in numbers_pattern.findall(line)]
|
return [int(x) for x in numbers_pattern.findall(line)]
|
||||||
|
|
||||||
def lines_to_numbers(lines):
|
def lines_to_numbers(lines):
|
||||||
return [line_to_numbers(line) for line in lines]
|
return [line_to_numbers(line) for line in lines]
|
||||||
|
|
||||||
def transpose_array_of_strings(aos, reverse_x = False, reverse_y = False, strip = ''):
|
def transpose_array_of_strings(aos, reverse_x = False, reverse_y = False, strip = ''):
|
||||||
return [''.join(l[i] for l in aos[::-1 if reverse_y else 1]).strip(strip) for i in range(len(aos[0]))[::-1 if reverse_x else 1]]
|
return [''.join(l[i] for l in aos[::-1 if reverse_y else 1]).strip(strip) for i in range(len(aos[0]))[::-1 if reverse_x else 1]]
|
||||||
|
|
||||||
|
def read_day(day):
|
||||||
|
with open(f'input/{day:02}', 'r') as file:
|
||||||
|
return file.read().strip()
|
||||||
|
|
||||||
|
dtype = np.int32
|
||||||
|
|
||||||
|
directions_array = np.array([[1,0], [-1,0], [0,1], [0,-1]], dtype=dtype)
|
||||||
|
directions_dict = {'R': directions_array[0], 'L': directions_array[1], 'D': directions_array[2], 'U': directions_array[3]} # Positive down for visualization
|
||||||
|
|
||||||
|
def visualise_sparse_cells_set(cells: set, size=20, sym_hit='#', sym_miss='.'):
|
||||||
|
vis_lol = [[sym_hit if (x,y) in cells else sym_miss for x in range(-size, size)] for y in range(-size, size)]
|
||||||
|
vis_str = '\n'.join(''.join(line) for line in vis_lol)
|
||||||
|
print(vis_str)
|
||||||
|
|
Loading…
Reference in New Issue