sperm 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2ef71a04bbb2e84a9baa9d94c78c7d2f0a2d3ac3
4
+ data.tar.gz: 343595cd65a161078b48c082bdca8bf0f44c17e9
5
+ SHA512:
6
+ metadata.gz: b674a6080bf35a001cbc34064b0de3de3ac9181d2e52c6039560e03c3678d7c6b5ee2ae05f72946ac76c76d62d05d84c94f34ae66bc0396b1bf19b7d451281aa
7
+ data.tar.gz: 568b52e9c823c7ca2578133cd733813075e32951e2c0785b9e13b99a46f70e6e7a07e8cebe95b07448773fd4090ab092170b0ec7f82125d7e17d004c64fd0df3
@@ -0,0 +1,12 @@
1
+ # editorconfig.org
2
+ root = true
3
+
4
+ [*]
5
+ indent_style = space
6
+ indent_size = 2
7
+ charset = utf-8
8
+ trim_trailing_whitespace = true
9
+ insert_final_newline = true
10
+
11
+ [*.md]
12
+ trim_trailing_whitespace = false
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ vendor
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ AllCops:
2
+ Excludes:
3
+ - vendor/**
4
+ LineLength:
5
+ Max: 119
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1.0
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Arthur Khashaev
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.
@@ -0,0 +1,53 @@
1
+ # Stupendous Permutations
2
+ **Sperm** is a random permutations generator based on the ideas of group
3
+ theory that allows you to generate very large permutations without extra
4
+ memory consumption.
5
+
6
+ [![Gem Version](https://badge.fury.io/rb/sperm.png)](https://badge.fury.io/rb/sperm)
7
+ [![Build Status](https://travis-ci.org/Invizory/sperm.png)](https://travis-ci.org/Invizory/sperm)
8
+ [![Code Climate](https://codeclimate.com/github/Invizory/sperm.png)](https://codeclimate.com/github/Invizory/sperm)
9
+ [![Coverage Status](https://coveralls.io/repos/Invizory/sperm/badge.png)](https://coveralls.io/r/Invizory/sperm)
10
+
11
+ ## Installation
12
+ Add this line to your application's Gemfile:
13
+ ```ruby
14
+ gem 'sperm'
15
+ ```
16
+
17
+ And then execute:
18
+ ```bash
19
+ $ bundle
20
+ ```
21
+
22
+ Or install it yourself as:
23
+ ```bash
24
+ $ gem install sperm
25
+ ```
26
+
27
+ ## Usage
28
+ ```ruby
29
+ Sperm.rand(5).each { |element| puts element }
30
+ ```
31
+
32
+ This is a shorthand for:
33
+ ```ruby
34
+ Sperm::RandomPermutations.new(5).rand.each { |element| puts element }
35
+ ```
36
+
37
+ You can also use your own source of randomness:
38
+ ```ruby
39
+ Sperm::RandomPermutations.new(5, Random.new(42))
40
+ Sperm::RandomPermutations.new(10**8, SecureRandom)
41
+ ```
42
+
43
+ ## How it works
44
+ ### Computational complexity
45
+ Operation | Time complexity | Space complexity
46
+ ---------------------------|--------------------|------------------
47
+ Initialization | O(n/ϕ(n) · log(n)) | O(1)
48
+ Generation of next element | O(1) | O(1)
49
+
50
+ ## Copyright
51
+ Copyright © 2014 [Arthur Khashaev]. See [LICENSE.txt](LICENSE.txt) for details.
52
+
53
+ [Arthur Khashaev]: http://khashaev.ru/
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rubocop/rake_task'
3
+ require 'rspec/core/rake_task'
4
+
5
+ Rubocop::RakeTask.new
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :default => :spec
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'sperm'
4
+ require 'optparse'
5
+
6
+ optparse = OptionParser.new do |opts|
7
+ opts.banner = "Usage: #{$PROGRAM_NAME} [options] order"
8
+
9
+ opts.on_tail '-p', '--permutation ORDER', Integer,
10
+ 'Generate permutation of specified order' do |order|
11
+ Sperm.rand(order).each { |element| puts element }
12
+ exit
13
+ end
14
+
15
+ opts.on_tail '-h', '--help', 'Just display this help' do
16
+ puts opts
17
+ exit
18
+ end
19
+
20
+ opts.on_tail '-v', '--version', 'Just print the version infomation' do
21
+ puts "Sperm #{Sperm::VERSION}"
22
+ exit
23
+ end
24
+ end
25
+
26
+ optparse.parse!
@@ -0,0 +1,55 @@
1
+ -
2
+ prime: 17
3
+ generator: 3
4
+ order_phi: 8
5
+ order_factors: [2, 2, 2, 2]
6
+ -
7
+ prime: 107
8
+ generator: 2
9
+ order_phi: 52
10
+ order_factors: [2, 53]
11
+ -
12
+ prime: 1019
13
+ generator: 2
14
+ order_phi: 508
15
+ order_factors: [2, 509]
16
+ -
17
+ prime: 10007
18
+ generator: 5
19
+ order_phi: 5038
20
+ order_factors: [2, 5003]
21
+ -
22
+ prime: 100043
23
+ generator: 2
24
+ order_phi: 50020
25
+ order_factors: [2, 50021]
26
+ -
27
+ prime: 1000667
28
+ generator: 2
29
+ order_phi: 500332
30
+ order_factors: [2, 500333]
31
+ -
32
+ prime: 10000223
33
+ generator: 5
34
+ order_phi: 5000110
35
+ order_factors: [2, 5000111]
36
+ -
37
+ prime: 100000127
38
+ generator: 5
39
+ order_phi: 50000062
40
+ order_factors: [2, 50000063]
41
+ -
42
+ prime: 1000000007
43
+ generator: 5
44
+ order_phi: 500000002
45
+ order_factors: [2, 500000003]
46
+ -
47
+ prime: 1000099403
48
+ generator: 2
49
+ order_phi: 500049700
50
+ order_factors: [2, 500049701]
51
+ -
52
+ prime: 4100000027
53
+ generator: 2
54
+ order_phi: 2050000012
55
+ order_factors: [2, 2050000013]
@@ -0,0 +1,11 @@
1
+ require 'sperm/version'
2
+ require 'sperm/exceptions'
3
+ require 'sperm/random_permutations'
4
+
5
+ # Sperm is an efficient random permutations generator.
6
+ #
7
+ module Sperm
8
+ def self.rand(order)
9
+ RandomPermutations.new(order).rand
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ module Sperm
2
+ # This runtime error appears when requested permutation order is bigger
3
+ # than maximum group order in known set of cyclic groups.
4
+ #
5
+ class NoSuitableGroup < RuntimeError
6
+ attr_reader :order
7
+
8
+ def initialize(order)
9
+ @order = order
10
+ end
11
+
12
+ def to_s
13
+ "no suitable group for permutation of order #{order} found"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,6 @@
1
+ require 'sperm/groups/additive'
2
+ require 'sperm/groups/multiplicative'
3
+ require 'sperm/groups/isomorphism'
4
+ require 'sperm/groups/multiplicative_shuffler'
5
+ require 'sperm/groups/intmod'
6
+ require 'sperm/groups/collection'
@@ -0,0 +1,28 @@
1
+ require 'sperm/groups/intmod'
2
+
3
+ module Sperm::Groups
4
+ # Represents (Z/nZ, +) - an additive cyclic group of integers modulo n.
5
+ #
6
+ class ZnAdd
7
+ include Zn
8
+
9
+ attr_reader :modulo
10
+ alias_method :order, :modulo
11
+
12
+ def initialize(modulo_factors)
13
+ @modulo_factors = modulo_factors.uniq
14
+ @modulo = modulo_factors.inject(1, &:*)
15
+ end
16
+
17
+ def generator?(number)
18
+ fail ArgumentError, 'not an element' unless include?(number)
19
+ @modulo_factors.all? { |prime| coprime_with_prime?(number, prime) }
20
+ end
21
+
22
+ private
23
+
24
+ def coprime_with_prime?(number, prime)
25
+ number % prime != 0
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ require 'sperm/groups/additive'
2
+ require 'sperm/groups/multiplicative'
3
+ require 'sperm/groups/isomorphism'
4
+
5
+ require 'ostruct'
6
+ require 'yaml'
7
+
8
+ module Sperm::Groups
9
+ # Represents collection of known cyclic groups that can be used
10
+ # for generating random permutations.
11
+ #
12
+ class GroupsCollection
13
+ def initialize(isomorphisms)
14
+ @isomorphisms = isomorphisms.sort_by { |isomorphism| isomorphism.order }
15
+ end
16
+
17
+ def find_suitable_isomorphism(order)
18
+ @isomorphisms.bsearch { |isomorphism| isomorphism.order >= order }
19
+ end
20
+
21
+ def self.load_file(path)
22
+ array = YAML.load_file(path)
23
+ isomorphisms = array.map { |hash| OpenStruct.new(hash) }.map do |group|
24
+ add_group = ZnAdd.new(group.order_factors)
25
+ mul_group = ZpMul.new(group.prime, group.generator)
26
+ Isomorphism.new(add_group, mul_group)
27
+ end
28
+ new(isomorphisms)
29
+ end
30
+
31
+ DEFAULT_FILE = File.expand_path('../../../../data/groups.yml', __FILE__)
32
+ DEFAULT = load_file(DEFAULT_FILE)
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ module Sperm::Groups
2
+ # Represents Z/nZ group.
3
+ #
4
+ module Zn
5
+ def include?(element)
6
+ (0...modulo).include?(element)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,24 @@
1
+ require 'forwardable'
2
+ require 'openssl'
3
+
4
+ module Sperm::Groups
5
+ # Provides isomorphism from (Z/(p-1)Z, +) to (Z/pZ \ {0}, *).
6
+ #
7
+ class Isomorphism
8
+ extend Forwardable
9
+
10
+ attr_reader :add_group, :mul_group
11
+ def_delegator :add_group, :order
12
+
13
+ def initialize(add_group, mul_group)
14
+ fail ArgumentError, 'unequal orders' unless add_group.order == mul_group.order
15
+ @add_group = add_group
16
+ @mul_group = mul_group
17
+ end
18
+
19
+ def map(number)
20
+ fail ArgumentError, 'not an element' unless add_group.include?(number)
21
+ mul_group.generator.to_bn.mod_exp(number, mul_group.modulo).to_i
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ require 'sperm/groups/intmod'
2
+
3
+ module Sperm::Groups
4
+ # Represents (Z/pZ \ {0}, *) - a multiplicative cyclic group of integers
5
+ # modulo p.
6
+ #
7
+ class ZpMul
8
+ include Zn
9
+
10
+ attr_reader :prime, :generator
11
+ alias_method :modulo, :prime
12
+
13
+ def initialize(prime, generator)
14
+ @prime = prime
15
+ @generator = generator
16
+ end
17
+
18
+ def order
19
+ modulo - 1
20
+ end
21
+
22
+ def produce_cycle(first, multiplier)
23
+ fail ArgumentError, 'not an element' unless include?(first) && include?(multiplier)
24
+ Enumerator.new do |yielder|
25
+ current = first
26
+ loop do
27
+ yielder.yield current
28
+ current = (current * multiplier) % modulo
29
+ break if current == first
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,35 @@
1
+ module Sperm::Groups
2
+ # Generates random cyclic representations of (Z/pZ \ {0}, *).
3
+ #
4
+ class ZpMulShuffler
5
+ def initialize(isomorphism, rand_source)
6
+ @isomorphism, @rand_source = isomorphism, rand_source
7
+ end
8
+
9
+ def rand
10
+ first = 1 + @rand_source.rand(mul_group.modulo - 1)
11
+ mul_group.produce_cycle(first, rand_mul_generator).lazy
12
+ end
13
+
14
+ private
15
+
16
+ def rand_mul_generator
17
+ add_gen = rand_add_generator
18
+ @isomorphism.map(add_gen)
19
+ end
20
+
21
+ def rand_add_generator
22
+ gen = @rand_source.rand(add_group.modulo)
23
+ gen = (gen + 1) % add_group.modulo until add_group.generator?(gen)
24
+ gen
25
+ end
26
+
27
+ def add_group
28
+ @isomorphism.add_group
29
+ end
30
+
31
+ def mul_group
32
+ @isomorphism.mul_group
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,23 @@
1
+ require 'sperm/groups'
2
+ require 'sperm/exceptions'
3
+ require 'sperm/random_source'
4
+
5
+ module Sperm
6
+ # Generates random permutations of given order.
7
+ #
8
+ class RandomPermutations
9
+ attr_reader :order
10
+
11
+ def initialize(order, random = Random.new, groups = Groups::GroupsCollection::DEFAULT)
12
+ isomorphism = groups.find_suitable_isomorphism(order)
13
+ fail NoSuitableGroup, order unless isomorphism
14
+ random_source = RandomSource.new(random)
15
+ @order = order
16
+ @shuffler = Groups::ZpMulShuffler.new(isomorphism, random_source)
17
+ end
18
+
19
+ def rand
20
+ @shuffler.rand.select { |element| element.between?(1, order) }.map { |element| element - 1 }
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ module Sperm
2
+ # Internal wrapper for Random instances and RandomSecure.
3
+ #
4
+ class RandomSource
5
+ include Forwardable
6
+
7
+ def initialize(adaptee)
8
+ @adaptee = adaptee
9
+
10
+ %i(rand random_number).each do |method|
11
+ next unless @adaptee.respond_to? method
12
+ def_delegator :@adaptee, method, :rand
13
+ return
14
+ end
15
+
16
+ fail ArgumentError, 'unsupported source of randomness'
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,5 @@
1
+ # Sperm is an efficient random permutations generator.
2
+ #
3
+ module Sperm
4
+ VERSION = '0.1.1'
5
+ end
@@ -0,0 +1,28 @@
1
+ if ENV['COVERAGE'] || ENV['TRAVIS']
2
+ require 'simplecov'
3
+ require 'coveralls'
4
+
5
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
6
+ SimpleCov::Formatter::HTMLFormatter,
7
+ Coveralls::SimpleCov::Formatter
8
+ ]
9
+ SimpleCov.start do
10
+ add_filter '/vendor/'
11
+ add_filter '/spec/'
12
+ end
13
+ end
14
+
15
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
16
+ require 'sperm'
17
+
18
+ # Some helpers for Enumerable.
19
+ #
20
+ module Enumerable
21
+ def permutation?
22
+ sort.to_a == (0...count).to_a
23
+ end
24
+
25
+ def empty?
26
+ count == 0
27
+ end
28
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sperm::RandomPermutations do
4
+ subject { Sperm::RandomPermutations.new(order) }
5
+
6
+ describe '#rand' do
7
+ context 'when order is zero' do
8
+ let(:order) { 0 }
9
+ it 'generates an empty permutation' do
10
+ expect(subject.rand).to be_empty
11
+ end
12
+ end
13
+
14
+ context 'when order is small' do
15
+ let(:order) { 42 }
16
+ it 'generates a permutation' do
17
+ expect(subject.rand).to be_a_permutation
18
+ end
19
+ end
20
+
21
+ context 'when order is large' do
22
+ let(:order) { 10**8 }
23
+ it 'generates at least first element of permutation' do
24
+ expect(subject.rand.first).to be_between(0, order - 1)
25
+ end
26
+ end
27
+
28
+ context 'when order is too large' do
29
+ let(:order) { 10**100 }
30
+ it 'raises an error' do
31
+ expect { subject }.to raise_error Sperm::NoSuitableGroup
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sperm do
4
+ it 'has a version number' do
5
+ expect(Sperm::VERSION).not_to be_nil
6
+ end
7
+ end
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'sperm/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'sperm'
9
+ spec.version = Sperm::VERSION
10
+
11
+ spec.author = 'Arthur Khashaev'
12
+ spec.email = 'arthur@khashaev.ru'
13
+
14
+ spec.summary = 'Sperm is an efficient random permutations generator'
15
+ spec.description = 'Sperm is a random permutations generator ' \
16
+ 'based on the ideas of group theory ' \
17
+ 'that allows you to generate stupendous permutations ' \
18
+ 'without extra memory consumption.'
19
+
20
+ spec.homepage = 'https://github.com/Invizory/sperm'
21
+ spec.license = 'MIT'
22
+
23
+ spec.files = `git ls-files -z`.split("\x0")
24
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
25
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
26
+ spec.require_paths = ['lib']
27
+
28
+ spec.add_development_dependency 'bundler', "~> 1.5"
29
+ spec.add_development_dependency 'rake'
30
+ spec.add_development_dependency 'rspec'
31
+ spec.add_development_dependency 'rubocop'
32
+ spec.add_development_dependency 'simplecov'
33
+ spec.add_development_dependency 'coveralls'
34
+ end
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sperm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Arthur Khashaev
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-07 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.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
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: rspec
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
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: coveralls
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Sperm is a random permutations generator based on the ideas of group
98
+ theory that allows you to generate stupendous permutations without extra memory
99
+ consumption.
100
+ email: arthur@khashaev.ru
101
+ executables:
102
+ - sperm
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - .editorconfig
107
+ - .gitignore
108
+ - .rspec
109
+ - .rubocop.yml
110
+ - .travis.yml
111
+ - Gemfile
112
+ - LICENSE.txt
113
+ - README.md
114
+ - Rakefile
115
+ - bin/sperm
116
+ - data/groups.yml
117
+ - lib/sperm.rb
118
+ - lib/sperm/exceptions.rb
119
+ - lib/sperm/groups.rb
120
+ - lib/sperm/groups/additive.rb
121
+ - lib/sperm/groups/collection.rb
122
+ - lib/sperm/groups/intmod.rb
123
+ - lib/sperm/groups/isomorphism.rb
124
+ - lib/sperm/groups/multiplicative.rb
125
+ - lib/sperm/groups/multiplicative_shuffler.rb
126
+ - lib/sperm/random_permutations.rb
127
+ - lib/sperm/random_source.rb
128
+ - lib/sperm/version.rb
129
+ - spec/spec_helper.rb
130
+ - spec/sperm/random_permutations_spec.rb
131
+ - spec/sperm_spec.rb
132
+ - sperm.gemspec
133
+ homepage: https://github.com/Invizory/sperm
134
+ licenses:
135
+ - MIT
136
+ metadata: {}
137
+ post_install_message:
138
+ rdoc_options: []
139
+ require_paths:
140
+ - lib
141
+ required_ruby_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ required_rubygems_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - '>='
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ requirements: []
152
+ rubyforge_project:
153
+ rubygems_version: 2.0.7
154
+ signing_key:
155
+ specification_version: 4
156
+ summary: Sperm is an efficient random permutations generator
157
+ test_files:
158
+ - spec/spec_helper.rb
159
+ - spec/sperm/random_permutations_spec.rb
160
+ - spec/sperm_spec.rb