bijection 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Rakefile CHANGED
@@ -1 +1,7 @@
1
1
  require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  $:.push File.expand_path("../lib", __FILE__)
3
- require "bijection/version"
3
+ require "bijection"
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "bijection"
@@ -8,8 +8,8 @@ Gem::Specification.new do |s|
8
8
  s.authors = ["Ryan Berckmans"]
9
9
  s.email = ["ryan.berckmans@gmail.com"]
10
10
  s.homepage = "https://github.com/ryanberckmans/bijection"
11
- s.summary = "bijection container in ruby; pre-alpha wip"
12
- s.description = s.summary
11
+ s.summary = "bijection container in ruby"
12
+ s.description = s.summary + ". See example in Class Bijection."
13
13
 
14
14
  s.rubyforge_project = "bijection"
15
15
 
@@ -1,12 +1,143 @@
1
- require "bijection/version"
2
- require "bijection/base"
3
-
4
- # @example b = Bijection.new
5
- module Bijection
6
- class << self
7
- # @return [Base]
8
- def new
9
- Bijection::Base.new
10
- end
1
+
2
+ # Bijection is a container similar to a Hash with unique values.
3
+ # {http://en.wikipedia.org/wiki/Bijection}
4
+ #
5
+ # Bijection associates each non-nil unique x in a set X, with a non-nil unique y in a set Y.
6
+ #
7
+ # Please send (welcome) feedback and bug reports to my {https://github.com/ryanberckmans github}.
8
+ #
9
+ # @example
10
+ # b = Bijection.new
11
+ # b.add 5, 7 # associates 5 in X with 7 in Y
12
+ # b.size
13
+ # => 1
14
+ # b.add 5, 2 # raises, 5 already in X
15
+ # b.add "foo", 7 # raises, 7 already in Y
16
+ # b.add "bar", 5 # OK; 5 was not yet in Y
17
+ # b.size
18
+ # => 2
19
+ # d = b.domain # d == [5, "bar"]
20
+ # r = b.range # r == [7, 5] # i.e., not the "same" 5 in domain
21
+ # b.each_x { |x| puts x }
22
+ # => 5
23
+ # => "bar"
24
+ # b.each_y { |y| puts y }
25
+ # => 7
26
+ # => 5 # i.e., not the "same" 5 that's in X
27
+ # b.each_pair { |x,y| .. }
28
+ # x = b.get_x 7 # x == 5
29
+ # y = b.get_y 5 # y == 7
30
+ # is_nil = b.get_x "returns nil if not found" # is_nil == nil
31
+ # b.inverse! # X and Y are now swapped; all as above with x and y swapped
32
+ class Bijection
33
+ VERSION = "0.1.0"
34
+
35
+ def initialize
36
+ @X = {} # @X[x] -> y
37
+ @Y = {} # @Y[y] -> x
38
+ end
39
+
40
+ # returns the number of pairs in the bijection
41
+ # @return [Fixnum]
42
+ def size
43
+ @X.size
44
+ end
45
+
46
+ # add (x,y) to the bijection set (X,Y)
47
+ # @param x the non-nil object associated with y
48
+ # @param y the non-nil object associated with x
49
+ # @note x must be unique in X; y must be unique in Y
50
+ # @return [self]
51
+ def add( x, y )
52
+ raise "Bijection: x may not be nil" if x == nil
53
+ raise "Bijection: y may not be nil" if y == nil
54
+ raise "Bijection: #{x.to_s} already present in domain set X" if @X.key? x
55
+ raise "Bijection: #{y.to_s} already present in range set Y" if @Y.key? y
56
+ @X[x] = y
57
+ @Y[y] = x
58
+ self
59
+ end
60
+
61
+ # get the domain set X as an Array
62
+ # @return [Array]
63
+ def domain
64
+ @X.keys
65
+ end
66
+
67
+ # get the range set Y as an Array
68
+ # @return [Array]
69
+ def range
70
+ @Y.keys
71
+ end
72
+
73
+ # swap domain X and range Y of this
74
+ # @return [nil]
75
+ def inverse!
76
+ temp = @X
77
+ @X = @Y
78
+ @Y = temp
79
+ nil
80
+ end
81
+
82
+ # get the x associated with y
83
+ # @param y in domain set Y
84
+ # @return the x associated with y, or nil if y not in range Y
85
+ def get_x( y )
86
+ @Y[y]
87
+ end
88
+
89
+ # get the y associated with x
90
+ # @param x in domain set X
91
+ # @return the y associated with x, or nil if x not in domain X
92
+ def get_y( x )
93
+ @X[x]
94
+ end
95
+
96
+ # @yield [x] each x in domain set X
97
+ # @return [nil]
98
+ def each_x
99
+ @X.each_key { |x| yield x } if block_given?
100
+ nil
101
+ end
102
+
103
+ # @yield [y] each y in range set Y
104
+ # @return [nil]
105
+ def each_y
106
+ @Y.each_key { |y| yield y } if block_given?
107
+ nil
108
+ end
109
+
110
+ # @yield [x,y] each (x,y) in sets X and Y
111
+ # @return [nil]
112
+ def each_pair
113
+ @X.each_pair { |x,y| yield x,y } if block_given?
114
+ nil
115
+ end
116
+
117
+ # given x, delete (x,y) and return y
118
+ # @param (see #get_x)
119
+ # @example
120
+ # b = Bijection.new
121
+ # x = 2 ; y = 3
122
+ # b.add x, y
123
+ # y = nil
124
+ # while true do y = b.delete_by_x x ; b.add x, y end
125
+ # @return (see #get_x)
126
+ def delete_by_x( x )
127
+ y = @X[x]
128
+ @X.delete x
129
+ @Y.delete y
130
+ y
131
+ end
132
+
133
+ # given y, delete (x,y) and return x
134
+ # @param (see #get_y)
135
+ # @return (see #get_y)
136
+ # see example #delete_by_x
137
+ def delete_by_y( y )
138
+ x = @Y[y]
139
+ @Y.delete y
140
+ @X.delete x
141
+ x
11
142
  end
12
143
  end
@@ -0,0 +1,160 @@
1
+ require "spec_helper"
2
+
3
+ describe Bijection do
4
+ before(:each) { @b = Bijection.new }
5
+
6
+ it "initializes with empty domain" do
7
+ @b.domain.should be_empty
8
+ end
9
+
10
+ it "initializes with empty range" do
11
+ @b.range.should be_empty
12
+ end
13
+
14
+ it "initializes with empty size" do
15
+ @b.size.should == 0
16
+ end
17
+
18
+ it "returns self when add is called" do
19
+ @b.add(5, 3).should == @b
20
+ end
21
+
22
+ it "returns nil when inverse! is called" do
23
+ @b.inverse!.should be_nil
24
+ end
25
+
26
+ it "add raises when x is nil" do
27
+ expect { @b.add nil, "fooz" }.to raise_error
28
+ end
29
+
30
+ it "add raises when y is nil" do
31
+ expect { @b.add 57, nil }.to raise_error
32
+ end
33
+
34
+ it "delete_by_x returns nil for x not in X" do
35
+ @b.delete_by_x(5).should be_nil
36
+ end
37
+
38
+ it "delete_by_y returns nil for y not in Y" do
39
+ @b.delete_by_y(5).should be_nil
40
+ end
41
+
42
+ it "each_x returns nil" do
43
+ @b.each_x.should be_nil
44
+ end
45
+
46
+ it "each_y returns nil" do
47
+ @b.each_y.should be_nil
48
+ end
49
+
50
+ it "each_pair returns nil" do
51
+ @b.each_pair.should be_nil
52
+ end
53
+
54
+ context "with one pair added" do
55
+ before :each do
56
+ @x = 3
57
+ @y = []
58
+ @b.add @x, @y
59
+ end
60
+
61
+ it "has domain with exactly x" do
62
+ @b.domain.should == [@x]
63
+ end
64
+
65
+ it "has range with exactly y" do
66
+ @b.range.should == [@y]
67
+ end
68
+
69
+ it "finds x in each_x" do
70
+ @b.each_x { |x| x.should == @x }
71
+ end
72
+
73
+ it "finds y in the each_y" do
74
+ @b.each_y { |y| y.should == @y }
75
+ end
76
+
77
+ it "finds x,y in each_pair" do
78
+ x1 = nil
79
+ y1 = nil
80
+ @b.each_pair do |x,y|
81
+ x1 = x
82
+ y1 = y
83
+ end
84
+ x1.should == @x
85
+ y1.should == @y
86
+ end
87
+
88
+ it "raises when x is re-added" do
89
+ expect { @b.add @x, "fooz" }.to raise_error
90
+ end
91
+
92
+ it "raises when y is re-added" do
93
+ expect { @b.add "sdfdsfs", @y }.to raise_error
94
+ end
95
+
96
+ it "returns x when given y" do
97
+ @b.get_x(@y).should == @x
98
+ end
99
+
100
+ it "returns y when given x" do
101
+ @b.get_y(@x).should == @y
102
+ end
103
+
104
+ it "returns nil when given x not in X" do
105
+ @b.get_y(7).should be_nil
106
+ end
107
+
108
+ it "returns nil when given y not in Y" do
109
+ @b.get_x("foo").should be_nil
110
+ end
111
+
112
+ it "returns x for delete_by_y y and then the bijection is empty" do
113
+ @b.delete_by_y(@y).should == @x
114
+ @b.size == 0
115
+ end
116
+
117
+ it "returns y for delete_by_x x and then the bijection is empty" do
118
+ @b.delete_by_x(@x).should == @y
119
+ @b.size == 0
120
+ end
121
+
122
+ context "after deleting (x,y)" do
123
+ before :each do
124
+ @b.delete_by_x @x
125
+ end
126
+
127
+ it "bijection is empty" do
128
+ @b.size.should == 0
129
+ end
130
+
131
+ it "allows re-adding of (x,y)" do
132
+ @b.add @x, @y
133
+ end
134
+
135
+ context "when re-adding (x,y)" do
136
+ before :each do
137
+ @b.add @x, @y
138
+ end
139
+
140
+ it "should have size 1" do
141
+ @b.size.should == 1
142
+ end
143
+ end
144
+ end
145
+
146
+ context "the inverse" do
147
+ before(:each) do
148
+ @b.inverse!
149
+ end
150
+
151
+ it "returns y for get_x" do
152
+ @b.get_x(@x).should == @y
153
+ end
154
+
155
+ it "returns x for get_y" do
156
+ @b.get_y(@y).should == @x
157
+ end
158
+ end # context inverse
159
+ end # context one pair added
160
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bijection
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,9 +9,9 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-06-20 00:00:00.000000000Z
12
+ date: 2011-06-21 00:00:00.000000000Z
13
13
  dependencies: []
14
- description: bijection container in ruby; pre-alpha wip
14
+ description: bijection container in ruby. See example in Class Bijection.
15
15
  email:
16
16
  - ryan.berckmans@gmail.com
17
17
  executables: []
@@ -19,14 +19,14 @@ extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
21
  - .gitignore
22
+ - .rspec
22
23
  - .rvmrc
23
24
  - .yardopts
24
25
  - Gemfile
25
26
  - Rakefile
26
27
  - bijection.gemspec
27
28
  - lib/bijection.rb
28
- - lib/bijection/base.rb
29
- - lib/bijection/version.rb
29
+ - spec/lib/bijection_spec.rb
30
30
  - spec/spec_helper.rb
31
31
  homepage: https://github.com/ryanberckmans/bijection
32
32
  licenses: []
@@ -51,5 +51,5 @@ rubyforge_project: bijection
51
51
  rubygems_version: 1.8.5
52
52
  signing_key:
53
53
  specification_version: 3
54
- summary: bijection container in ruby; pre-alpha wip
54
+ summary: bijection container in ruby
55
55
  test_files: []
@@ -1,68 +0,0 @@
1
- module Bijection
2
-
3
- # @example
4
- # b = Bijection.new
5
- # => Bijection::Base
6
- class Base
7
- def initialize
8
- @x = {}
9
- @y = {}
10
- end
11
-
12
- # add (x,y) to the bijection set (X,Y)
13
- # @param x the object associated with y
14
- # @param y the object associated with x
15
- # @note x must be unique in X; y must be unique in Y
16
- # @return self
17
- def map( x, y )
18
- self
19
- end
20
-
21
- # @return [Enumerator] the domain set X
22
- def domain
23
- @x.each_key
24
- end
25
-
26
- # @return [Enumerator] the range set Y
27
- def range
28
- @y.each_key
29
- end
30
-
31
- # swap domain X and range Y of this
32
- # @return nil
33
- def inverse!
34
- end
35
-
36
- # @param y in domain set Y
37
- # @return the x associated with y
38
- def get_x( y )
39
- end
40
-
41
- # @param x in domain set X
42
- # @return the y associated with x
43
- def get_y( x )
44
- end
45
-
46
- # @return [Enumerator] an enumerator all (x,y)
47
- def each_pair
48
- end
49
-
50
- # given x, delete (x,y) and return y
51
- # @param (see #get_x)
52
- # @example
53
- # b = Bijection.new
54
- # x = 2 ; y = 3
55
- # b.map x, y
56
- # y = nil
57
- # while 1 { y = b.delete_x x ; b.map x, y }
58
- # @return the y associated with x
59
- def delete_x( x )
60
- end
61
-
62
- # given y, delete (x,y) and return x
63
- # @param (see #get_y)
64
- # @return x associated with y
65
- def delete_y( y )
66
- end
67
- end
68
- end
@@ -1,3 +0,0 @@
1
- module Bijection
2
- VERSION = "0.0.1"
3
- end