172 lines
5.9 KiB
Python
172 lines
5.9 KiB
Python
# --- Day 3: Toboggan Trajectory ---
|
|
|
|
# With the toboggan login problems resolved, you set off toward the airport.
|
|
# While travel by toboggan might be easy, it's certainly not safe: there's very
|
|
# minimal steering and the area is covered in trees. You'll need to see which
|
|
# angles will take you near the fewest trees.
|
|
|
|
# Due to the local geology, trees in this area only grow on exact integer
|
|
# coordinates in a grid. You make a map (your puzzle input) of the open squares
|
|
# (.) and trees (#) you can see. For example:
|
|
|
|
# ..##.......
|
|
# #...#...#..
|
|
# .#....#..#.
|
|
# ..#.#...#.#
|
|
# .#...##..#.
|
|
# ..#.##.....
|
|
# .#.#.#....#
|
|
# .#........#
|
|
# #.##...#...
|
|
# #...##....#
|
|
# .#..#...#.#
|
|
|
|
# These aren't the only trees, though; due to something you read about once
|
|
# involving arboreal genetics and biome stability, the same pattern repeats to
|
|
# the right many times:
|
|
|
|
# ..##.........##.........##.........##.........##.........##....... --->
|
|
# #...#...#..#...#...#..#...#...#..#...#...#..#...#...#..#...#...#..
|
|
# .#....#..#..#....#..#..#....#..#..#....#..#..#....#..#..#....#..#.
|
|
# ..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#
|
|
# .#...##..#..#...##..#..#...##..#..#...##..#..#...##..#..#...##..#.
|
|
# ..#.##.......#.##.......#.##.......#.##.......#.##.......#.##..... --->
|
|
# .#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#
|
|
# .#........#.#........#.#........#.#........#.#........#.#........#
|
|
# #.##...#...#.##...#...#.##...#...#.##...#...#.##...#...#.##...#...
|
|
# #...##....##...##....##...##....##...##....##...##....##...##....#
|
|
# .#..#...#.#.#..#...#.#.#..#...#.#.#..#...#.#.#..#...#.#.#..#...#.# --->
|
|
|
|
# You start on the open square (.) in the top-left corner and need to reach the
|
|
# bottom (below the bottom-most row on your map).
|
|
|
|
# The toboggan can only follow a few specific slopes (you opted for a cheaper
|
|
# model that prefers rational numbers); start by counting all the trees you
|
|
# would encounter for the slope right 3, down 1:
|
|
|
|
# From your starting position at the top-left, check the position that is right
|
|
# 3 and down 1. Then, check the position that is right 3 and down 1 from there,
|
|
# and so on until you go past the bottom of the map.
|
|
|
|
# The locations you'd check in the above example are marked here with O where
|
|
# there was an open square and X where there was a tree:
|
|
|
|
# ..##.........##.........##.........##.........##.........##....... --->
|
|
# #..O#...#..#...#...#..#...#...#..#...#...#..#...#...#..#...#...#..
|
|
# .#....X..#..#....#..#..#....#..#..#....#..#..#....#..#..#....#..#.
|
|
# ..#.#...#O#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#
|
|
# .#...##..#..X...##..#..#...##..#..#...##..#..#...##..#..#...##..#.
|
|
# ..#.##.......#.X#.......#.##.......#.##.......#.##.......#.##..... --->
|
|
# .#.#.#....#.#.#.#.O..#.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#
|
|
# .#........#.#........X.#........#.#........#.#........#.#........#
|
|
# #.##...#...#.##...#...#.X#...#...#.##...#...#.##...#...#.##...#...
|
|
# #...##....##...##....##...#X....##...##....##...##....##...##....#
|
|
# .#..#...#.#.#..#...#.#.#..#...X.#.#..#...#.#.#..#...#.#.#..#...#.# --->
|
|
|
|
# In this example, traversing the map using this slope would cause you to
|
|
# encounter 7 trees.
|
|
|
|
# Starting at the top-left corner of your map and following a slope of right 3
|
|
# and down 1, how many trees would you encounter?
|
|
|
|
|
|
with open("files/P3.txt", "r") as f:
|
|
forest = [line.split() for line in f.read().strip().split("\n")]
|
|
|
|
|
|
def part_1() -> None:
|
|
trees_found, pos = 0, 0
|
|
for idx, line in enumerate(forest):
|
|
extended_line = ",".join(line * 32).replace(",", "")
|
|
if extended_line[pos] == "#":
|
|
trees_found += 1
|
|
pos += 3
|
|
|
|
print(f"We found {trees_found} trees in our way")
|
|
|
|
|
|
# --- Part Two ---
|
|
|
|
# Time to check the rest of the slopes - you need to minimize the probability
|
|
# of a sudden arboreal stop, after all.
|
|
|
|
# Determine the number of trees you would encounter if, for each of the
|
|
# following slopes, you start at the top-left corner and traverse the map all
|
|
# the way to the bottom:
|
|
|
|
# Right 1, down 1.
|
|
# Right 3, down 1. (This is the slope you already checked.)
|
|
# Right 5, down 1.
|
|
# Right 7, down 1.
|
|
# Right 1, down 2.
|
|
|
|
# In the above example, these slopes would find 2, 7, 3, 4, and 2 tree(s)
|
|
# respectively; multiplied together, these produce the answer 336.
|
|
|
|
# What do you get if you multiply together the number of trees encountered on
|
|
# each of the listed slopes?
|
|
|
|
|
|
def part_2() -> None:
|
|
pos = 0
|
|
trees_first = 0
|
|
# first slope: right 1, down 1
|
|
for idx, line in enumerate(forest):
|
|
extended_line = ",".join(line * 11).replace(",", "")
|
|
if extended_line[pos] == "#":
|
|
trees_first += 1
|
|
pos += 1
|
|
|
|
# reset pos
|
|
pos = 0
|
|
trees_second = 0
|
|
# second slope: right 3, down 1
|
|
for idx, line in enumerate(forest):
|
|
extended_line = ",".join(line * 32).replace(",", "")
|
|
if extended_line[pos] == "#":
|
|
trees_second += 1
|
|
pos += 3
|
|
|
|
# reset pos
|
|
pos = 0
|
|
trees_third = 0
|
|
# third slope: right 5, down 1
|
|
for idx, line in enumerate(forest):
|
|
extended_line = ",".join(line * 55).replace(",", "")
|
|
if extended_line[pos] == "#":
|
|
trees_third += 1
|
|
pos += 5
|
|
|
|
# reset pos
|
|
pos = 0
|
|
trees_fourth = 0
|
|
# fourth slope: right 7, down 1
|
|
for idx, line in enumerate(forest):
|
|
extended_line = ",".join(line * 77).replace(",", "")
|
|
if extended_line[pos] == "#":
|
|
trees_fourth += 1
|
|
pos += 7
|
|
|
|
# reset pos
|
|
pos = 0
|
|
trees_fifth = 0
|
|
# fifth slope: right 1, down 2
|
|
for idx, line in enumerate(forest):
|
|
if idx % 2 == 0:
|
|
# break
|
|
extended_line = ",".join(line * 6).replace(",", "")
|
|
if extended_line[pos] == "#":
|
|
trees_fifth += 1
|
|
pos += 1
|
|
|
|
total_trees = (
|
|
trees_first * trees_second * trees_third * trees_fourth * trees_fifth
|
|
)
|
|
|
|
print(f"We found {total_trees} trees in our way")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
part_1()
|
|
part_2()
|