Mercurial > repos > other > adventofcode2023
comparison day5b.rb @ 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 | |
children | 7826431dbc4f |
comparison
equal
deleted
inserted
replaced
9:9ec95ff0d33d | 10:25dda3397797 |
---|---|
1 #! /usr/bin/env ruby | |
2 | |
3 require 'set' | |
4 | |
5 if ARGV.length != 1 | |
6 abort("Incorrect arguments - needs input file") | |
7 elsif not File.exist? (ARGV[0]) | |
8 abort("File #{ARGV[0]} did not exist") | |
9 end | |
10 | |
11 file = ARGV[0] | |
12 | |
13 maps = Hash.new | |
14 | |
15 lines = File.open(file, "r").each_line(chomp: true) | |
16 | |
17 seeds = lines.first.split(":")[1].split(" ").map(&:to_i).each_slice(2).map {|v| v[0]..(v[0]+v[1])} | |
18 | |
19 puts "#{seeds}" | |
20 | |
21 RawMapping = Struct.new(:from, :to, :ranges) | |
22 MappingRange = Struct.new(:source_range, :offset) | |
23 | |
24 mappings = Array.new | |
25 mappings_array = [] | |
26 | |
27 lines.drop(1).reduce(mappings_array) do |mappings, val| | |
28 if m = /([a-z]+)-to-([a-z]+) map:/.match(val) then | |
29 mappings << RawMapping.new(m[1], m[2], []) | |
30 elsif val != "" then | |
31 dest_start, source_start, range_length = val.split(" ").map(&:to_i) | |
32 mappings[-1].ranges << MappingRange.new((source_start...(source_start + range_length)), dest_start - source_start) | |
33 end | |
34 mappings | |
35 end | |
36 | |
37 mappings = mappings_array.map {|mapping| [mapping.from, mapping]}.to_h | |
38 | |
39 def map_with_override(mappings, input) | |
40 puts "Mappings: #{mappings} - input: #{input}" | |
41 mappings.ranges.reduce(input) do |input_ranges, mapping| | |
42 puts "Input Ranges: #{input_ranges}; Mapping: #{mapping}" | |
43 input_ranges.flat_map do |input_range| | |
44 if mapping.source_range.cover?(input_range) | |
45 # Input is inside the mapped range | |
46 [(input_range.begin+mapping.offset)..(input_range.end+mapping.offset)] | |
47 elsif mapping.source_range.end < input_range.begin or input_range.end < mapping.source_range.begin | |
48 # Input is entirely outside the mapped range | |
49 [input_range] | |
50 elsif input_range.begin < mapping.source_range.begin | |
51 # Input straddles the start | |
52 [ | |
53 (input_range.begin+mapping.offset)...(mapping.source_range.begin+mapping.offset), | |
54 (mapping.source_range.begin+mapping.offset)..(input_range.end+mapping.offset) | |
55 ] | |
56 else | |
57 # Must straddle the end | |
58 [ | |
59 (input_range.begin+mapping.offset)...(mapping.source_range.end+mapping.offset), | |
60 (mapping.source_range.end+mapping.offset)..(input_range.end+mapping.offset) | |
61 ] | |
62 end | |
63 end | |
64 end | |
65 end | |
66 | |
67 steps = ["seed", "soil", "fertilizer", "water", "light", "temperature", "humidity"] | |
68 | |
69 # FIXME: Some negative values and 0s, and the final `min()` gets a nill value | |
70 puts steps.reduce(seeds) {|vals, map_name| map_with_override(mappings[map_name], vals)}.map{|v| v.min}.min() |