advent_of_code_2021

My attempts to work through the 2021 Advent of Code problems.
git clone https://git.eamoncaddigan.net/advent_of_code_2021.git
Log | Files | Refs | README | LICENSE

commit 80236e07f07f797b9d7f69036a16b193b8edb3ac
parent c865c4b63b4723de63e31efbfaf877ce38987274
Author: Eamon Caddigan <eamon.caddigan@gmail.com>
Date:   Thu,  2 Dec 2021 20:00:27 -0500

Tried a simpler (pandas-free) implementation and it's much faster

Diffstat:
Mday02_part1.py | 6+++---
Mday02_part2.py | 6+++---
Aday02_part2_v2.py | 45+++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 51 insertions(+), 6 deletions(-)

diff --git a/day02_part1.py b/day02_part1.py @@ -55,13 +55,13 @@ def calculate_puzzle_solution(axis_summary_df): return axis_summary_df.loc['horizontal', 'offset'] * \ axis_summary_df.loc['vertical', 'offset'] -def solve_puzzle(): +def solve_puzzle(input_string): """Return the numeric solution to the puzzle""" return calculate_puzzle_solution( find_total_offsets( convert_commands_to_offsets( split_command_parts( - convert_input_to_df(get_puzzle_input(2)) + convert_input_to_df(input_string) ) ) ) @@ -69,4 +69,4 @@ def solve_puzzle(): if __name__ == "__main__": print("Product of horizontal and vertical offsets:", - solve_puzzle()) + solve_puzzle(get_puzzle_input(2))) diff --git a/day02_part2.py b/day02_part2.py @@ -52,7 +52,7 @@ def calculate_puzzle_solution(running_state_df): `horizontal` offset and `depth`""" return running_state_df.iloc[-1][['depth', 'horizontal']].prod() -def solve_puzzle(): +def solve_puzzle(input_string): """Return the numeric solution to the puzzle""" # Wouldn't it be lovely if this instead looked like: # return get_puzzle_input(2) |> @@ -66,7 +66,7 @@ def solve_puzzle(): find_submarine_state( convert_commands_to_offsets( split_command_parts( - convert_input_to_df(get_puzzle_input(2)) + convert_input_to_df(input_string) ) ) ) @@ -74,4 +74,4 @@ def solve_puzzle(): if __name__ == "__main__": print("Product of (new) horizontal and vertical offsets:", - solve_puzzle()) + solve_puzzle(get_puzzle_input(2))) diff --git a/day02_part2_v2.py b/day02_part2_v2.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +"""I have a bit of downtime so I'm trying out another implementation of Part 2, +all in 'base' Python""" + +import timeit +from utils import get_puzzle_input +import day02_part2 + +def solve_puzzle(input_string): + commands = ((c, float(d)) for c, d in \ + (x.split(' ') for x in input_string.split('\n') if len(x) > 0)) + + horizontal_position = 0 + depth = 0 + aim = 0 + + for c, d in commands: + if c == 'down': + aim += d + elif c == 'up': + aim -= d + else: # c == 'forward' + horizontal_position += d + depth += aim * d + + return depth * horizontal_position + +if __name__ == "__main__": + input_string = get_puzzle_input(2) + + # Check that the results are the same + assert solve_puzzle(input_string) == day02_part2.solve_puzzle(input_string) + + # Compare the timings + loops = 1000 + time_old = timeit.timeit(lambda: day02_part2.solve_puzzle(input_string), + number=loops) + time_new = timeit.timeit(lambda: solve_puzzle(input_string), + number = loops) + print(f"Pandas implementation: {time_old:.4f} s for {loops} loops", + f"Generator implementation: {time_new:.4f} s for {loops} loops", + sep='\n') + # Results on my laptop + #> Pandas implementation: 5.3778 s for 1000 loops + #> Generator implementation: 0.3710 s for 1000 loops