0.02
No commit activity in last 3 years
No release in over 3 years
Multisets with negative membership
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.3
>= 0
 Project Readme

signed_multiset

Gem Version Build Status Code Climate Dependency Status

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's functionality is very similar to Sorted Sets available in Redis (albeit without the storage functionality). It feels like a Ruby Hash or Array, but with some differences:

  • A key (any ruby object) can be added to or removed from the SignedMultiset any number of times. The number of times it is included in the multiset (positive or negative) is referred to as it's multiplicity.

  • A key can only be considered a member of the SignedMultiset if it's multiplicity is not 0. Setting it's multiplicity to 0 effectively removes that item from the SignedMultiset.

  • The size or length of a SignedMultiset is the number of unique keys with non-zero multiplicities.

  • The cardinality or sum of a SignedMultiset is the total sum of the multiplicities.

For futher reading, refer to Negative Membership by Wayne D. Blizard.

Installation

Add this line to your application's Gemfile:

gem 'signed_multiset'

And then execute:

$ bundle

Or install it yourself as:

$ gem install signed_multiset

Usage

require 'signed_multiset'

set = SignedMultiset.new(a: 1, b: 2, c: 3)
# => <SignedMultiset a: 1, b: 2, c: 3>

set[:b]
# => 2

set[:d] = -4
# => -4

set << :d
# => <SignedMultiset a: 1, b: 2, c: 3, d: -3>

set.increment(a, -1)
# => 0

set[:a]
# => nil

set
# => <SignedMultiset b: 2, c: 3, d: -3>

set.cardinality
# => 2

set.size
# => 3

other_set = SignedMultiset(:a, :c, :d, :d)
# => <SignedMultiset a: 1, c: 1, d: 2>

set + other_set
# => <SignedMultiset b: 2, c: 4, d: -1, a: 1>

set & other_set
# => <SignedMultiset c: 1, d: -3>

set | other_set
# => <SignedMultiset b: 2, c: 3, d: 2, a: 1>

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request