range_list_barry 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/range_list.rb +111 -0
  3. metadata +43 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b4305219593ab7b1dd9998ed1a9e6211663a3cc38c21afc830e1504ea5b6228b
4
+ data.tar.gz: e476b3a3549bdbe246bb1562d2f186cede26bb81f0e9ab279597953ee9f7d1f3
5
+ SHA512:
6
+ metadata.gz: 65050613f0354ac69fc77eae564396fe5f1eef78996095a71138e7b6a2d98765daa2554dc6300972e87c1c40e8cbb9e2684a272eef4c9cb05f868611776d6f27
7
+ data.tar.gz: e8ab26c327ac65cc37b29856f37dd5ece2758cf69bebe63f88d4de50ea5db8071781e4f1c530905e3eae660cf5dfd17fc4ca469c50bdc92ef0e39fd521ce4977
data/lib/range_list.rb ADDED
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ require './lib/range_list/intersection'
4
+ require './lib/range_list/verify_range'
5
+
6
+ ##
7
+ # A pair of integers define a range, for example: [1, 5). This range includes integers: 1, 2, 3, and 4.
8
+ # A range list is an aggregate of these ranges: [1, 5), [10, 11), [100, 201)
9
+ class RangeList
10
+ attr_reader :range_list
11
+
12
+ def initialize
13
+ @range_list = {}
14
+ end
15
+
16
+ # @param [Array<Integer>] range
17
+ # @return [Hash] return the sorted hash representation of the range list.
18
+ def add(range)
19
+ veryify_range!(range)
20
+
21
+ # we need to modify the value in the hash, so disable HashEachMethods cop.
22
+ # rubocop:disable Style/HashEachMethods
23
+ @range_list.keys.each do |key|
24
+ intersection = intersection(range, [key, @range_list[key]])
25
+ next unless intersection
26
+
27
+ # 增加新的range时, 如果有交集, 则需要将交集的range更新为[min, max]
28
+ min = [key, range[0]].min
29
+ @range_list[min] = @range_list.delete(key)
30
+
31
+ max = [@range_list[min], range[1]].max
32
+ @range_list[min] = max
33
+ return remove_overlapped_range
34
+ end
35
+ # rubocop:enable Style/HashEachMethods
36
+
37
+ # when no intersection, insert to hash
38
+ insert(range)
39
+ end
40
+
41
+ # rubocop:disable Style/HashEachMethods
42
+ # rubocop:disable Metrics/AbcSize
43
+ #
44
+ # @param [Array<Integer>] range
45
+ # @return [Hash] return the sorted hash representation of the range list
46
+ def remove(range)
47
+ veryify_range!(range)
48
+
49
+ @range_list.keys.each do |key|
50
+ intersection = intersection(range, [key, @range_list[key]])
51
+ next unless intersection&.max # an intersecion might not has max becuase the range[0] = range[1]
52
+
53
+ # 如果intersection.min == key, 则需要删除key, 创建新的hash {intersection.max => @range_list[key]}
54
+ # 如果intersection.min > key, 则需要删除key, 创建更新hash {key => intersection.min}
55
+ # 如果value > intersection.max, 则需要创建更新hash {intersection.max => value}
56
+ @range_list[intersection.max] = @range_list[key] if @range_list[key] > intersection.max
57
+
58
+ if intersection.min == key
59
+ @range_list[intersection.max] = @range_list.delete(key)
60
+ elsif intersection.min > key
61
+ @range_list[key] = intersection.min
62
+ end
63
+ end
64
+
65
+ sorted_range_list
66
+ end
67
+ # rubocop:enable Style/HashEachMethods
68
+ # rubocop:enable Metrics/AbcSize
69
+
70
+ ##
71
+ # Print all the ranges in format: [1, 5) [10, 20)
72
+ def print
73
+ str = ''
74
+ sorted_range_list.each do |key, value|
75
+ str += "[#{key}, #{value}) " unless key == value
76
+ end
77
+ puts str
78
+ end
79
+
80
+ # @return [String] return all the ranges in hash format
81
+ def inspect
82
+ sorted_range_list
83
+ end
84
+
85
+ private
86
+
87
+ # @params [Array<Integer>] range
88
+ # insert the range to range_list hash
89
+ def insert(range)
90
+ @range_list[range[0]] = range[1]
91
+ sorted_range_list
92
+ end
93
+
94
+ def sorted_range_list
95
+ @range_list.sort.to_h.reject { |key, value| key == value }
96
+ end
97
+
98
+ def remove_overlapped_range
99
+ return sorted_range_list if @range_list.length == 1
100
+
101
+ groups = @range_list.sort.map { |key, value| [key, value] }
102
+
103
+ # only need to iterate to the second last group, because we know the last group is not overlapped
104
+ groups[0..-2].each_with_index do |group, i|
105
+ groups.delete_at(i + 1) if group[1] > groups[i + 1][0]
106
+ end
107
+ @range_list = groups.to_h
108
+
109
+ sorted_range_list
110
+ end
111
+ end
metadata ADDED
@@ -0,0 +1,43 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: range_list_barry
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - uooobarry
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-06-25 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A simple range list gem
14
+ email: huahua.personal@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/range_list.rb
20
+ homepage: https://jihulab.com/UoooBarry/rangelist
21
+ licenses:
22
+ - MIT
23
+ metadata: {}
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ requirements: []
39
+ rubygems_version: 3.3.3
40
+ signing_key:
41
+ specification_version: 4
42
+ summary: Ruby implementation of range list.
43
+ test_files: []