philiprehberger-interval 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6039cd1187d208aeb17ffae5d095d4dd9416fd8175f95084984600dc36c15b74
4
- data.tar.gz: 4cb497c7a97490954a47568a6b024e517f71a680f040644073b60b316f6fe174
3
+ metadata.gz: ecb8d7c68d3603d44c8df9a87a224c52300377809ad98ab1d19fe1a89ec13449
4
+ data.tar.gz: 75b3438103596f8a4de7f358a9f1cc25cd39fe5e80a47dfb6f25d38852e26964
5
5
  SHA512:
6
- metadata.gz: 60355c282c23da5623dc104947363632290343db018701c800f0b10e65bb64d87e5c5e0a69b08ca309ee7241318d92381cca64a1f9fc0f5be036a139d2258b9a
7
- data.tar.gz: 4c686abfd2318284ca810c87d25787804029ec3355039f56f3a859d3abdae8925704e0320a3ac6be192174dbe426fd28622ce73be36d514e0e18ae00b26117f1
6
+ metadata.gz: 78198caa2a0cf621b3545997e8fdfb58ad7424d7304e7d4367873dd69eaa02db2c91f1ed5a95cd365074be886063fb91941dea72180b2ce4e099c6e1982fddcf
7
+ data.tar.gz: 2dbb700fce8cd9cf5d973ab0baabece8e8b94e8d79f71939a805418f7fdfdbf626ca183ae9ab0fc18c2c036f21a2c0de9ddd28d90e1978da02139ac8eb3d1178
data/CHANGELOG.md CHANGED
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.4.0] - 2026-04-15
11
+
12
+ ### Added
13
+ - `Range#overlap_ratio(other)` — fraction of self covered by another interval (Float in 0.0–1.0)
14
+
15
+ ## [0.3.0] - 2026-04-15
16
+
17
+ ### Added
18
+ - `Interval.intersection(intervals)` — compute the common overlap of a collection of intervals
19
+
10
20
  ## [0.2.0] - 2026-04-03
11
21
 
12
22
  ### Added
data/README.md CHANGED
@@ -36,6 +36,7 @@ a.overlaps?(b) # => true
36
36
  a.intersect(b) # => [3, 5]
37
37
  a.union(b) # => [1, 8]
38
38
  a.include?(4) # => true
39
+ a.overlap_ratio(b) # => 0.5
39
40
  ```
40
41
 
41
42
  ### Interval Types
@@ -83,6 +84,19 @@ Philiprehberger::Interval.gaps(intervals)
83
84
  # => [[7, 10]]
84
85
  ```
85
86
 
87
+ ### Finding a Common Intersection
88
+
89
+ Compute the overlap shared by every interval, or `nil` if any pair is disjoint:
90
+
91
+ ```ruby
92
+ Philiprehberger::Interval.intersection([
93
+ Philiprehberger::Interval.new(1, 10),
94
+ Philiprehberger::Interval.new(3, 8),
95
+ Philiprehberger::Interval.new(5, 12)
96
+ ])
97
+ # => [5, 8]
98
+ ```
99
+
86
100
  ### With Time Values
87
101
 
88
102
  ```ruby
@@ -100,6 +114,7 @@ shift.include?(Time.new(2026, 1, 1, 12)) # => true
100
114
  | `#contains?(other)` | Check if interval fully contains another |
101
115
  | `#adjacent?(other)` | Check if intervals are touching but not overlapping |
102
116
  | `#intersect(other)` | Return the overlap between two intervals |
117
+ | `#overlap_ratio(other)` | Fraction of self covered by other (0.0–1.0) |
103
118
  | `#union(other)` | Return the combined interval |
104
119
  | `#subtract(other)` | Remove another interval, returning remaining parts |
105
120
  | `#size` | Length of the interval |
@@ -110,6 +125,7 @@ shift.include?(Time.new(2026, 1, 1, 12)) # => true
110
125
  | `#clamp(value)` | Clamp value to interval bounds |
111
126
  | `.merge(intervals)` | Merge overlapping intervals into non-overlapping set |
112
127
  | `.gaps(intervals)` | Find gaps between a set of intervals |
128
+ | `.intersection(intervals)` | Common overlap of a collection of intervals, or `nil` |
113
129
 
114
130
  ## Development
115
131
 
@@ -113,6 +113,23 @@ module Philiprehberger
113
113
  @finish - @start
114
114
  end
115
115
 
116
+ # Return the fraction of self that is covered by another interval.
117
+ #
118
+ # Returns a Float in 0.0..1.0. Returns 0.0 if disjoint, 1.0 if self is
119
+ # fully contained in other. If self has zero length (a point), returns
120
+ # 1.0 when the point is within other, else 0.0.
121
+ #
122
+ # @param other [Range] the other interval
123
+ # @return [Float] the fraction of self covered by other
124
+ def overlap_ratio(other)
125
+ return other.include?(@start) ? 1.0 : 0.0 if size.zero?
126
+
127
+ overlap = intersect(other)
128
+ return 0.0 if overlap.nil?
129
+
130
+ overlap.size.to_f / size
131
+ end
132
+
116
133
  # Check if a point is within the interval.
117
134
  #
118
135
  # @param point [Comparable] the point to check
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  module Interval
5
- VERSION = '0.2.0'
5
+ VERSION = '0.4.0'
6
6
  end
7
7
  end
@@ -39,6 +39,20 @@ module Philiprehberger
39
39
  merged
40
40
  end
41
41
 
42
+ # Compute the common overlap across a collection of intervals.
43
+ #
44
+ # @param intervals [Array<Range>] the intervals to intersect
45
+ # @return [Range, nil] the common intersection, or nil if any pair is disjoint
46
+ def self.intersection(intervals)
47
+ return nil if intervals.empty?
48
+
49
+ intervals[1..].reduce(intervals.first) do |acc, current|
50
+ return nil if acc.nil?
51
+
52
+ acc.intersect(current)
53
+ end
54
+ end
55
+
42
56
  # Find gaps between a collection of intervals.
43
57
  #
44
58
  # @param intervals [Array<Range>] the intervals to analyze
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philiprehberger-interval
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Philip Rehberger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-03 00:00:00.000000000 Z
11
+ date: 2026-04-15 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Interval data type supporting closed, open, and half-open boundaries
14
14
  with overlap detection, containment, intersection, union, subtraction, shift, scale,