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