[2017][ruby][13.x] refactored
diff --git a/2017/ruby/day_13.rb b/2017/ruby/day_13.rb
index 6ec1ff7..1af2f4a 100644
--- a/2017/ruby/day_13.rb
+++ b/2017/ruby/day_13.rb
@@ -1,62 +1,11 @@
-input = ARGF.read.strip
-# input = <<INPUT
-# 0: 3
-# 1: 2
-# 4: 4
-# 6: 4
-# INPUT
-@input = Hash[input.scan(/(\d+): (\d+)/).map {|x| x.map(&:to_i) }]
-
-class Firewall
- def initialize(input)
- @layers = input
- @scanners = Hash[input.map {|d,_| [d, 0] }]
- @deltas = Hash[input.map {|d,_| [d, 1] }]
- end
-
- def each
- return enum_for(__method__) unless block_given?
-
- loop do
- yield @scanners
-
- @layers.each do |depth, range|
- @scanners[depth] += @deltas[depth]
- @deltas[depth] = case @scanners[depth]
- when 0
- 1
- when range - 1
- -1
- else
- @deltas[depth]
- end
- end
- end
- end
+firewall = Hash[ARGF.read.strip.scan(/(\d+): (\d+)/).map {|x| x.map(&:to_i) }]
+def caught?(time, range)
+ (time % (2 * (range - 1))).zero?
end
-def pass?(delay)
- f = Firewall.new(@input).each
- delay.times do
- f.next
- end
+p firewall.select {|depth, range| caught?(depth, range) }.map {|d,r| d * r }.sum
- severity = 0
- (0..@input.map(&:first).max).each do |pos|
- scanners = f.next
- return false if scanners[pos] == 0
- end
- true
-end
-
-def s(t, r)
- r - (t % (2*r) - r).abs
-end
-
-(0..Float::INFINITY).each do |delay|
- if @input.all? {|d,r| s(d + delay, r-1) != 0 }
- p delay
- exit
- end
-end
+p (1..Float::INFINITY).find {|delay|
+ firewall.none? {|depth, range| caught?(delay+depth, range) }
+}