require 'debug' module FileHandler def self.read_lines(file_path) File.readlines(file_path, chomp: true).map do |line| yield(line) end end def self.read_file(file_path) File.read(file_path) end end class JoltageCalculator def initialize(file_path, debug: false) @file_path = file_path @debug = debug end def calculate_total_joltage total = 0 FileHandler.read_lines(@file_path) do |line| int_array = line.split('').map(&:to_i) total += calculate_joltage(int_array) end total end # @param [] bank def _calculate_joltage(bank) joltage = '' first_digit, first_pos = max_and_index_from_slice(bank, 1) joltage += first_digit.to_s sub_bank = bank.slice(first_pos + 1, bank.length) second_digit, _ = max_and_index_from_slice(sub_bank, 0) joltage += second_digit.to_s joltage.to_i end # @param [] bank def calculate_joltage(bank, total_digits: 12) joltage = '' current_offset = total_digits - 1 while current_offset >= 0 maximum, i = max_and_index_from_slice(bank, current_offset) joltage += maximum.to_s bank = bank.slice(i + 1, bank.length) current_offset -= 1 end joltage.to_i end private # Get max and index from the first part of the array. Ignore the last `offset` # number of digits. # @param [] array # @param [integer] offset def max_and_index_from_slice(array, offset) maximum = array.slice(0, array.length - offset).max index = array.find_index(maximum) [maximum, index] end end if ARGV[0].nil? || ARGV[0].empty? puts "Usage: ruby part2.rb [debug]" exit 1 end debug = (ARGV[1] == "debug") calculator = JoltageCalculator.new(ARGV[0], debug:) puts "The answer is: #{calculator.calculate_total_joltage}" # The answer is: 169077317650774 # real 0m0,260s # user 0m0,222s # sys 0m0,038s