signed_multiset 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/joshwlewis/signed_multiset.png?branch=master)](https://travis-ci.org/joshwlewis/signed_multiset)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/joshwlewis/signed_multiset.png)](https://codeclimate.com/github/joshwlewis/signed_multiset)
|
5
|
+
[![Dependency Status](https://gemnasium.com/joshwlewis/signed_multiset.png)](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:
|