1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Array#permutation" do
before :each do
@numbers = (1..3).to_a
@yielded = []
end
it "returns an Enumerator of all permutations when called without a block or arguments" do
enum = @numbers.permutation
enum.should be_an_instance_of(Enumerator)
enum.to_a.sort.should == [
[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]
].sort
end
it "returns an Enumerator of permutations of given length when called with an argument but no block" do
enum = @numbers.permutation(1)
enum.should be_an_instance_of(Enumerator)
enum.to_a.sort.should == [[1],[2],[3]]
end
it "yields all permutations to the block then returns self when called with block but no arguments" do
array = @numbers.permutation {|n| @yielded << n}
array.should be_an_instance_of(Array)
array.sort.should == @numbers.sort
@yielded.sort.should == [
[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]
].sort
end
it "yields all permutations of given length to the block then returns self when called with block and argument" do
array = @numbers.permutation(2) {|n| @yielded << n}
array.should be_an_instance_of(Array)
array.sort.should == @numbers.sort
@yielded.sort.should == [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]].sort
end
it "returns the empty permutation ([[]]) when the given length is 0" do
@numbers.permutation(0).to_a.should == [[]]
@numbers.permutation(0) { |n| @yielded << n }
@yielded.should == [[]]
end
it "returns the empty permutation([]) when called on an empty Array" do
[].permutation.to_a.should == [[]]
[].permutation { |n| @yielded << n }
@yielded.should == [[]]
end
it "returns no permutations when the given length has no permutations" do
@numbers.permutation(9).entries.size.should == 0
@numbers.permutation(9) { |n| @yielded << n }
@yielded.should == []
end
it "handles duplicate elements correctly" do
@numbers << 1
@numbers.permutation(2).sort.should == [
[1,1],[1,1],[1,2],[1,2],[1,3],[1,3],
[2,1],[2,1],[2,3],
[3,1],[3,1],[3,2]
].sort
end
it "handles nested Arrays correctly" do
# The ugliness is due to the order of permutations returned by
# permutation being undefined combined with #sort croaking on Arrays of
# Arrays.
@numbers << [4,5]
got = @numbers.permutation(2).to_a
expected = [
[1, 2], [1, 3], [1, [4, 5]],
[2, 1], [2, 3], [2, [4, 5]],
[3, 1], [3, 2], [3, [4, 5]],
[[4, 5], 1], [[4, 5], 2], [[4, 5], 3]
]
expected.each {|e| got.include?(e).should be_true}
got.size.should == expected.size
end
it "truncates Float arguments" do
@numbers.permutation(3.7).to_a.sort.should ==
@numbers.permutation(3).to_a.sort
end
it "returns an Enumerator which works as expected even when the array was modified" do
@numbers = [1, 2]
enum = @numbers.permutation
@numbers << 3
enum.to_a.sort.should == [
[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]
].sort
end
it "generates from a defensive copy, ignoring mutations" do
accum = []
ary = [1,2,3]
ary.permutation(3) do |x|
accum << x
ary[0] = 5
end
accum.should == [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
end
describe "when no block is given" do
describe "returned Enumerator" do
describe "size" do
describe "with an array size greater than 0" do
it "returns the descending factorial of array size and given length" do
@numbers.permutation(4).size.should == 0
@numbers.permutation(3).size.should == 6
@numbers.permutation(2).size.should == 6
@numbers.permutation(1).size.should == 3
@numbers.permutation(0).size.should == 1
end
it "returns the descending factorial of array size with array size when there's no param" do
@numbers.permutation.size.should == 6
[1,2,3,4].permutation.size.should == 24
[1].permutation.size.should == 1
end
end
describe "with an empty array" do
it "returns 1 when the given length is 0" do
[].permutation(0).size.should == 1
end
it "returns 1 when there's param" do
[].permutation.size.should == 1
end
end
end
end
end
end
|