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()