combinatorics 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,11 @@
1
+ # .document is used by rdoc and yard to know how to generate documentation
2
+ # for example, it can be used to control how rdoc gets built when you do `gem install foo`
3
+
4
+ README.rdoc
5
+ lib/**/*.rb
6
+ bin/*
7
+
8
+ # Files below this - are treated as 'extra files', and aren't parsed for ruby code
9
+ -
10
+ features/**/*.feature
11
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ pkg
2
+ doc
3
+ web
4
+ tmp
5
+ .DS_Store
6
+ .yardoc
7
+ *.swp
8
+ *~
data/.specopts ADDED
@@ -0,0 +1 @@
1
+ --colour --format specdoc
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup markdown --title 'Combinatorics Documentation' --protected --files ChangeLog.md,LICENSE.txt
data/ChangeLog.md ADDED
@@ -0,0 +1,6 @@
1
+ ### 0.1.0 / 2010-10-02
2
+
3
+ * Initial release:
4
+ * Adds `powerset` to {Array} and {Set}.
5
+ * Adds Haskell/Python style list comprehensions via {Array#comprehension}.
6
+
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+
2
+ Copyright (c) 2010 Hal Brodigan
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # Combinatorics
2
+
3
+ * [github.com/postmodern/combinatorics](http://github.com/postmodern/combinatorics)
4
+ * [github.com/postmodern/combinatorics/issues](http://github.com/postmodern/combinatorics/issues)
5
+ * Postmodern (postmodern.mod3 at gmail.com)
6
+
7
+ ## Description
8
+
9
+ A collection of modules and methods for performing
10
+ [Combinatoric](http://en.wikipedia.org/wiki/Combinatoric) calculations.
11
+
12
+ ## Features
13
+
14
+ * Adds `powerset` to {Array} and {Set}.
15
+ * Adds Haskell/Python style list comprehensions via {Array#comprehension}.
16
+
17
+ ## Examples
18
+
19
+ Power-set of an {Array}:
20
+
21
+ require 'combinatorics/power_set'
22
+
23
+ [1,2,3,4].powerset
24
+ # => [[],
25
+ [4],
26
+ [3],
27
+ [3, 4],
28
+ [2],
29
+ [2, 4],
30
+ [2, 3],
31
+ [2, 3, 4],
32
+ [1],
33
+ [1, 4],
34
+ [1, 3],
35
+ [1, 3, 4],
36
+ [1, 2],
37
+ [1, 2, 4],
38
+ [1, 2, 3],
39
+ [1, 2, 3, 4]]
40
+
41
+ Power-set of a {Set}:
42
+
43
+ Set['ab', 'cd', 'ef'].powerset
44
+ # => [#<Set: {}>,
45
+ #<Set: {"ef"}>,
46
+ #<Set: {"cd"}>,
47
+ #<Set: {"cd", "ef"}>,
48
+ #<Set: {"ab"}>,
49
+ #<Set: {"ab", "ef"}>,
50
+ #<Set: {"ab", "cd"}>,
51
+ #<Set: {"ab", "cd", "ef"}>]
52
+
53
+ List comprehensions:
54
+
55
+ require 'combinatorics/list_comprehension'
56
+
57
+ [(0..10).step(2),('a'..'c')].comprehension.to_a
58
+ # => [[0, "a"],
59
+ [0, "b"],
60
+ [0, "c"],
61
+ [2, "a"],
62
+ [2, "b"],
63
+ [2, "c"],
64
+ [4, "a"],
65
+ [4, "b"],
66
+ [4, "c"],
67
+ [6, "a"],
68
+ [6, "b"],
69
+ [6, "c"],
70
+ [8, "a"],
71
+ [8, "b"],
72
+ [8, "c"],
73
+ [10, "a"],
74
+ [10, "b"],
75
+ [10, "c"]]
76
+
77
+ ## Install
78
+
79
+ $ sudo gem install combinatorics
80
+
81
+ ## License
82
+
83
+ See {file:LICENSE.txt} for license information.
84
+
data/Rakefile ADDED
@@ -0,0 +1,42 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ gem 'jeweler', '~> 1.4.0'
6
+ require 'jeweler'
7
+
8
+ Jeweler::Tasks.new do |gem|
9
+ gem.name = 'combinatorics'
10
+ gem.summary = %Q{Bringing (more) Combinatorics to Ruby}
11
+ gem.description = %Q{A collection of modules and methods for performing Combinatoric calculations.}
12
+ gem.email = 'postmodern.mod3@gmail.com'
13
+ gem.homepage = 'http://github.com/postmodern/combinatorics'
14
+ gem.authors = ['Postmodern']
15
+ gem.add_development_dependency 'rspec', '~> 1.3.0'
16
+ gem.add_development_dependency 'yard', '~> 0.6.0'
17
+ gem.add_development_dependency 'jeweler', '~> 1.4.0'
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts 'Jeweler (or a dependency) not available. Install it with: gem install jeweler'
22
+ end
23
+
24
+ require 'spec/rake/spectask'
25
+ Spec::Rake::SpecTask.new(:spec) do |spec|
26
+ spec.libs += %w[lib spec]
27
+ spec.spec_files = FileList['spec/**/*_spec.rb']
28
+ spec.spec_opts = %w[--options .specopts]
29
+ end
30
+
31
+ task :spec => :check_dependencies
32
+ task :default => :spec
33
+
34
+ begin
35
+ require 'yard'
36
+
37
+ YARD::Rake::YardocTask.new
38
+ rescue LoadError
39
+ task :yard do
40
+ abort 'YARD is not available. In order to run yard, you must: gem install yard'
41
+ end
42
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,79 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{combinatorics}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Postmodern"]
12
+ s.date = %q{2010-10-02}
13
+ s.description = %q{A collection of modules and methods for performing Combinatoric calculations.}
14
+ s.email = %q{postmodern.mod3@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "ChangeLog.md",
17
+ "LICENSE.txt",
18
+ "README.md"
19
+ ]
20
+ s.files = [
21
+ ".document",
22
+ ".gitignore",
23
+ ".specopts",
24
+ ".yardopts",
25
+ "ChangeLog.md",
26
+ "LICENSE.txt",
27
+ "README.md",
28
+ "Rakefile",
29
+ "VERSION",
30
+ "combinatorics.gemspec",
31
+ "lib/combinatorics.rb",
32
+ "lib/combinatorics/list_comprehension.rb",
33
+ "lib/combinatorics/power_set.rb",
34
+ "lib/combinatorics/power_set/extensions.rb",
35
+ "lib/combinatorics/power_set/extensions/array.rb",
36
+ "lib/combinatorics/power_set/extensions/set.rb",
37
+ "lib/combinatorics/power_set/mixin.rb",
38
+ "spec/.rspec",
39
+ "spec/combinatorics_spec.rb",
40
+ "spec/list_comprehension_spec.rb",
41
+ "spec/power_set/array_spec.rb",
42
+ "spec/power_set/mixin_examples.rb",
43
+ "spec/power_set/set_spec.rb",
44
+ "spec/spec_helper.rb"
45
+ ]
46
+ s.homepage = %q{http://github.com/postmodern/combinatorics}
47
+ s.rdoc_options = ["--charset=UTF-8"]
48
+ s.require_paths = ["lib"]
49
+ s.rubygems_version = %q{1.3.7}
50
+ s.summary = %q{Bringing (more) Combinatorics to Ruby}
51
+ s.test_files = [
52
+ "spec/combinatorics_spec.rb",
53
+ "spec/list_comprehension_spec.rb",
54
+ "spec/spec_helper.rb",
55
+ "spec/power_set/set_spec.rb",
56
+ "spec/power_set/array_spec.rb",
57
+ "spec/power_set/mixin_examples.rb"
58
+ ]
59
+
60
+ if s.respond_to? :specification_version then
61
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
62
+ s.specification_version = 3
63
+
64
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
65
+ s.add_development_dependency(%q<rspec>, ["~> 1.3.0"])
66
+ s.add_development_dependency(%q<yard>, ["~> 0.6.0"])
67
+ s.add_development_dependency(%q<jeweler>, ["~> 1.4.0"])
68
+ else
69
+ s.add_dependency(%q<rspec>, ["~> 1.3.0"])
70
+ s.add_dependency(%q<yard>, ["~> 0.6.0"])
71
+ s.add_dependency(%q<jeweler>, ["~> 1.4.0"])
72
+ end
73
+ else
74
+ s.add_dependency(%q<rspec>, ["~> 1.3.0"])
75
+ s.add_dependency(%q<yard>, ["~> 0.6.0"])
76
+ s.add_dependency(%q<jeweler>, ["~> 1.4.0"])
77
+ end
78
+ end
79
+
@@ -0,0 +1,2 @@
1
+ require 'combinatorics/list_comprehension'
2
+ require 'combinatorics/power_set'
@@ -0,0 +1,74 @@
1
+ class Array
2
+
3
+ #
4
+ # Iterates over each permutation of the enumerable values within the
5
+ # {Array}.
6
+ #
7
+ # @yield [list]
8
+ # The given block will be passed each permutation of the enumerable
9
+ # values in the {Array}.
10
+ #
11
+ # @yieldparam [Array] list
12
+ # A permutation of the enumerable values within the {Array}.
13
+ #
14
+ # @return [Enumerator]
15
+ # If no block is given, an enumerator object will be returned.
16
+ #
17
+ # @example
18
+ # [(1..5),(1..4),(1..3)].comprehension.to_a
19
+ # # => [
20
+ # [1, 1, 1], [1, 1, 2], [1, 1, 3],
21
+ # [1, 2, 1], [1, 2, 2], [1, 2, 3],
22
+ # [1, 3, 1], [1, 3, 2], [1, 3, 3],
23
+ # [1, 4, 1], [1, 4, 2], [1, 4, 3],
24
+ # [2, 1, 1], [2, 1, 2], [2, 1, 3],
25
+ # [2, 2, 1], [2, 2, 2], [2, 2, 3],
26
+ # [2, 3, 1], [2, 3, 2], [2, 3, 3],
27
+ # [2, 4, 1], [2, 4, 2], [2, 4, 3],
28
+ # [3, 1, 1], [3, 1, 2], [3, 1, 3],
29
+ # [3, 2, 1], [3, 2, 2], [3, 2, 3],
30
+ # [3, 3, 1], [3, 3, 2], [3, 3, 3],
31
+ # [3, 4, 1], [3, 4, 2], [3, 4, 3],
32
+ # [4, 1, 1], [4, 1, 2], [4, 1, 3],
33
+ # [4, 2, 1], [4, 2, 2], [4, 2, 3],
34
+ # [4, 3, 1], [4, 3, 2], [4, 3, 3],
35
+ # [4, 4, 1], [4, 4, 2], [4, 4, 3],
36
+ # [5, 1, 1], [5, 1, 2], [5, 1, 3],
37
+ # [5, 2, 1], [5, 2, 2], [5, 2, 3],
38
+ # [5, 3, 1], [5, 3, 2], [5, 3, 3],
39
+ # [5, 4, 1], [5, 4, 2], [5, 4, 3]
40
+ # ]
41
+ #
42
+ def comprehension
43
+ return enum_for(:comprehension) unless block_given?
44
+
45
+ if empty?
46
+ yield self
47
+ return nil
48
+ end
49
+
50
+ enums = self.map do |value|
51
+ if value.kind_of?(Enumerable)
52
+ value
53
+ else
54
+ (value..value)
55
+ end
56
+ end
57
+
58
+ cycles = enums.map { |e| e.cycle }
59
+ start = cycles.map { |e| e.next }
60
+ iteration = start.dup
61
+
62
+ loop do
63
+ yield iteration.dup
64
+
65
+ (cycles.length - 1).downto(0) do |index|
66
+ iteration[index] = cycles[index].next
67
+ break unless iteration[index] == start[index]
68
+
69
+ return nil if index == 0
70
+ end
71
+ end
72
+ end
73
+
74
+ end
@@ -0,0 +1,2 @@
1
+ require 'combinatorics/power_set/mixin'
2
+ require 'combinatorics/power_set/extensions'
@@ -0,0 +1,2 @@
1
+ require 'combinatorics/power_set/extensions/array'
2
+ require 'combinatorics/power_set/extensions/set'
@@ -0,0 +1,7 @@
1
+ require 'combinatorics/power_set/mixin'
2
+
3
+ class Array
4
+
5
+ include Combinatorics::PowerSet::Mixin
6
+
7
+ end
@@ -0,0 +1,9 @@
1
+ require 'combinatorics/power_set/mixin'
2
+
3
+ require 'set'
4
+
5
+ class Set
6
+
7
+ include Combinatorics::PowerSet::Mixin
8
+
9
+ end
@@ -0,0 +1,40 @@
1
+ module Combinatorics
2
+ module PowerSet
3
+ module Mixin
4
+ #
5
+ # Calculates the power-set of an Enumerable object.
6
+ #
7
+ # @return [Array]
8
+ # The power set.
9
+ #
10
+ # @example Power-set of an Array.
11
+ # [1,2,3].powerset
12
+ # # => [[], [3], [2], [2, 3], [1], [1, 3], [1, 2], [1, 2, 3]]
13
+ #
14
+ # @example Power-set on a Set of strings.
15
+ # Set['abc', 'xyz', '123'].powerset
16
+ # # => [#<Set: {}>, #<Set: {"123"}>, #<Set: {"xyz"}>,
17
+ # #<Set: {"abc"}>, #<Set: {"xyz", "123"}>,
18
+ # #<Set: {"abc", "123"}>, #<Set: {"abc", "xyz"}>,
19
+ # #<Set: {"abc", "xyz", "123"}>]
20
+ #
21
+ # @see http://johncarrino.net/blog/2006/08/11/powerset-in-ruby/
22
+ #
23
+ def powerset
24
+ inject([self.class.new]) do |power_set,element|
25
+ sub_set = []
26
+
27
+ power_set.each do |i|
28
+ sub_set << i
29
+ sub_set << i + [element]
30
+ end
31
+
32
+ sub_set
33
+ end
34
+ end
35
+
36
+ alias cartesian_product powerset
37
+
38
+ end
39
+ end
40
+ end
data/spec/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Combinatorics" do
4
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ require 'combinatorics/list_comprehension'
3
+
4
+ describe "Array#comprehension" do
5
+ it "should return an Enumerator object if no block is given" do
6
+ a = [1..5]
7
+
8
+ a.comprehension.should_not be_kind_of(Array)
9
+ end
10
+
11
+ it "should yield iterations to the given block" do
12
+ range = (1..5)
13
+ a = [range]
14
+
15
+ a.comprehension.to_a.should == [[1],[2],[3],[4],[5]]
16
+ end
17
+
18
+ it "should do nothing an Array of all non-enumerable objects" do
19
+ a = [1,2,3]
20
+
21
+ a.comprehension.to_a.should == [a]
22
+ end
23
+
24
+ it "should pass through an empty Array" do
25
+ a = []
26
+
27
+ a.comprehension.to_a.should == [a]
28
+ end
29
+
30
+ it "should iterate over the values within an enumerable value" do
31
+ range = (1..10)
32
+ a = [range]
33
+
34
+ a.comprehension.to_a.should == [[1],[2],[3],[4],[5],[6],[7],[8],[9],[10]]
35
+ end
36
+
37
+ it "should ignore non-enumerable values" do
38
+ range = (1..5)
39
+ a = [1,range]
40
+
41
+ a.comprehension.to_a.should == [[1,1],[1,2],[1,3],[1,4],[1,5]]
42
+ end
43
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+ require 'combinatorics/power_set/extensions/array'
3
+ require 'power_set/mixin_examples'
4
+
5
+ describe Array do
6
+ subject { Array }
7
+
8
+ it_should_behave_like "Combinatorics::PowerSet::Mixin"
9
+ end
@@ -0,0 +1,25 @@
1
+ shared_examples_for "Combinatorics::PowerSet::Mixin" do
2
+ it "the powerset of an empty Set should only contain the empty Set" do
3
+ set = subject[]
4
+
5
+ set.powerset.should == [set]
6
+ end
7
+
8
+ it "the powerset of a single Set should contain that Set" do
9
+ set = subject[1]
10
+
11
+ set.powerset.should == [subject[], set]
12
+ end
13
+
14
+ it "the powerset of a Set should all be subsets" do
15
+ set = subject[1,2,3]
16
+
17
+ set.powerset.each { |subset| (set & subset).should == subset }
18
+ end
19
+
20
+ it "should alias cartesian_product to powerset" do
21
+ set = subject[1,2,3]
22
+
23
+ set.cartesian_product.should == set.powerset
24
+ end
25
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+ require 'combinatorics/power_set/extensions/set'
3
+ require 'power_set/mixin_examples'
4
+
5
+ describe Set do
6
+ subject { Set }
7
+
8
+ it_should_behave_like "Combinatorics::PowerSet::Mixin"
9
+ end
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+
3
+ gem 'rspec', '>= 1.3.0'
4
+ require 'spec'
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: combinatorics
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Postmodern
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-10-02 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 1
30
+ - 3
31
+ - 0
32
+ version: 1.3.0
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: yard
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 0
45
+ - 6
46
+ - 0
47
+ version: 0.6.0
48
+ type: :development
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: jeweler
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ~>
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 1
60
+ - 4
61
+ - 0
62
+ version: 1.4.0
63
+ type: :development
64
+ version_requirements: *id003
65
+ description: A collection of modules and methods for performing Combinatoric calculations.
66
+ email: postmodern.mod3@gmail.com
67
+ executables: []
68
+
69
+ extensions: []
70
+
71
+ extra_rdoc_files:
72
+ - ChangeLog.md
73
+ - LICENSE.txt
74
+ - README.md
75
+ files:
76
+ - .document
77
+ - .gitignore
78
+ - .specopts
79
+ - .yardopts
80
+ - ChangeLog.md
81
+ - LICENSE.txt
82
+ - README.md
83
+ - Rakefile
84
+ - VERSION
85
+ - combinatorics.gemspec
86
+ - lib/combinatorics.rb
87
+ - lib/combinatorics/list_comprehension.rb
88
+ - lib/combinatorics/power_set.rb
89
+ - lib/combinatorics/power_set/extensions.rb
90
+ - lib/combinatorics/power_set/extensions/array.rb
91
+ - lib/combinatorics/power_set/extensions/set.rb
92
+ - lib/combinatorics/power_set/mixin.rb
93
+ - spec/.rspec
94
+ - spec/combinatorics_spec.rb
95
+ - spec/list_comprehension_spec.rb
96
+ - spec/power_set/array_spec.rb
97
+ - spec/power_set/mixin_examples.rb
98
+ - spec/power_set/set_spec.rb
99
+ - spec/spec_helper.rb
100
+ has_rdoc: true
101
+ homepage: http://github.com/postmodern/combinatorics
102
+ licenses: []
103
+
104
+ post_install_message:
105
+ rdoc_options:
106
+ - --charset=UTF-8
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ segments:
115
+ - 0
116
+ version: "0"
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ segments:
123
+ - 0
124
+ version: "0"
125
+ requirements: []
126
+
127
+ rubyforge_project:
128
+ rubygems_version: 1.3.7
129
+ signing_key:
130
+ specification_version: 3
131
+ summary: Bringing (more) Combinatorics to Ruby
132
+ test_files:
133
+ - spec/combinatorics_spec.rb
134
+ - spec/list_comprehension_spec.rb
135
+ - spec/spec_helper.rb
136
+ - spec/power_set/set_spec.rb
137
+ - spec/power_set/array_spec.rb
138
+ - spec/power_set/mixin_examples.rb