Last active
December 6, 2023 14:51
-
-
Save carlwiedemann/d7111102935b24a3199250a4e79da969 to your computer and use it in GitHub Desktop.
Advent of Code 2023 day005.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require_relative "main" | |
module Day005 | |
INPUT = File.read('INPUT.txt') | |
lines = INPUT.to_lines | |
seeds = lines.shift.split(":").last.split_strip(" ").map(&:to_i) | |
lines.shift | |
categories = [] | |
lines.each do |line| | |
matches = /([a-z]+)-to-([a-z]+)/.match(line) | |
if matches | |
categories.push([]) | |
elsif line != "" | |
parts = line.split_strip(" ").map(&:to_i) | |
dest_start = parts[0] | |
source_start = parts[1] | |
size = parts[2] | |
dest_end = dest_start + size - 1 | |
source_end = source_start + size - 1 | |
categories.last.push({ | |
source: (source_start..source_end), | |
dest: (dest_start..dest_end) | |
}) | |
end | |
end | |
seed_to_location = ->(seed) do | |
cursor = seed | |
categories.each do |category| | |
found = false | |
category.each do |map| | |
if map[:source].include?(cursor) | |
found = true | |
source_i = cursor - map[:source].first | |
dest_v = map[:dest].first + source_i | |
cursor = dest_v | |
end | |
break if found | |
end | |
end | |
cursor | |
end | |
location_to_seed = ->(location) do | |
cursor = location | |
categories.reverse.each do |category| | |
found = false | |
category.each do |map| | |
if map[:dest].include?(cursor) | |
found = true | |
dest_i = cursor - map[:dest].first | |
source_v = map[:source].first + dest_i | |
cursor = source_v | |
end | |
break if found | |
end | |
end | |
cursor | |
end | |
########## | |
# Part 1 # | |
########## | |
min1 = nil | |
seeds.each do |seed| | |
cursor = seed_to_location.call(seed) | |
min1 = cursor if min1.nil? || cursor < min1 | |
end | |
answer1 = min1 | |
pp answer1 | |
########## | |
# Part 2 # | |
########## | |
seed_ranges = seeds.each_slice(2).map do |pair| | |
first = pair[0] | |
last = pair[0] + pair[1] | |
(first..last) | |
end | |
# Let's try 100,000 values, spaced 100 apart | |
min2 = nil | |
100000.times do |i| | |
j = i * 100 | |
seed = location_to_seed.call(j) | |
break_all = false | |
seed_ranges.filter.with_index do |range| | |
if range.include?(seed) | |
k = j | |
loop do | |
seed2 = location_to_seed.call(k) | |
if range.include?(seed2) | |
min2 = k if min2.nil? || k < min2 | |
else | |
break_all = true | |
break | |
end | |
k -= 1 | |
end | |
end | |
break if break_all | |
end | |
break if break_all | |
end | |
answer2 = min2 | |
pp answer2 | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment