signed_multiset 0.0.1
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 +7 -0
- data/.gitignore +17 -0
- data/.ruby-version +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +65 -0
- data/Rakefile +10 -0
- data/lib/signed_multiset.rb +2 -0
- data/lib/signed_multiset/signed_multiset.rb +198 -0
- data/lib/signed_multiset/version.rb +3 -0
- data/signed_multiset.gemspec +25 -0
- data/test/signed_multiset/signed_multiset_test.rb +196 -0
- data/test/test_helper.rb +4 -0
- metadata +104 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 09a3ae9f761ec896d77d62a7a691f9fe65a20f09
|
4
|
+
data.tar.gz: 0f66bdd5eb798fece35bcd588bc90a50e1c22d81
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a30b92054d69d03ebfa1947fd8505f81ce57d7f1230095ec2ffff274910232a26596c8af4df9bfba87cacaab441e6704cc9b1fcde7477969b4411282628dc382
|
7
|
+
data.tar.gz: 45684d6839b35ffe4c26073fd4d026064b2aa251ef8aee35eb07c1408ab1b4cfbf97d3e073dd2f4d098861a05247c64c4b8bbea4dfeeb3233ce5814ce3b3dd89
|
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.0.0-p195
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Josh Lewis
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# signed_multiset
|
2
|
+
|
3
|
+
[](https://travis-ci.org/joshwlewis/signed_multiset)
|
4
|
+
[](https://codeclimate.com/github/joshwlewis/signed_multiset)
|
5
|
+
[](https://gemnasium.com/joshwlewis/signed_multiset)
|
6
|
+
|
7
|
+
Signed Multiset is a Ruby implementation of a Multiset that allows negative membership.
|
8
|
+
|
9
|
+
You can think of it as a Multiset or Bag that allows for negative counts. It feels like a Ruby Hash or Array, but with some differences:
|
10
|
+
|
11
|
+
- A key (any ruby object) can be added to or removed from the Multiset any number of times, and is referred to as it's multiplicity
|
12
|
+
|
13
|
+
- A key can only be considered a member of the Signed Multiset if it's multiplicity is not 0. Setting it's multiplicity to 0 effectively removes that item from the SignedMultiset.
|
14
|
+
|
15
|
+
- The size or length of a SignedMultiset is the number of unique keys with non-zero multiplicities.
|
16
|
+
|
17
|
+
- The cardinality or sum of a SignedMultiset is the total sum of the multiplicities.
|
18
|
+
|
19
|
+
For theory and proofs, refer to [Negative Membership](http://projecteuclid.org/DPubS/Repository/1.0/Disseminate?view=body&id=pdf_1&handle=euclid.ndjfl/1093635499) by Wayne D. Blizard.
|
20
|
+
|
21
|
+
## Installation
|
22
|
+
|
23
|
+
Add this line to your application's Gemfile:
|
24
|
+
|
25
|
+
gem 'signed_multiset'
|
26
|
+
|
27
|
+
And then execute:
|
28
|
+
|
29
|
+
$ bundle
|
30
|
+
|
31
|
+
Or install it yourself as:
|
32
|
+
|
33
|
+
$ gem install signed_multiset
|
34
|
+
|
35
|
+
## Usage
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
require 'signed_multiset'
|
39
|
+
|
40
|
+
s = SignedMultiset.new(a: 1, b: 2, c: 3)
|
41
|
+
#=> => <SignedMultiset a: 1, b: 2, c: 3>
|
42
|
+
|
43
|
+
s[:b]
|
44
|
+
#=> 2
|
45
|
+
|
46
|
+
s[:d] = -4
|
47
|
+
#=> -4
|
48
|
+
|
49
|
+
s << :d
|
50
|
+
#=> <SignedMultiset a: 1, b: 2, c: 3, d: -3>
|
51
|
+
|
52
|
+
s.increment(a, -1)
|
53
|
+
#=> 0
|
54
|
+
|
55
|
+
s[:a]
|
56
|
+
#=> nil
|
57
|
+
```
|
58
|
+
|
59
|
+
## Contributing
|
60
|
+
|
61
|
+
1. Fork it
|
62
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
63
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
64
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
65
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,198 @@
|
|
1
|
+
class SignedMultiset
|
2
|
+
|
3
|
+
include Enumerable
|
4
|
+
include Comparable
|
5
|
+
|
6
|
+
# Create a new instance with a list of objects.
|
7
|
+
#
|
8
|
+
# @param *list [Object] A list of objects to add to the set
|
9
|
+
def self.[](*list)
|
10
|
+
new(list)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Create a new SignedMultiset instance.
|
14
|
+
#
|
15
|
+
# @param object [Enumerable, nil] An array of keys, or key-muliplicity pairs.
|
16
|
+
def initialize(object=nil)
|
17
|
+
if object.is_a?(Enumerable)
|
18
|
+
object.each { |k, v| increment(k, v || 1) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Get the non-zero key-multiplicity pairs.
|
23
|
+
#
|
24
|
+
# @return [Hash]
|
25
|
+
def multiplicities
|
26
|
+
entries.delete_if{|k,v| v == 0}
|
27
|
+
end
|
28
|
+
|
29
|
+
# Iterate over the multiplicity collection.
|
30
|
+
#
|
31
|
+
# @return [Enumerator]
|
32
|
+
def each(*args, &block)
|
33
|
+
if block_given?
|
34
|
+
multiplicities.each { |k,v| yield(k,v) }
|
35
|
+
else
|
36
|
+
multiplicities.each(args)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Get the multiplicity for a key.
|
41
|
+
#
|
42
|
+
# @param key [Object] The key to get the multiplicity of
|
43
|
+
# @return [Integer, nil] The multiplicity for the key, or nil if the key is
|
44
|
+
# not present, or has a zero multiplicity
|
45
|
+
def [](key)
|
46
|
+
multiplicities[key]
|
47
|
+
end
|
48
|
+
|
49
|
+
# Set the multiplicity for a key.
|
50
|
+
#
|
51
|
+
# @param key [Object] The key to set the multiplicity of
|
52
|
+
# @param multiplicity [Integer] The desired multiplicity
|
53
|
+
# @return [Integer] The multiplicity for the key
|
54
|
+
def []=(key, multiplicity)
|
55
|
+
entries[key] = multiplicity
|
56
|
+
multiplicities[key]
|
57
|
+
end
|
58
|
+
|
59
|
+
# Increment the multiplicity for a key.
|
60
|
+
#
|
61
|
+
# @param key (see #[]=)
|
62
|
+
# @param value [Integer] The desired increment value, positive or negative
|
63
|
+
# @return (see #[]=)
|
64
|
+
def increment(key, value)
|
65
|
+
entries[key] ||= 0
|
66
|
+
entries[key] += value
|
67
|
+
end
|
68
|
+
|
69
|
+
# Increment multiplicity by 1 for a key. This method is chainable.
|
70
|
+
#
|
71
|
+
# @param key [Object] The key to increment the multiplicity of
|
72
|
+
# @return [self]
|
73
|
+
def <<(key)
|
74
|
+
increment(key, 1)
|
75
|
+
self
|
76
|
+
end
|
77
|
+
|
78
|
+
# Creates a new instance of equal to current instance
|
79
|
+
# @return [SignedMultiset]
|
80
|
+
def dup
|
81
|
+
self.class.new(multiplicities)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Combine self with another SignedMultiset via addition to create a merged instance.
|
85
|
+
#
|
86
|
+
# @param other [SignedMultiset]
|
87
|
+
# @return [SignedMultiset]
|
88
|
+
def +(other)
|
89
|
+
other.multiplicities.reduce(self.dup) do |m, (k, v)|
|
90
|
+
m.increment(k,v); m
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Combine self with another SignedMultiset via subtraction to create a merged instance.
|
95
|
+
#
|
96
|
+
# @param other (see #+)
|
97
|
+
# @return (see #+)
|
98
|
+
def -(other)
|
99
|
+
other.multiplicities.reduce(self.dup) do |m, (k, v)|
|
100
|
+
m.increment(k,-v); m
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Combine self with another SignedMultiset via union to create a merged instance.
|
105
|
+
#
|
106
|
+
# @param other (see #+)
|
107
|
+
# @return (see #+)
|
108
|
+
def |(other)
|
109
|
+
(keys | other.keys).reduce(self.class.new) do |m, k|
|
110
|
+
m.increment(k, [self[k] || 0, other[k] || 0].max); m
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Combine self with another SignedMultiset via intersection to create a merged instance.
|
115
|
+
#
|
116
|
+
# @param other (see #+)
|
117
|
+
# @return (see #+)
|
118
|
+
def &(other)
|
119
|
+
(keys & other.keys).reduce(self.class.new) do |m, k|
|
120
|
+
value = [self[k], other[k]].min
|
121
|
+
m.increment(k, value); m
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Get the list of keys for self.
|
126
|
+
#
|
127
|
+
# @return [Array]
|
128
|
+
def keys
|
129
|
+
multiplicities.keys
|
130
|
+
end
|
131
|
+
|
132
|
+
# Get the multiplicity values for self.
|
133
|
+
#
|
134
|
+
# @return [Array]
|
135
|
+
def values
|
136
|
+
multiplicities.values
|
137
|
+
end
|
138
|
+
|
139
|
+
# Get the cardinality (sum of multiplicities) for self.
|
140
|
+
#
|
141
|
+
# @return [Integer]
|
142
|
+
def cardinality
|
143
|
+
values.inject(&:+)
|
144
|
+
end
|
145
|
+
alias_method :sum, :cardinality
|
146
|
+
|
147
|
+
# Get the count of unique keys in the SignedMultiset.
|
148
|
+
#
|
149
|
+
# @return [Integer]
|
150
|
+
def size
|
151
|
+
keys.size
|
152
|
+
end
|
153
|
+
alias_method :length, :size
|
154
|
+
|
155
|
+
# Compare self with another SignedMultiset
|
156
|
+
#
|
157
|
+
# @param other (see #+)
|
158
|
+
# @return [-1,0,1]
|
159
|
+
def <=>(other)
|
160
|
+
if [:multiplicities, :cardinality, :size].all? { |m| other.respond_to?(m) }
|
161
|
+
if multiplicities == other.multiplicities
|
162
|
+
0
|
163
|
+
elsif cardinality != other.cardinality
|
164
|
+
cardinality <=> other.cardinality
|
165
|
+
elsif size != other.size
|
166
|
+
size <=> other.size
|
167
|
+
else
|
168
|
+
multiplicities <=> other.multiplicities
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def to_hash
|
174
|
+
multiplicities.dup
|
175
|
+
end
|
176
|
+
|
177
|
+
def to_a
|
178
|
+
multiplicities.to_a
|
179
|
+
end
|
180
|
+
|
181
|
+
def to_s
|
182
|
+
multiplicities.map{ |k,c| "#{k}: #{c}"}.join(', ')
|
183
|
+
end
|
184
|
+
|
185
|
+
def inspect
|
186
|
+
"<SignedMultiset #{to_s}>"
|
187
|
+
end
|
188
|
+
|
189
|
+
private
|
190
|
+
|
191
|
+
# Get the key-multiplicity pairs (even those with zero multiplicities).
|
192
|
+
#
|
193
|
+
# @return [Hash]
|
194
|
+
def entries
|
195
|
+
@entries ||= {}
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'signed_multiset/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "signed_multiset"
|
8
|
+
spec.version = SignedMultiset::VERSION
|
9
|
+
spec.authors = ["Josh Lewis"]
|
10
|
+
spec.email = ["josh.w.lewis@gmail.com"]
|
11
|
+
spec.description = %q{Multisets with negative membership}
|
12
|
+
spec.summary = %q{Signed Multiset is a Ruby implementation of a Multiset that allows negative membership. You can think of it as a Multiset or Bag that allows for negative counts. It feels like a Ruby Hash or Array, but with some differences.}
|
13
|
+
spec.homepage = "http://github.com/joshwlewis/signed_multiset"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "minitest"
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe SignedMultiset do
|
4
|
+
subject { SignedMultiset.new(foo: 4, bar: 2, baz: 0) }
|
5
|
+
let(:other){ SignedMultiset.new(foo: -3, qux: 2) }
|
6
|
+
|
7
|
+
describe "#initialize" do
|
8
|
+
it "must accept a hash" do
|
9
|
+
subject.keys.must_equal([:foo, :bar])
|
10
|
+
end
|
11
|
+
it "must accept no arguments" do
|
12
|
+
set = SignedMultiset.new
|
13
|
+
set.keys.must_equal([])
|
14
|
+
end
|
15
|
+
it "must accept an Array" do
|
16
|
+
set = SignedMultiset.new([:a, :b, :c, :a, :b])
|
17
|
+
set.keys.must_equal([:a, :b, :c])
|
18
|
+
end
|
19
|
+
it "must accept a SignedMultiset" do
|
20
|
+
set = SignedMultiset.new(subject)
|
21
|
+
set.keys.must_equal([:foo, :bar])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "::[]" do
|
26
|
+
it "must create a new set" do
|
27
|
+
set = SignedMultiset[:a, :b, :b, :c]
|
28
|
+
set.keys.must_equal([:a, :b, :c])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "multiplicities" do
|
33
|
+
it "must be an Enumerable" do
|
34
|
+
subject.multiplicities.must_be_kind_of(Enumerable)
|
35
|
+
end
|
36
|
+
it "should delete keys with zero multiplicitys" do
|
37
|
+
subject.multiplicities.keys.must_equal([:foo, :bar])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#[]" do
|
42
|
+
it "must find existing keys and return multiplicity" do
|
43
|
+
subject[:foo].must_equal(4)
|
44
|
+
subject[:bar].must_equal(2)
|
45
|
+
end
|
46
|
+
it "must return nil for missing keys" do
|
47
|
+
subject[:qux].must_be_nil
|
48
|
+
end
|
49
|
+
it "must return nil for keys with zero multiplicitys" do
|
50
|
+
subject[:bax].must_be_nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#[]=" do
|
55
|
+
it "must set multiplicity for exisiting keys" do
|
56
|
+
subject[:foo].must_equal(4)
|
57
|
+
subject[:foo] = -1
|
58
|
+
subject[:foo].must_equal(-1)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "must increment key and set multiplicity for new keys" do
|
62
|
+
subject[:baz].must_be_nil
|
63
|
+
subject[:baz] = 3
|
64
|
+
subject[:baz].must_equal(3)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "increment" do
|
69
|
+
it "should increment existing keys" do
|
70
|
+
subject[:bar].must_equal(2)
|
71
|
+
subject.increment(:bar, -4)
|
72
|
+
subject[:bar].must_equal(-2)
|
73
|
+
end
|
74
|
+
it "should increment new keys" do
|
75
|
+
subject[:qux].must_be_nil
|
76
|
+
subject.increment(:qux, 2)
|
77
|
+
subject[:qux].must_equal(2)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "<<" do
|
82
|
+
it "should increment existing keys" do
|
83
|
+
subject[:bar].must_equal(2)
|
84
|
+
subject << :bar
|
85
|
+
subject[:bar].must_equal(3)
|
86
|
+
end
|
87
|
+
it "should increment new keys" do
|
88
|
+
subject[:qux].must_be_nil
|
89
|
+
subject << :qux
|
90
|
+
subject[:qux].must_equal(1)
|
91
|
+
end
|
92
|
+
it "should be chainable" do
|
93
|
+
subject << :foo << :baz << :foo
|
94
|
+
subject[:foo].must_equal(6)
|
95
|
+
subject[:baz].must_equal(1)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "#+" do
|
100
|
+
let(:merged) { subject + other }
|
101
|
+
it "should return a new set" do
|
102
|
+
merged.must_be_instance_of(SignedMultiset)
|
103
|
+
merged.wont_equal(subject)
|
104
|
+
merged.wont_equal(other)
|
105
|
+
end
|
106
|
+
it "should sum the keys" do
|
107
|
+
merged[:foo].must_equal(1)
|
108
|
+
merged[:bar].must_equal(2)
|
109
|
+
merged[:qux].must_equal(2)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "#-" do
|
114
|
+
let(:merged) { subject - other }
|
115
|
+
it "should return a new set" do
|
116
|
+
merged.must_be_instance_of(SignedMultiset)
|
117
|
+
merged.wont_equal(subject)
|
118
|
+
merged.wont_equal(other)
|
119
|
+
end
|
120
|
+
it "should sum the keys" do
|
121
|
+
merged[:foo].must_equal(7)
|
122
|
+
merged[:bar].must_equal(2)
|
123
|
+
merged[:qux].must_equal(-2)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "#&" do
|
128
|
+
let(:merged) { subject & other }
|
129
|
+
it "should reutrn a new set" do
|
130
|
+
subject.must_be_instance_of(SignedMultiset)
|
131
|
+
merged.wont_equal(subject)
|
132
|
+
merged.wont_equal(other)
|
133
|
+
end
|
134
|
+
it "should return the intersection" do
|
135
|
+
merged[:foo].must_equal(-3)
|
136
|
+
merged[:bar].must_be_nil
|
137
|
+
merged[:baz].must_be_nil
|
138
|
+
merged[:qux].must_be_nil
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "#|" do
|
143
|
+
let(:merged) { subject | other }
|
144
|
+
it "should reutrn a new set" do
|
145
|
+
subject.must_be_instance_of(SignedMultiset)
|
146
|
+
merged.wont_equal(subject)
|
147
|
+
merged.wont_equal(other)
|
148
|
+
end
|
149
|
+
it "should return the union" do
|
150
|
+
merged[:foo].must_equal(4)
|
151
|
+
merged[:bar].must_equal(2)
|
152
|
+
merged[:baz].must_be_nil
|
153
|
+
merged[:qux].must_equal(2)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "#to_hash" do
|
158
|
+
it "should return a hash" do
|
159
|
+
subject.to_hash.must_equal(foo: 4, bar: 2)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe "#to_a" do
|
164
|
+
it "should return an Array" do
|
165
|
+
subject.to_a.must_equal([[:foo, 4], [:bar, 2]])
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe "#cardinality" do
|
170
|
+
it "should return the total of all multiplicitys" do
|
171
|
+
subject.cardinality.must_equal(6)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe "#size" do
|
176
|
+
it "should return the multiplicity of non-zero keys" do
|
177
|
+
subject.size.must_equal(2)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe "#<=>" do
|
182
|
+
let(:small) { SignedMultiset[:foo, :bar] }
|
183
|
+
let(:large) { SignedMultiset[:foo, :bar, :baz, :foo, :bar, :qux, :foo, :bar] }
|
184
|
+
let(:equal) { subject.dup }
|
185
|
+
|
186
|
+
it "should return 1 when compared to a smaller set" do
|
187
|
+
(subject <=> small).must_equal(1)
|
188
|
+
end
|
189
|
+
it "should return -1 when compared to a larger set" do
|
190
|
+
(subject <=> large).must_equal(-1)
|
191
|
+
end
|
192
|
+
it "should return 0 when compared to an equal set" do
|
193
|
+
(subject <=> equal).must_equal(0)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: signed_multiset
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Josh Lewis
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-06-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Multisets with negative membership
|
56
|
+
email:
|
57
|
+
- josh.w.lewis@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- .ruby-version
|
64
|
+
- .travis.yml
|
65
|
+
- Gemfile
|
66
|
+
- LICENSE.txt
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- lib/signed_multiset.rb
|
70
|
+
- lib/signed_multiset/signed_multiset.rb
|
71
|
+
- lib/signed_multiset/version.rb
|
72
|
+
- signed_multiset.gemspec
|
73
|
+
- test/signed_multiset/signed_multiset_test.rb
|
74
|
+
- test/test_helper.rb
|
75
|
+
homepage: http://github.com/joshwlewis/signed_multiset
|
76
|
+
licenses:
|
77
|
+
- MIT
|
78
|
+
metadata: {}
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options: []
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubyforge_project:
|
95
|
+
rubygems_version: 2.0.2
|
96
|
+
signing_key:
|
97
|
+
specification_version: 4
|
98
|
+
summary: Signed Multiset is a Ruby implementation of a Multiset that allows negative
|
99
|
+
membership. You can think of it as a Multiset or Bag that allows for negative counts.
|
100
|
+
It feels like a Ruby Hash or Array, but with some differences.
|
101
|
+
test_files:
|
102
|
+
- test/signed_multiset/signed_multiset_test.rb
|
103
|
+
- test/test_helper.rb
|
104
|
+
has_rdoc:
|