diff --git a/ruby/2019/4/bin/problem b/ruby/2019/4/bin/problem new file mode 100644 index 0000000..8d93ed7 --- /dev/null +++ b/ruby/2019/4/bin/problem @@ -0,0 +1,8 @@ +#!/usr/bin/env ruby + +require "secure_container" +low, high = STDIN.read.chomp.split("-").map(&:to_i) +range = low..high + +puts "Part 1: #{range.count(&:valid_part_1_password?)}" +puts "Part 2: #{range.count(&:valid_part_2_password?)}" \ No newline at end of file diff --git a/ruby/2019/4/lib/secure_container.rb b/ruby/2019/4/lib/secure_container.rb new file mode 100644 index 0000000..c82f420 --- /dev/null +++ b/ruby/2019/4/lib/secure_container.rb @@ -0,0 +1,25 @@ +class Integer + def valid_part_1_password? + has_two_adjacent_digits? and digits_never_decrease? + end + + def valid_part_2_password? + has_exactly_two_adjacent_digits? and digits_never_decrease? + end + + def digits_never_decrease? + digits.reverse == digits.sort + end + + def has_two_adjacent_digits? + digits[..-2].zip(digits[1..]).any? { |x, y| x == y } + end + + def has_exactly_two_adjacent_digits? + threes = digits[..-3].zip(digits[1..-2]).zip(digits[2..]).map{ |x| x.flatten(1) } + triple_indices = threes.each_with_index.select{ |trip, index| trip[0] == trip[1] && trip[0] == trip[2] }.map(&:last) + pairs = digits[..-2].zip(digits[1..]) + pair_indices = pairs.each_with_index.select{ |pair, index| pair[0] == pair[1]}.map(&:last) + pair_indices.any? { |pair_index| !triple_indices.include?(pair_index) && !triple_indices.include?(pair_index - 1) } + end +end