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…
x
Reference in New Issue
Block a user