Solution to problem 13 in Python
This commit is contained in:
parent
2236757376
commit
13e387386b
357
src/Year_2017/P13.py
Normal file
357
src/Year_2017/P13.py
Normal file
@ -0,0 +1,357 @@
|
||||
# --- Day 13: Packet Scanners ---
|
||||
|
||||
# You need to cross a vast firewall. The firewall consists of several layers,
|
||||
# each with a security scanner that moves back and forth across the layer.
|
||||
# To succeed, you must not be detected by a scanner.
|
||||
|
||||
# By studying the firewall briefly, you are able to record (in your puzzle input)
|
||||
# the depth of each layer and the range of the scanning area for the scanner
|
||||
# within it, written as depth: range. Each layer has a thickness of exactly 1.
|
||||
# A layer at depth 0 begins immediately inside the firewall; a layer at depth 1
|
||||
# would start immediately after that.
|
||||
|
||||
# For example, suppose you've recorded the following:
|
||||
|
||||
# 0: 3
|
||||
# 1: 2
|
||||
# 4: 4
|
||||
# 6: 4
|
||||
|
||||
# This means that there is a layer immediately inside the firewall (with range
|
||||
# 3), a second layer immediately after that (with range 2), a third layer which
|
||||
# begins at depth 4 (with range 4), and a fourth layer which begins at depth 6
|
||||
# (also with range 4). Visually, it might look like this:
|
||||
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [ ] ... ... [ ] ... [ ]
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [ ] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
# Within each layer, a security scanner moves back and forth within its range.
|
||||
# Each security scanner starts at the top and moves down until it reaches the
|
||||
# bottom, then moves up until it reaches the top, and repeats. A security scanner
|
||||
# takes one picosecond to move one step. Drawing scanners as S, the first few
|
||||
# picoseconds look like this:
|
||||
|
||||
|
||||
# Picosecond 0:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [S] [S] ... ... [S] ... [S]
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [ ] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
# Picosecond 1:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [ ] ... ... [ ] ... [ ]
|
||||
# [S] [S] [S] [S]
|
||||
# [ ] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
# Picosecond 2:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [S] ... ... [ ] ... [ ]
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [S] [S] [S]
|
||||
# [ ] [ ]
|
||||
|
||||
# Picosecond 3:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [ ] ... ... [ ] ... [ ]
|
||||
# [S] [S] [ ] [ ]
|
||||
# [ ] [ ] [ ]
|
||||
# [S] [S]
|
||||
|
||||
# Your plan is to hitch a ride on a packet about to move through the firewall.
|
||||
# The packet will travel along the top of each layer, and it moves at one layer
|
||||
# per picosecond. Each picosecond, the packet moves one layer forward (its first
|
||||
# move takes it into layer 0), and then the scanners move one step. If there is
|
||||
# a scanner at the top of the layer as your packet enters it, you are caught.
|
||||
# (If a scanner moves into the top of its layer while you are there, you are not
|
||||
# caught: it doesn't have time to notice you before you leave.) If you were to
|
||||
# do this in the configuration above, marking your current position with
|
||||
# parentheses, your passage through the firewall would look like this:
|
||||
|
||||
# Initial state:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [S] [S] ... ... [S] ... [S]
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [ ] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
# Picosecond 0:
|
||||
# 0 1 2 3 4 5 6
|
||||
# (S) [S] ... ... [S] ... [S]
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [ ] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
# 0 1 2 3 4 5 6
|
||||
# ( ) [ ] ... ... [ ] ... [ ]
|
||||
# [S] [S] [S] [S]
|
||||
# [ ] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
|
||||
# Picosecond 1:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] ( ) ... ... [ ] ... [ ]
|
||||
# [S] [S] [S] [S]
|
||||
# [ ] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] (S) ... ... [ ] ... [ ]
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [S] [S] [S]
|
||||
# [ ] [ ]
|
||||
|
||||
|
||||
# Picosecond 2:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [S] (.) ... [ ] ... [ ]
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [S] [S] [S]
|
||||
# [ ] [ ]
|
||||
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [ ] (.) ... [ ] ... [ ]
|
||||
# [S] [S] [ ] [ ]
|
||||
# [ ] [ ] [ ]
|
||||
# [S] [S]
|
||||
|
||||
|
||||
# Picosecond 3:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [ ] ... (.) [ ] ... [ ]
|
||||
# [S] [S] [ ] [ ]
|
||||
# [ ] [ ] [ ]
|
||||
# [S] [S]
|
||||
|
||||
# 0 1 2 3 4 5 6
|
||||
# [S] [S] ... (.) [ ] ... [ ]
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [ ] [S] [S]
|
||||
# [ ] [ ]
|
||||
|
||||
|
||||
# Picosecond 4:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [S] [S] ... ... ( ) ... [ ]
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [ ] [S] [S]
|
||||
# [ ] [ ]
|
||||
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [ ] ... ... ( ) ... [ ]
|
||||
# [S] [S] [S] [S]
|
||||
# [ ] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
|
||||
# Picosecond 5:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [ ] ... ... [ ] (.) [ ]
|
||||
# [S] [S] [S] [S]
|
||||
# [ ] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [S] ... ... [S] (.) [S]
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [S] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
|
||||
# Picosecond 6:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [S] ... ... [S] ... (S)
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [S] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [ ] ... ... [ ] ... ( )
|
||||
# [S] [S] [S] [S]
|
||||
# [ ] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
# In this situation, you are caught in layers 0 and 6, because your packet
|
||||
# entered the layer when its scanner was at the top when you entered it. You are
|
||||
# not caught in layer 1, since the scanner moved into the top of the layer once
|
||||
# you were already there.
|
||||
|
||||
# The severity of getting caught on a layer is equal to its depth multiplied by
|
||||
# its range. (Ignore layers in which you do not get caught.) The severity of the
|
||||
# whole trip is the sum of these values. In the example above, the trip severity
|
||||
# is 0*3 + 6*4 = 24.
|
||||
|
||||
# Given the details of the firewall you've recorded, if you leave immediately,
|
||||
# what is the severity of your whole trip?
|
||||
|
||||
with open("files/P13.txt") as f:
|
||||
record = [line for line in f.read().strip().split("\n")]
|
||||
|
||||
|
||||
def layer_timing(depth: str) -> int:
|
||||
return 2 * int(depth) - 2
|
||||
|
||||
|
||||
def part_1() -> None:
|
||||
severity = 0
|
||||
for val in record:
|
||||
layer, depth = val.split(": ")
|
||||
if int(layer) % layer_timing(depth) == 0:
|
||||
severity += int(layer) * int(depth)
|
||||
|
||||
print(severity)
|
||||
|
||||
|
||||
# --- Part Two ---
|
||||
|
||||
# Now, you need to pass through the firewall without being caught - easier said
|
||||
# than done.
|
||||
|
||||
# You can't control the speed of the packet, but you can delay it any number of
|
||||
# picoseconds. For each picosecond you delay the packet before beginning your
|
||||
# trip, all security scanners move one step. You're not in the firewall during
|
||||
# this time; you don't enter layer 0 until you stop delaying the packet.
|
||||
|
||||
# In the example above, if you delay 10 picoseconds (picoseconds 0 - 9), you
|
||||
# won't get caught:
|
||||
|
||||
# State after delaying:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [S] ... ... [ ] ... [ ]
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [S] [S] [S]
|
||||
# [ ] [ ]
|
||||
|
||||
# Picosecond 10:
|
||||
# 0 1 2 3 4 5 6
|
||||
# ( ) [S] ... ... [ ] ... [ ]
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [S] [S] [S]
|
||||
# [ ] [ ]
|
||||
|
||||
# 0 1 2 3 4 5 6
|
||||
# ( ) [ ] ... ... [ ] ... [ ]
|
||||
# [S] [S] [S] [S]
|
||||
# [ ] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
|
||||
# Picosecond 11:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] ( ) ... ... [ ] ... [ ]
|
||||
# [S] [S] [S] [S]
|
||||
# [ ] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
# 0 1 2 3 4 5 6
|
||||
# [S] (S) ... ... [S] ... [S]
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [ ] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
|
||||
# Picosecond 12:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [S] [S] (.) ... [S] ... [S]
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [ ] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [ ] (.) ... [ ] ... [ ]
|
||||
# [S] [S] [S] [S]
|
||||
# [ ] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
|
||||
# Picosecond 13:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [ ] ... (.) [ ] ... [ ]
|
||||
# [S] [S] [S] [S]
|
||||
# [ ] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [S] ... (.) [ ] ... [ ]
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [S] [S] [S]
|
||||
# [ ] [ ]
|
||||
|
||||
|
||||
# Picosecond 14:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [S] ... ... ( ) ... [ ]
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [S] [S] [S]
|
||||
# [ ] [ ]
|
||||
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [ ] ... ... ( ) ... [ ]
|
||||
# [S] [S] [ ] [ ]
|
||||
# [ ] [ ] [ ]
|
||||
# [S] [S]
|
||||
|
||||
|
||||
# Picosecond 15:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [ ] ... ... [ ] (.) [ ]
|
||||
# [S] [S] [ ] [ ]
|
||||
# [ ] [ ] [ ]
|
||||
# [S] [S]
|
||||
|
||||
# 0 1 2 3 4 5 6
|
||||
# [S] [S] ... ... [ ] (.) [ ]
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [ ] [S] [S]
|
||||
# [ ] [ ]
|
||||
|
||||
|
||||
# Picosecond 16:
|
||||
# 0 1 2 3 4 5 6
|
||||
# [S] [S] ... ... [ ] ... ( )
|
||||
# [ ] [ ] [ ] [ ]
|
||||
# [ ] [S] [S]
|
||||
# [ ] [ ]
|
||||
|
||||
# 0 1 2 3 4 5 6
|
||||
# [ ] [ ] ... ... [ ] ... ( )
|
||||
# [S] [S] [S] [S]
|
||||
# [ ] [ ] [ ]
|
||||
# [ ] [ ]
|
||||
|
||||
# Because all smaller delays would get you caught, the fewest number of
|
||||
# picoseconds you would need to delay to get through safely is 10.
|
||||
|
||||
# What is the fewest number of picoseconds that you need to delay the packet to
|
||||
# pass through the firewall without being caught?
|
||||
|
||||
|
||||
def got_caught(delay):
|
||||
for r in record:
|
||||
layer, scanRange = r.split(": ")
|
||||
layer_delayed = int(layer) + delay
|
||||
if (
|
||||
layer_delayed == 0
|
||||
or layer_delayed % (2 * (int(scanRange) - 1)) == 0
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def part_2() -> None:
|
||||
delay = 0
|
||||
while got_caught(delay):
|
||||
delay += 1
|
||||
|
||||
print(delay)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part_1()
|
||||
part_2()
|
Loading…
Reference in New Issue
Block a user