103 lines
2.3 KiB
Ruby
103 lines
2.3 KiB
Ruby
require 'debug'
|
|
|
|
# Generic FileHandler
|
|
class FileHandler
|
|
def initialize(file_path)
|
|
@file_path = file_path
|
|
end
|
|
|
|
# Usage:
|
|
# FileHandler.new('/path_to_file').read_lines do |line|
|
|
# # process line
|
|
# end
|
|
def read_lines
|
|
File.foreach(@file_path, chomp: true).map do |line|
|
|
yield(line)
|
|
end
|
|
end
|
|
|
|
# Usage:
|
|
# file_content = FileHandler.new('/path_to_file').read_file(
|
|
def read_file
|
|
File.read(@file_path, chomp: true)
|
|
end
|
|
end
|
|
|
|
class PuzzleSolver
|
|
def initialize(file_handler, debug: false)
|
|
@handler = file_handler
|
|
@debug = debug
|
|
end
|
|
|
|
def debug(message)
|
|
puts message if @debug
|
|
end
|
|
|
|
def print_debug(message)
|
|
print message if @debug
|
|
end
|
|
|
|
def solve
|
|
raise NotImplementedError, 'Please implement this method in subclasses.'
|
|
end
|
|
end
|
|
|
|
class FreshnessDatabase
|
|
# @param [<Range>] list of ranges of fresh IDs
|
|
def initialize(fresh_ranges)
|
|
@fresh_ranges = fresh_ranges
|
|
end
|
|
|
|
def fresh_id?(id)
|
|
@fresh_ranges.any? {|range| range.include?(id)}
|
|
end
|
|
end
|
|
|
|
class Solver < PuzzleSolver
|
|
# @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
|
|
|
|
# @param [String] full input e.g., "11-22\n33-604\n..."
|
|
# @return [<Range>] e.g., [11..22, 33..604, ...]
|
|
def parse_ranges(input)
|
|
input.split("\n").map {|range| to_range(range)}
|
|
end
|
|
|
|
# @param [String] ids_str e.g., "1\n5\n8\n11\n17\n32"
|
|
# @return [<Integer>] e.g., [1, 5, 8, 11, 17, 32]
|
|
def parse_ids(ids_str)
|
|
ids_str.split("\n").map(&:to_i)
|
|
end
|
|
|
|
def solve
|
|
two_parts = @handler.read_file.split("\n\n")
|
|
raise "Invalid file format: #{two_parts.inpsect}" if two_parts.length != 2
|
|
|
|
db = FreshnessDatabase.new(parse_ranges(two_parts[0]))
|
|
ids = parse_ids(two_parts[1])
|
|
|
|
fresh_ids = ids.select {|id| db.fresh_id?(id)}
|
|
fresh_ids.length
|
|
end
|
|
end
|
|
|
|
|
|
if ARGV[0].nil? || ARGV[0].empty?
|
|
puts "Usage: ruby #{__FILE__} <file_name> [debug]"
|
|
exit 1
|
|
end
|
|
file_path = ARGV[0]
|
|
debug = (ARGV[1] == "debug")
|
|
file_handler = FileHandler.new(file_path)
|
|
|
|
## Puzzle-specific
|
|
cls = Solver
|
|
##
|
|
|
|
puts "The answer is: #{cls.new(file_handler, debug:).solve}"
|