view day5.rb @ 33:676461cc3a70

Day 23 - track segments, not each space This allows us to explore the branches once then do quicker calculations for valid route lengths. But still requires exploring 1,262,816 routes to find the longest!
author IBBoard <dev@ibboard.co.uk>
date Thu, 04 Jan 2024 14:52:24 +0000
parents cd5a8f086973
children
line wrap: on
line source

#! /usr/bin/env ruby

require 'set'

if ARGV.length != 1
        abort("Incorrect arguments - needs input file")
elsif not File.exist? (ARGV[0])
	abort("File #{ARGV[0]} did not exist")
end

file = ARGV[0]

maps = Hash.new

lines = File.open(file, "r").each_line(chomp: true)

seeds = lines.first.split(":")[1].split(" ").map(&:to_i)

RawMapping = Struct.new(:from, :to, :ranges)
MappingRange = Struct.new(:source_range, :offset)

mappings = Array.new
mappings_array = []

lines.drop(1).reduce(mappings_array) do |mappings, val|
	if m = /([a-z]+)-to-([a-z]+) map:/.match(val) then
		mappings << RawMapping.new(m[1], m[2], [])
	elsif val != "" then
		dest_start, source_start, range_length = val.split(" ").map(&:to_i)
		mappings[-1].ranges << MappingRange.new((source_start...(source_start + range_length)), dest_start - source_start)
	end
	mappings
end

mappings = mappings_array.map {|mapping| [mapping.from, mapping]}.to_h

def map_with_override(mappings, input)
	mappings.ranges.reduce(input) { |memo, mapping| mapping.source_range.cover?(input) ? input + mapping.offset : memo }
end

steps = ["seed", "soil", "fertilizer", "water", "light", "temperature", "humidity"]

puts steps.reduce(seeds) {|vals, map_name| vals.map {|v| map_with_override(mappings[map_name], v)}}.min()