#!/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) })