Mercurial > repos > other > adventofcode2023
changeset 10:25dda3397797
Partial attempt at day 5 part 2
Trying to intersect ranges to make new ranges.
Not working yet.
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sat, 09 Dec 2023 15:46:29 +0000 |
parents | 9ec95ff0d33d |
children | a7fb64b48830 |
files | day5b.rb |
diffstat | 1 files changed, 70 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/day5b.rb Sat Dec 09 15:46:29 2023 +0000 @@ -0,0 +1,70 @@ +#! /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).each_slice(2).map {|v| v[0]..(v[0]+v[1])} + +puts "#{seeds}" + +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) + puts "Mappings: #{mappings} - input: #{input}" + mappings.ranges.reduce(input) do |input_ranges, mapping| + puts "Input Ranges: #{input_ranges}; Mapping: #{mapping}" + input_ranges.flat_map do |input_range| + if mapping.source_range.cover?(input_range) + # Input is inside the mapped range + [(input_range.begin+mapping.offset)..(input_range.end+mapping.offset)] + elsif mapping.source_range.end < input_range.begin or input_range.end < mapping.source_range.begin + # Input is entirely outside the mapped range + [input_range] + elsif input_range.begin < mapping.source_range.begin + # Input straddles the start + [ + (input_range.begin+mapping.offset)...(mapping.source_range.begin+mapping.offset), + (mapping.source_range.begin+mapping.offset)..(input_range.end+mapping.offset) + ] + else + # Must straddle the end + [ + (input_range.begin+mapping.offset)...(mapping.source_range.end+mapping.offset), + (mapping.source_range.end+mapping.offset)..(input_range.end+mapping.offset) + ] + end + end + end +end + +steps = ["seed", "soil", "fertilizer", "water", "light", "temperature", "humidity"] + +# FIXME: Some negative values and 0s, and the final `min()` gets a nill value +puts steps.reduce(seeds) {|vals, map_name| map_with_override(mappings[map_name], vals)}.map{|v| v.min}.min()