58 lines
1.5 KiB
Ruby
58 lines
1.5 KiB
Ruby
require 'debug'
|
|
|
|
class ValidIdFilter
|
|
def initialize(file_path)
|
|
@file_path = file_path
|
|
end
|
|
|
|
def sum_invalid_ids(debug: false)
|
|
ranges = parse_input(File.read(@file_path))
|
|
invalid_ids = ranges.flat_map {|range| get_invalid_ids_from_range(range)}
|
|
invalid_ids.sum
|
|
end
|
|
|
|
private
|
|
|
|
# @param [Range] e.g., 11-22
|
|
# @return [<Integer>] array of invalid ids in range
|
|
def get_invalid_ids_from_range(range)
|
|
range.select {|element| invalid_id?(element)}
|
|
end
|
|
|
|
def invalid_id?(integer)
|
|
# ID is invalid if it is made only of some sequence of digits repeated twice
|
|
string = integer.to_s
|
|
num_digits = string.length
|
|
|
|
# some sequence repeated twice => number of digits must be even
|
|
return false if num_digits % 2 != 0
|
|
|
|
half_length = num_digits / 2
|
|
|
|
string[0...half_length] == string[half_length..-1]
|
|
end
|
|
|
|
# @param [String] full input e.g., "11-22,33-604,..."
|
|
# @return [<Range>] e.g., [11..22, 33..604, ...]
|
|
def parse_input(input)
|
|
input.split(',').map {|range| to_range(range)}
|
|
end
|
|
|
|
# @param [String] e.g., "11-22"
|
|
# @return [Range] e.g., 11..22 (inclusive)
|
|
def to_range(string)
|
|
boundaries = string.split('-').map(&:to_i)
|
|
raise "Invalid boundaries for #{string}, got #{boundaries.inspect}" if boundaries.length != 2
|
|
Range.new(boundaries[0], boundaries[1])
|
|
end
|
|
end
|
|
|
|
if ARGV[0].nil? || ARGV[0].empty?
|
|
puts "Usage: ruby part1.rb <file_name> [debug]"
|
|
exit 1
|
|
end
|
|
|
|
debug = (ARGV[1] == "debug")
|
|
filter = ValidIdFilter.new(ARGV[0])
|
|
puts "The answer is: #{filter.sum_invalid_ids(debug:)}"
|