-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerator.go
78 lines (68 loc) · 1.79 KB
/
generator.go
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
package fibonacci
import (
"errors"
"math/big"
)
// Custom Number to use generating the fibonacci numbers, can swap out
// the underlying type without affecting the algorithm
type FibNum struct {
value big.Int
}
func newFibNum(init int64) FibNum {
fn := FibNum{}
fn.value = *big.NewInt(init)
return fn
}
// Clone to get copy of a FibNum.
// With big.Int need to do a new big.NewInt so the FibNum is not using the same
// big.Int value.
func cloneFibNum(src FibNum) FibNum {
fn := FibNum{}
fn.value = *big.NewInt(0)
fn.value.Set(&src.value)
return fn
}
func (fn *FibNum) add(a FibNum, b FibNum) {
fn.value.Add(&a.value, &b.value)
}
// Return string representation of FibNum
func (fn FibNum) String() string {
return fn.value.String()
}
type Generator struct {
maxIterations int
}
// iterations is the number of fibonacci numbers that will be generated by Produce
func NewGenerator(iterations int) (fg *Generator, err error) {
if iterations < 0 {
return nil, errors.New("Number of iterations cannot be negative")
} else if iterations > 100000 {
// Seems like an unreasonably high number but I think there should be some
// limit to what will be generated
return nil, errors.New("Number of iterations cannot be greater than 100000")
}
fg = &Generator{}
fg.maxIterations = iterations
return fg, nil
}
// Generates the number of fibonacci number specified when NewGenerator was called
// Closes the out chan when finished to signal that all values have been generated
func (fg *Generator) Produce(out chan<- FibNum) {
defer close(out)
if fg.maxIterations == 0 {
return
}
var v [2]FibNum
v[0] = newFibNum(0)
v[1] = newFibNum(1)
idx := 0
for i := 0; i < fg.maxIterations; i = i + 1 {
out <- cloneFibNum(v[idx])
v[idx].add(v[0], v[1])
if idx == 0 {
idx = 1
} else {
idx = 0
}
}
}