Mercurial > repos > other > adventofcode2023
comparison day5.rb @ 4:cd5a8f086973
Implement part 1 plant mapping and lookup
Timings with Ruby "Range":
real 0m0.046s
user 0m0.032s
sys 0m0.014s
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Wed, 06 Dec 2023 20:02:38 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:9da7a71b313d | 4:cd5a8f086973 |
---|---|
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) | |
18 | |
19 RawMapping = Struct.new(:from, :to, :ranges) | |
20 MappingRange = Struct.new(:source_range, :offset) | |
21 | |
22 mappings = Array.new | |
23 mappings_array = [] | |
24 | |
25 lines.drop(1).reduce(mappings_array) do |mappings, val| | |
26 if m = /([a-z]+)-to-([a-z]+) map:/.match(val) then | |
27 mappings << RawMapping.new(m[1], m[2], []) | |
28 elsif val != "" then | |
29 dest_start, source_start, range_length = val.split(" ").map(&:to_i) | |
30 mappings[-1].ranges << MappingRange.new((source_start...(source_start + range_length)), dest_start - source_start) | |
31 end | |
32 mappings | |
33 end | |
34 | |
35 mappings = mappings_array.map {|mapping| [mapping.from, mapping]}.to_h | |
36 | |
37 def map_with_override(mappings, input) | |
38 mappings.ranges.reduce(input) { |memo, mapping| mapping.source_range.cover?(input) ? input + mapping.offset : memo } | |
39 end | |
40 | |
41 steps = ["seed", "soil", "fertilizer", "water", "light", "temperature", "humidity"] | |
42 | |
43 puts steps.reduce(seeds) {|vals, map_name| vals.map {|v| map_with_override(mappings[map_name], v)}}.min() |