Hoo boy 2025 ruby day 5
This commit is contained in:
parent
cdb3c720c5
commit
d3952a8ed2
6
ruby/2025/5/bin/problem
Normal file
6
ruby/2025/5/bin/problem
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require "ingredient_management"
|
||||||
|
im = IngredientManagement.for(STDIN.read.chomp)
|
||||||
|
puts "Part 1: #{im.fresh_ingredient_ids.count}"
|
||||||
|
puts "Part 2: #{im.all_fresh_ids_count}"
|
||||||
56
ruby/2025/5/lib/ingredient_management.rb
Normal file
56
ruby/2025/5/lib/ingredient_management.rb
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
class IngredientManagement
|
||||||
|
attr_reader :ranges, :ids
|
||||||
|
def initialize(ranges, ids)
|
||||||
|
@ranges = ranges
|
||||||
|
@ids = ids
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.for(input)
|
||||||
|
ranges, ids = input.split("\n\n")
|
||||||
|
new(
|
||||||
|
ranges.split("\n").map{ |r| s, e = r.split("-").map(&:to_i); s..e },
|
||||||
|
ids.split("\n").map(&:to_i)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def fresh?(id)
|
||||||
|
ranges.any? { |range| range.include? id }
|
||||||
|
end
|
||||||
|
|
||||||
|
def fresh_ingredient_ids
|
||||||
|
ids.select { |id| fresh? id }
|
||||||
|
end
|
||||||
|
|
||||||
|
def all_fresh_ids
|
||||||
|
# this makes it OOM!
|
||||||
|
# return ranges.map(&:to_a).flatten.uniq
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
|
def all_fresh_ids_count
|
||||||
|
combine_ranges.map(&:size).sum
|
||||||
|
end
|
||||||
|
|
||||||
|
def combine_two_ranges(r1, r2)
|
||||||
|
return [r1, r2] if r2.begin > r1.end || r1.begin > r2.end
|
||||||
|
|
||||||
|
[([r1.begin, r2.begin].min)..([r1.end, r2.end].max)]
|
||||||
|
end
|
||||||
|
|
||||||
|
def combine_ranges(rs = ranges)
|
||||||
|
rs.sort_by!(&:begin)
|
||||||
|
index = 0
|
||||||
|
while index < rs.length - 1
|
||||||
|
c2r = combine_two_ranges(rs[index], rs[index + 1])
|
||||||
|
if c2r.length == 2 # did not combine
|
||||||
|
index += 1
|
||||||
|
else # combined
|
||||||
|
rs.delete_at(index)
|
||||||
|
rs.delete_at(index)
|
||||||
|
rs.insert(index, c2r[0])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
rs
|
||||||
|
end
|
||||||
|
end
|
||||||
43
ruby/2025/5/test/test_ingredient_management.rb
Normal file
43
ruby/2025/5/test/test_ingredient_management.rb
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
require "minitest/autorun"
|
||||||
|
require "ingredient_management"
|
||||||
|
|
||||||
|
class TestIngredientManagement < Minitest::Test
|
||||||
|
def database
|
||||||
|
<<-END
|
||||||
|
3-5
|
||||||
|
10-14
|
||||||
|
16-20
|
||||||
|
12-18
|
||||||
|
|
||||||
|
1
|
||||||
|
5
|
||||||
|
8
|
||||||
|
11
|
||||||
|
17
|
||||||
|
32
|
||||||
|
END
|
||||||
|
end
|
||||||
|
def test_fresh_ingredient_ids
|
||||||
|
im = IngredientManagement.for(database)
|
||||||
|
assert_equal([1,5,8,11,17,32], im.ids)
|
||||||
|
assert_equal([3..5, 10..14, 16..20, 12..18], im.ranges)
|
||||||
|
assert_equal([5, 11, 17], im.fresh_ingredient_ids)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_all_fresh_ids_count
|
||||||
|
im = IngredientManagement.for(database)
|
||||||
|
assert_equal(14, im.all_fresh_ids_count)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_combine_two_ranges
|
||||||
|
im = IngredientManagement.new([], [])
|
||||||
|
assert_equal([1..6, 9..12], im.combine_two_ranges(1..6, 9..12))
|
||||||
|
assert_equal([1..12], im.combine_two_ranges(1..9, 6..12))
|
||||||
|
assert_equal([1..12], im.combine_two_ranges(1..9, 1..12))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_combine_ranges
|
||||||
|
im = IngredientManagement.new([1..2, 3..4, 2..6, 9..12], [])
|
||||||
|
assert_equal([1..6, 9..12], im.combine_ranges)
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in New Issue
Block a user