Advent of Code (Day 13)


Check out out day 13 here.

Run down

You need to get through a firewall that has scanners bouncing back and forth in each layer at different depths. Each layer has different ranges of areas it’s scanning, and the scanner bounces back and forth. You travel deeper through the firewall and your speed is 1 picosecond per layer. How many times would you get caught by the scanner?

Challenge One

The scanner’s path was dependent on the depth of that layer and the range in that the scanner patrolled. ie, the scanner would be at the top of its range if:

depth % [(range - 1) * 2] == 0

If this condition was met, then you would get caught.


firewall = {}

input = File.read('input.txt').split("\n")

input.each do |line|
  depth, range = line.split(': ')
  firewall[depth.to_i] = range.to_i
end

severity = 0

firewall.each do |depth, range|
  cycle = (range - 1) * 2

  if depth % cycle == 0
    severity += depth * range
  end
end

print severity

Challenge Two

For this challenge, you can delay your travel through the firewall and determine when you wouldn’t reach any scanners. Now, you can use the following to determine if you’d get caught:

(depth + delay) % [(range - 1) * 2] == 0

This was interesting because the severity method above was very slow so calculating the delay took a long time. I realized I only needed to find out if I would get caught or not so I had a new mathod caught_at, that returned immediately once it was established that I would get caught. This made the calculation SO much faster.

def caught_at(delay, firewall)
  caught = false

  firewall.each do |depth, range|
    if depth == 0
      return true if (depth + delay) % 4 == 0
    end

    cycle = (range - 1) * 2

    if (depth + delay) % cycle == 0
      return true
    end
  end

  caught
end

(10..30000000).to_a.each do|delay|
  if !caught_at(delay, firewall)
    puts "delay: #{delay}"
    puts "not caught"
    puts
  end
end