Skip to content

Commit b68e464

Browse files
author
Chris Pilcher
committed
Merge pull request kodecocodes#117 from vinayjn/master
Replaced Array2D with swift 2d array
2 parents fea0d54 + 2d3238c commit b68e464

File tree

3 files changed

+135
-133
lines changed

3 files changed

+135
-133
lines changed

Combinatorics/Combinatorics.playground/Contents.swift

+103-102
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
/* Calculates n! */
44
func factorial(n: Int) -> Int {
5-
var n = n
6-
var result = 1
7-
while n > 1 {
8-
result *= n
9-
n -= 1
10-
}
11-
return result
5+
var n = n
6+
var result = 1
7+
while n > 1 {
8+
result *= n
9+
n -= 1
10+
}
11+
return result
1212
}
1313

1414
factorial(5)
@@ -17,17 +17,17 @@ factorial(20)
1717

1818

1919
/*
20-
Calculates P(n, k), the number of permutations of n distinct symbols
21-
in groups of size k.
22-
*/
20+
Calculates P(n, k), the number of permutations of n distinct symbols
21+
in groups of size k.
22+
*/
2323
func permutations(n: Int, _ k: Int) -> Int {
24-
var n = n
25-
var answer = n
26-
for _ in 1..<k {
27-
n -= 1
28-
answer *= n
29-
}
30-
return answer
24+
var n = n
25+
var answer = n
26+
for _ in 1..<k {
27+
n -= 1
28+
answer *= n
29+
}
30+
return answer
3131
}
3232

3333
permutations(5, 3)
@@ -37,22 +37,22 @@ permutations(9, 4)
3737

3838

3939
/*
40-
Prints out all the permutations of the given array.
41-
Original algorithm by Niklaus Wirth.
42-
See also Dr.Dobb's Magazine June 1993, Algorithm Alley
43-
*/
40+
Prints out all the permutations of the given array.
41+
Original algorithm by Niklaus Wirth.
42+
See also Dr.Dobb's Magazine June 1993, Algorithm Alley
43+
*/
4444
func permuteWirth<T>(a: [T], _ n: Int) {
45-
if n == 0 {
46-
print(a) // display the current permutation
47-
} else {
48-
var a = a
49-
permuteWirth(a, n - 1)
50-
for i in 0..<n {
51-
swap(&a[i], &a[n])
52-
permuteWirth(a, n - 1)
53-
swap(&a[i], &a[n])
45+
if n == 0 {
46+
print(a) // display the current permutation
47+
} else {
48+
var a = a
49+
permuteWirth(a, n - 1)
50+
for i in 0..<n {
51+
swap(&a[i], &a[n])
52+
permuteWirth(a, n - 1)
53+
swap(&a[i], &a[n])
54+
}
5455
}
55-
}
5656
}
5757

5858
let letters = ["a", "b", "c", "d", "e"]
@@ -66,30 +66,30 @@ permuteWirth(xyz, 2)
6666

6767

6868
/*
69-
Prints out all the permutations of an n-element collection.
70-
71-
The initial array must be initialized with all zeros. The algorithm
72-
uses 0 as a flag that indicates more work to be done on each level
73-
of the recursion.
74-
75-
Original algorithm by Robert Sedgewick.
76-
See also Dr.Dobb's Magazine June 1993, Algorithm Alley
77-
*/
69+
Prints out all the permutations of an n-element collection.
70+
71+
The initial array must be initialized with all zeros. The algorithm
72+
uses 0 as a flag that indicates more work to be done on each level
73+
of the recursion.
74+
75+
Original algorithm by Robert Sedgewick.
76+
See also Dr.Dobb's Magazine June 1993, Algorithm Alley
77+
*/
7878
func permuteSedgewick(a: [Int], _ n: Int, inout _ pos: Int) {
79-
var a = a
80-
pos += 1
81-
a[n] = pos
82-
if pos == a.count - 1 {
83-
print(a) // display the current permutation
84-
} else {
85-
for i in 0..<a.count {
86-
if a[i] == 0 {
87-
permuteSedgewick(a, i, &pos)
88-
}
79+
var a = a
80+
pos += 1
81+
a[n] = pos
82+
if pos == a.count - 1 {
83+
print(a) // display the current permutation
84+
} else {
85+
for i in 0..<a.count {
86+
if a[i] == 0 {
87+
permuteSedgewick(a, i, &pos)
88+
}
89+
}
8990
}
90-
}
91-
pos -= 1
92-
a[n] = 0
91+
pos -= 1
92+
a[n] = 0
9393
}
9494

9595
print("\nSedgewick permutations:")
@@ -100,35 +100,35 @@ permuteSedgewick(numbers, 0, &pos)
100100

101101

102102
/*
103-
Calculates C(n, k), or "n-choose-k", i.e. how many different selections
104-
of size k out of a total number of distinct elements (n) you can make.
105-
*/
103+
Calculates C(n, k), or "n-choose-k", i.e. how many different selections
104+
of size k out of a total number of distinct elements (n) you can make.
105+
*/
106106
func combinations(n: Int, _ k: Int) -> Int {
107-
return permutations(n, k) / factorial(k)
107+
return permutations(n, k) / factorial(k)
108108
}
109109

110110
combinations(3, 2)
111111
combinations(28, 5)
112112

113113
print("\nCombinations:")
114114
for i in 1...20 {
115-
print("\(20)-choose-\(i) = \(combinations(20, i))")
115+
print("\(20)-choose-\(i) = \(combinations(20, i))")
116116
}
117117

118118

119119

120120
/*
121-
Calculates C(n, k), or "n-choose-k", i.e. the number of ways to choose
122-
k things out of n possibilities.
123-
*/
121+
Calculates C(n, k), or "n-choose-k", i.e. the number of ways to choose
122+
k things out of n possibilities.
123+
*/
124124
func quickBinomialCoefficient(n: Int, _ k: Int) -> Int {
125-
var result = 1
125+
var result = 1
126126

127-
for i in 0..<k {
128-
result *= (n - i)
129-
result /= (i + 1)
130-
}
131-
return result
127+
for i in 0..<k {
128+
result *= (n - i)
129+
result /= (i + 1)
130+
}
131+
return result
132132
}
133133

134134
quickBinomialCoefficient(8, 2)
@@ -138,47 +138,48 @@ quickBinomialCoefficient(30, 15)
138138

139139
/* Supporting code because Swift doesn't have a built-in 2D array. */
140140
struct Array2D<T> {
141-
let columns: Int
142-
let rows: Int
143-
private var array: [T]
144-
145-
init(columns: Int, rows: Int, initialValue: T) {
146-
self.columns = columns
147-
self.rows = rows
148-
array = .init(count: rows*columns, repeatedValue: initialValue)
149-
}
150-
151-
subscript(column: Int, row: Int) -> T {
152-
get { return array[row*columns + column] }
153-
set { array[row*columns + column] = newValue }
154-
}
141+
let columns: Int
142+
let rows: Int
143+
private var array: [T]
144+
145+
init(columns: Int, rows: Int, initialValue: T) {
146+
self.columns = columns
147+
self.rows = rows
148+
array = .init(count: rows*columns, repeatedValue: initialValue)
149+
}
150+
151+
subscript(column: Int, row: Int) -> T {
152+
get { return array[row*columns + column] }
153+
set { array[row*columns + column] = newValue }
154+
}
155155
}
156156

157157
/*
158-
Calculates C(n, k), or "n-choose-k", i.e. the number of ways to choose
159-
k things out of n possibilities.
158+
Calculates C(n, k), or "n-choose-k", i.e. the number of ways to choose
159+
k things out of n possibilities.
160+
161+
Thanks to the dynamic programming, this algorithm from Skiena allows for
162+
the calculation of much larger numbers, at the cost of temporary storage
163+
space for the cached values.
164+
*/
160165

161-
Thanks to the dynamic programming, this algorithm from Skiena allows for
162-
the calculation of much larger numbers, at the cost of temporary storage
163-
space for the cached values.
164-
*/
165166
func binomialCoefficient(n: Int, _ k: Int) -> Int {
166-
var bc = Array2D(columns: n + 1, rows: n + 1, initialValue: 0)
167-
168-
for i in 0...n {
169-
bc[i, 0] = 1
170-
bc[i, i] = 1
171-
}
172-
173-
if n > 0 {
174-
for i in 1...n {
175-
for j in 1..<i {
176-
bc[i, j] = bc[i - 1, j - 1] + bc[i - 1, j]
177-
}
167+
var bc = Array(count: n + 1, repeatedValue: Array(count: n + 1, repeatedValue: 0))
168+
169+
for i in 0...n {
170+
bc[i][0] = 1
171+
bc[i][i] = 1
178172
}
179-
}
180-
181-
return bc[n, k]
173+
174+
if n > 0 {
175+
for i in 1...n {
176+
for j in 1..<i {
177+
bc[i][j] = bc[i - 1][j - 1] + bc[i - 1][j]
178+
}
179+
}
180+
}
181+
182+
return bc[n][k]
182183
}
183184

184185
binomialCoefficient(30, 15)

Combinatorics/Combinatorics.swift

+16-15
Original file line numberDiff line numberDiff line change
@@ -100,21 +100,22 @@ func quickBinomialCoefficient(n: Int, _ k: Int) -> Int {
100100
the calculation of much larger numbers, at the cost of temporary storage
101101
space for the cached values.
102102
*/
103+
103104
func binomialCoefficient(n: Int, _ k: Int) -> Int {
104-
var bc = Array2D(columns: n + 1, rows: n + 1, initialValue: 0)
105-
106-
for i in 0...n {
107-
bc[i, 0] = 1
108-
bc[i, i] = 1
109-
}
110-
111-
if n > 0 {
112-
for i in 1...n {
113-
for j in 1..<i {
114-
bc[i, j] = bc[i - 1, j - 1] + bc[i - 1, j]
115-
}
105+
var bc = Array(count: n + 1, repeatedValue: Array(count: n + 1, repeatedValue: 0))
106+
107+
for i in 0...n {
108+
bc[i][0] = 1
109+
bc[i][i] = 1
116110
}
117-
}
118-
119-
return bc[n, k]
111+
112+
if n > 0 {
113+
for i in 1...n {
114+
for j in 1..<i {
115+
bc[i][j] = bc[i - 1][j - 1] + bc[i - 1][j]
116+
}
117+
}
118+
}
119+
120+
return bc[n][k]
120121
}

Combinatorics/README.markdown

+16-16
Original file line numberDiff line numberDiff line change
@@ -366,26 +366,26 @@ The following code calculates Pascal's triangle in order to find the `C(n, k)` y
366366

367367
```swift
368368
func binomialCoefficient(n: Int, _ k: Int) -> Int {
369-
var bc = Array2D(columns: n + 1, rows: n + 1, initialValue: 0)
370-
371-
for i in 0...n {
372-
bc[i, 0] = 1
373-
bc[i, i] = 1
374-
}
375-
376-
if n > 0 {
377-
for i in 1...n {
378-
for j in 1..<i {
379-
bc[i, j] = bc[i - 1, j - 1] + bc[i - 1, j]
380-
}
369+
var bc = Array(count: n + 1, repeatedValue: Array(count: n + 1, repeatedValue: 0))
370+
371+
for i in 0...n {
372+
bc[i][0] = 1
373+
bc[i][i] = 1
381374
}
382-
}
383-
384-
return bc[n, k]
375+
376+
if n > 0 {
377+
for i in 1...n {
378+
for j in 1..<i {
379+
bc[i][j] = bc[i - 1][j - 1] + bc[i - 1][j]
380+
}
381+
}
382+
}
383+
384+
return bc[n][k]
385385
}
386386
```
387387

388-
This uses [Array2D](../Array2D/) as helper code because Swift doesn't have a built-in two-dimensional array. The algorithm itself is quite simple: the first loop fills in the 1s at the outer edges of the triangle. The other loops calculate each number in the triangle by adding up the two numbers from the previous row.
388+
The algorithm itself is quite simple: the first loop fills in the 1s at the outer edges of the triangle. The other loops calculate each number in the triangle by adding up the two numbers from the previous row.
389389

390390
Now you can calculate `C(66, 33)` without any problems:
391391

0 commit comments

Comments
 (0)