From b26479a0801a9c5419b1f191d59f2bc9e230da2d Mon Sep 17 00:00:00 2001 From: jbranchaud Date: Thu, 6 Jan 2022 15:47:51 -0600 Subject: [PATCH] Add Check For Any Overlaps In List Of Ranges as a Ruby til --- README.md | 3 +- ...heck-for-any-overlaps-in-list-of-ranges.md | 43 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 ruby/check-for-any-overlaps-in-list-of-ranges.md diff --git a/README.md b/README.md index d03c990..30c8378 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ pairing with smart people at Hashrocket. For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186). -_1178 TILs and counting..._ +_1179 TILs and counting..._ --- @@ -905,6 +905,7 @@ _1178 TILs and counting..._ - [Block Comments](ruby/block-comments.md) - [Build HTTP And HTTPS URLs](ruby/build-http-and-https-urls.md) - [Chaining Multiple RSpec Change Matchers](ruby/chaining-multiple-rspec-change-matchers.md) +- [Check For Any Overlaps In List Of Ranges](ruby/check-for-any-overlaps-in-list-of-ranges.md) - [Check If An Object Includes A Module](ruby/check-if-an-object-includes-a-module.md) - [Check Return Status Of Running A Shell Command](ruby/check-return-status-of-running-a-shell-command.md) - [Click On Text With Capybara](ruby/click-on-text-with-capybara.md) diff --git a/ruby/check-for-any-overlaps-in-list-of-ranges.md b/ruby/check-for-any-overlaps-in-list-of-ranges.md new file mode 100644 index 0000000..0e44276 --- /dev/null +++ b/ruby/check-for-any-overlaps-in-list-of-ranges.md @@ -0,0 +1,43 @@ +# Check For Any Overlaps In List Of Ranges + +If you have a list of things, such as meetings, you may want to be able to tell +if there are any conflicts. You could determine that by finding any overlaps in +their timeslots. + +Ranges are a good way to represent any span of data, including a timeslot. + +To do this in Ruby, we'll need two pieces. First, a way to determine if two +`Range` objects are overlapping. Second, an iterative utility for comparing +each range to every other range. + +Here is an `overlaps?` method that uses `Range#begin` and `Range#end`. + +```ruby +def overlaps?(range1, range2) + range1.begin <= range2.end && range2.begin <= range1.end +end +``` + +And here is an `any_overlaps?` method to find any overlaps over a list of +ranges. + +```ruby +def any_overlaps?(ranges) + ranges.each_with_index do |range1, i| + ranges.each_with_index do |range2, j| + return true if i != j && overlaps?(range1, range2) + end + end + + false +end + +puts any_overlaps?([(1..2), (3..4)]) #=> false +puts any_overlaps?([(1..2), (2..4)]) #=> true +puts any_overlaps?([(3..4), (1..5)]) #=> true +``` + +This second method isn't optimized, but it will work just fine for small lists +of ranges. + +[source](https://stackoverflow.com/questions/39934266/check-if-two-ranges-overlap-in-ruby)