58 lines
1.1 KiB
Ruby
Executable File
58 lines
1.1 KiB
Ruby
Executable File
#!/usr/bin/env ruby
|
|
# frozen_string_literal: true
|
|
|
|
require "pathname"
|
|
require "set"
|
|
|
|
def uppercase?(char)
|
|
char.ord.between?(65, 90)
|
|
end
|
|
|
|
def parse_file(file)
|
|
rules = []
|
|
input = nil
|
|
|
|
rules_parsed = false
|
|
file.each_line do |line|
|
|
line = line.chomp
|
|
if line.empty?
|
|
rules_parsed = true
|
|
elsif rules_parsed
|
|
input = line.each_char.slice_before { |x| uppercase?(x) }.map(&:join)
|
|
else
|
|
line.split(" => ") => [lhs, rhs]
|
|
replacement = rhs.each_char.slice_before { |x| uppercase?(x) }.map(&:join)
|
|
rules.push([lhs, replacement])
|
|
end
|
|
end
|
|
|
|
[input, rules]
|
|
end
|
|
|
|
def apply_rules(input, rules)
|
|
molecules = Set.new
|
|
|
|
input.each_with_index do |item, idx|
|
|
rules.select { |(x, _)| x == item }.each do |(_, re)|
|
|
head = input[...idx].join
|
|
tail = input[(idx+1)..].join
|
|
|
|
molecules.add("#{head}#{re.join}#{tail}")
|
|
end
|
|
end
|
|
|
|
molecules
|
|
end
|
|
|
|
def main(file_paths)
|
|
file_paths.each do |file_path|
|
|
puts "File: #{file_path}"
|
|
input, rules = parse_file(file_path)
|
|
|
|
solution1 = apply_rules(input, rules).size
|
|
puts " Solution 1: #{solution1}"
|
|
end
|
|
end
|
|
|
|
main(ARGV.map { |x| Pathname(x) })
|