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 [] 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 [] 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 [debug]" exit 1 end debug = (ARGV[1] == "debug") filter = ValidIdFilter.new(ARGV[0]) puts "The answer is: #{filter.sum_invalid_ids(debug:)}"