Skip to content

Commit e055dc8

Browse files
author
Robb Kidd
committed
day 5, part 2
implentation copied from Brandon Mitchell and then reworked into my map chain shenanigans
1 parent caab329 commit e055dc8

File tree

1 file changed

+70
-4
lines changed

1 file changed

+70
-4
lines changed

2023/ruby/day05.rb

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,34 @@ def part1
1919
end
2020

2121
# @example
22-
# day.part2 #=> 'how are you'
22+
# day.part2 #=> 46
2323
def part2
24+
maps = parse
25+
26+
maps["seeds"]
27+
.each_slice(2)
28+
.map { |start, length|
29+
min = Float::INFINITY
30+
i = 0
31+
while i < length do
32+
location, skip =
33+
[start + i]
34+
.map{ maps["seed-to-soil"] .convert_with_skip(_1) } # no skip to start
35+
.map{ maps["soil-to-fertilizer"] .convert_with_skip(*_1) } # <- from here on _1
36+
.map{ maps["fertilizer-to-water"] .convert_with_skip(*_1) } # is [previous_conversion, skip]
37+
.map{ maps["water-to-light"] .convert_with_skip(*_1) }
38+
.map{ maps["light-to-temperature"] .convert_with_skip(*_1) }
39+
.map{ maps["temperature-to-humidity"].convert_with_skip(*_1) }
40+
.map{ maps["humidity-to-location"] .convert_with_skip(*_1) }
41+
.first
42+
43+
min = location if location < min
44+
i = i + skip if 0 < skip
45+
i = i + 1
46+
end
47+
min
48+
}
49+
.min
2450
end
2551

2652
def parse
@@ -42,9 +68,7 @@ def parse
4268
maps
4369
end
4470

45-
# @example
46-
# mapper = Day05::Mapper.new(["50 98 2", "52 50 48"])
47-
# mapper.convert(79) #=> 81
71+
4872
class Mapper
4973
attr_reader :map_title, :maps
5074

@@ -57,6 +81,9 @@ def initialize(map_title, maps)
5781
}
5882
end
5983

84+
# @example
85+
# mapper = Day05::Mapper.new("test", ["50 98 2", "52 50 48"])
86+
# mapper.convert(79) #=> 81
6087
def convert(input)
6188
maps.each do |source_range, dest_start|
6289
next unless source_range.cover?(input)
@@ -65,6 +92,45 @@ def convert(input)
6592

6693
return input
6794
end
95+
96+
# @example seed-to-soil
97+
# maps = Day05.new(Day05::EXAMPLE_INPUT).parse
98+
# maps["seed-to-soil"].convert_with_skip(82) #=> [84, 15]
99+
# @example soil-to-fertilizer
100+
# maps = Day05.new(Day05::EXAMPLE_INPUT).parse
101+
# maps["soil-to-fertilizer"].convert_with_skip(84, 15) #=> [84, 15]
102+
# @example fertilizer-to-water
103+
# maps = Day05.new(Day05::EXAMPLE_INPUT).parse
104+
# maps["fertilizer-to-water"].convert_with_skip(84, 15) #=> [84, 15]
105+
# @example water-to-light
106+
# maps = Day05.new(Day05::EXAMPLE_INPUT).parse
107+
# maps["water-to-light"].convert_with_skip(84, 15) #=> [77, 10]
108+
# @example light-to-temperature
109+
# maps = Day05.new(Day05::EXAMPLE_INPUT).parse
110+
# maps["light-to-temperature"].convert_with_skip(77, 10) #=> [45, 10]
111+
# @example temperature-to-humidity
112+
# maps = Day05.new(Day05::EXAMPLE_INPUT).parse
113+
# maps["temperature-to-humidity"].convert_with_skip(45, 10) #=> [46, 10]
114+
# @example humidity-to-location
115+
# maps = Day05.new(Day05::EXAMPLE_INPUT).parse
116+
# maps["humidity-to-location"].convert_with_skip(46, 10) #=> [46, 9]
117+
#
118+
# logic copied enthusiastically from Brandon Mitchell; I couldn't figure it out
119+
def convert_with_skip(input, skip=-1)
120+
maps.each do |source_range, dest_start|
121+
if source_range.cover?(input)
122+
if skip && skip > source_range.size - (input - source_range.min) - 1
123+
skip = source_range.size - (input - source_range.min) - 1
124+
end
125+
return [dest_start + (input - source_range.min), skip]
126+
end
127+
if input < source_range.min && (skip < 0 || skip > source_range.min - input -1)
128+
skip = source_range.min - input - 1
129+
end
130+
end
131+
132+
return [input, skip]
133+
end
68134
end
69135

70136
EXAMPLE_INPUT = <<~INPUT

0 commit comments

Comments
 (0)