|
package main |
|
|
|
import ( |
|
"fmt" |
|
"time" |
|
) |
|
|
|
func main() { |
|
// |
|
// Kata 0: Print a simple greeting |
|
// |
|
fmt.Println("Hello!") |
|
fmt.Println("The time is", time.Now()) |
|
|
|
// |
|
// Kata 1: Read in 3 integers and print their average |
|
// |
|
var x, y, z int |
|
fmt.Println("Input 3 integers one line & hit [return]") |
|
fmt.Scanf("%d %d %d", &x, &y, &z) |
|
sum := x + y + z |
|
ave := float64(sum) / 3.0 |
|
fmt.Printf("\nAverage: %6.3g\n", ave) |
|
|
|
// |
|
// Kata 2: Read in a sequence of integers |
|
// and compute their average |
|
// |
|
// Variation 1: store sequence in a slice |
|
// with separate functions for input and computation |
|
// |
|
fmt.Println("Enter integers, one per line, terminate with blank line") |
|
data := ReadInts() |
|
ave = AveInts(data) |
|
fmt.Printf("\nAverage: %6.3g\n", ave) |
|
|
|
// |
|
// Kata 2: Read in a sequence of integers |
|
// and compute their average |
|
// |
|
// Variation 2: use producer-consumer model |
|
// producer reads integers |
|
// consumer computes average |
|
// |
|
var aveChannel = make(chan float64) |
|
var dChannel = make(chan int) |
|
fmt.Println("Enter integers, one per line, terminate with blank line") |
|
go produce(dChannel) |
|
go consume(dChannel, aveChannel) |
|
|
|
|
|
|
|
// |
|
// Kata 3: Recursively compute factorial |
|
// |
|
fmt.Println("\n5!=", factorial(5)) |
|
fmt.Printf("50!=%v\n", factorial(50)) |
|
|
|
// |
|
// showing off producer-consumer concurrency: |
|
// factorial gets computed before |
|
// user has chance to input anything |
|
// |
|
ave = <-aveChannel |
|
fmt.Printf("\nAverage: %6.3g\n", ave) |
|
|
|
// |
|
// Kata 4: Compute 50th Fibanacci number |
|
// |
|
// Variation 1: generate sequence using closure to |
|
// hold state between funciton invocations |
|
// |
|
start := time.Now() |
|
fib0 := closureFib() |
|
for i:=0; i<49; i++ { |
|
fib0() |
|
} |
|
f := fib0() |
|
end := time.Now() |
|
d := end.Sub(start) |
|
fmt.Printf("\nTook %d nanoseconds to compute\n", d.Nanoseconds()) |
|
fmt.Printf("50th Fibbanaci number=%v by iteration sequence\n", f) |
|
|
|
// |
|
// Kata 4: Compute 50th Fibanacci number |
|
// |
|
// Variation 2: Use recursion with memoization |
|
// |
|
fib := memoFib() |
|
|
|
start = time.Now() |
|
fib50 := fib(49) |
|
end = time.Now() |
|
d = end.Sub(start) |
|
fmt.Printf("\nTook %d nanoseconds to compute\n", d.Nanoseconds()) |
|
fmt.Printf("50th Fibbanaci number=%v by recursion (first try)\n", fib50) |
|
|
|
// faster on second try because just one table lookup |
|
start = time.Now() |
|
fib50 = fib(49) |
|
end = time.Now() |
|
d = end.Sub(start) |
|
fmt.Printf("\nTook %d nanoseconds to compute\n", d.Nanoseconds()) |
|
fmt.Printf("50th Fibbanaci number=%v by recursion(second try)\n", fib50) |
|
} |
|
|
|
|
|
func ReadInts() (result []int) { |
|
var item int |
|
nRead, err := fmt.Scanf("%d\n", &item) |
|
for nRead > 0 && err == nil { |
|
result = append(result, item) |
|
nRead, err = fmt.Scanf("%d\n", &item) |
|
} |
|
return |
|
} |
|
|
|
func AveInts(items []int) (result float64){ |
|
len := len(items) |
|
sum := 0 |
|
for i := 0; i<len; i++ { |
|
sum += items[i] |
|
} |
|
result = float64(sum) / float64(len) |
|
return |
|
} |
|
|
|
|
|
func produce(dataChannel chan<- int) { |
|
defer close(dataChannel) |
|
var item int |
|
nRead, err := fmt.Scanf("%d\n", &item) |
|
for nRead > 0 && err == nil { |
|
dataChannel <- item |
|
nRead, err = fmt.Scanf("%d\n", &item) |
|
} |
|
} |
|
|
|
func consume(dataChannel <-chan int, aveChannel chan<- float64) { |
|
sum := 0 |
|
count := 0 |
|
|
|
for item := range dataChannel { |
|
sum += item |
|
fmt.Println("sum=", sum) |
|
count++; |
|
} |
|
aveChannel <- float64(sum)/float64(count) |
|
} |
|
|
|
|
|
|
|
func factorial(n uint16) float64 { |
|
if n == 0 { |
|
return 1.0 |
|
} |
|
return float64(n)*factorial(n-1) |
|
} |
|
|
|
|
|
func closureFib() func() uint { |
|
var a, b uint = 0, 1 |
|
fib := func() uint { |
|
result := a |
|
a, b = b, a + b |
|
return result |
|
} |
|
return fib |
|
} |
|
|
|
|
|
func memoFib() func(uint) uint { |
|
var table []uint |
|
table = append(table, 0) |
|
table = append(table, 1) |
|
|
|
var fib func(uint) uint |
|
fib = func (n uint) uint { |
|
if n >= uint(len(table)) { |
|
result := fib(n-2) + fib(n-1) |
|
table = append(table, result) |
|
} |
|
return table[n] |
|
} |
|
return fib |
|
} |