110 lines
3.0 KiB
Ruby
110 lines
3.0 KiB
Ruby
#prepare the input which is a string containing new lines
|
|
def parse(input)
|
|
data = []
|
|
map = []
|
|
input.each_line do |line|
|
|
if data.empty?
|
|
seed_ranges = []
|
|
seeds = line.split(":").last.split(" ").map(&:to_i)
|
|
(seeds.length/2).times do |i|
|
|
seed_ranges << [seeds[2*i],seeds[2*i+1]]
|
|
end
|
|
data << seed_ranges
|
|
next
|
|
end
|
|
if line.include?(":") && !map.empty?
|
|
data << map
|
|
map = []
|
|
next
|
|
end
|
|
next if line.include?(":")
|
|
next if line.strip.empty?
|
|
# build the map
|
|
target,source,ranges = line.split(" ").map(&:to_i)
|
|
diff = target-source
|
|
map << [source,ranges,diff]
|
|
end
|
|
data << map
|
|
data
|
|
end
|
|
|
|
# result should a single string or integer
|
|
def calculate(data)
|
|
seeds = nil
|
|
data.each do |d|
|
|
if seeds.nil?
|
|
seeds = d
|
|
next
|
|
end
|
|
# start mapping
|
|
i=0
|
|
d.each do |mapping|
|
|
new_seeds = []
|
|
map_start,map_range,diff = mapping
|
|
map_end = map_start + map_range -1
|
|
|
|
puts "map: #{map_start}--#{map_end} doing #{diff}"
|
|
seeds.each do |seed_pair|
|
|
seed_start,seed_range = seed_pair
|
|
seed_end = seed_start+seed_range
|
|
|
|
# <---|---|--->
|
|
if seed_start <= map_start && map_end <= seed_end
|
|
puts "<---|---|--->"
|
|
new_seed_start = seed_start
|
|
new_seed_range = map_start - seed_start
|
|
additional_start = map_start + diff
|
|
additional_range = map_end - map_start
|
|
third_start = map_end
|
|
third_end = seed_end - map_end
|
|
new_seeds << [new_seed_start,new_seed_range]
|
|
new_seeds << [additional_start,additional_range]
|
|
new_seeds << [third_start,third_end]
|
|
next
|
|
end
|
|
|
|
# |---<---|--->
|
|
if map_start <= seed_start && map_end >= seed_start && map_end <= seed_end
|
|
puts "|---<---|--->"
|
|
new_seed_start = seed_start + diff
|
|
new_seed_range = map_end - seed_start
|
|
additional_start = map_end
|
|
additional_range = seed_end - map_end
|
|
new_seeds << [new_seed_start,new_seed_range]
|
|
new_seeds << [additional_start,additional_range]
|
|
next
|
|
end
|
|
|
|
# <---|--->---|
|
|
if seed_start <= map_start && seed_end >= map_start && seed_end <= map_end
|
|
puts "<---|--->---|"
|
|
new_seed_start = seed_start
|
|
new_seed_range = map_start - seed_start
|
|
additional_start = map_start + diff
|
|
additional_range = seed_end - map_start
|
|
new_seeds << [new_seed_start,new_seed_range]
|
|
new_seeds << [additional_start,additional_range]
|
|
next
|
|
end
|
|
# |---<-->---|
|
|
if map_start <= seed_start && seed_end <= map_end
|
|
puts "|---<-->---|"
|
|
new_seed_start = seed_start + diff
|
|
new_seed_range = seed_range
|
|
new_seeds << [new_seed_start,new_seed_range]
|
|
next
|
|
end
|
|
|
|
# else
|
|
new_seeds << seed_pair
|
|
end
|
|
pp new_seeds
|
|
seeds = new_seeds
|
|
end
|
|
break if i==1
|
|
i+=1
|
|
end
|
|
seeds = seeds.map{|seed_pair| seed_pair[0]}
|
|
seeds.min
|
|
end
|