Skip to content

Instantly share code, notes, and snippets.

@paulbuis
Last active February 1, 2016 19:53
Show Gist options
  • Save paulbuis/60f03e491f5286aae45a to your computer and use it in GitHub Desktop.
Save paulbuis/60f03e491f5286aae45a to your computer and use it in GitHub Desktop.
Simple programming in Go
Simple example of a Go program

#An example of simple programming in Go

Programs start in function main of package main

  1. Print a simple greeting
  2. Read in 3 integers and print their average
  3. Read in a sequence of integers and compute their average
  4. Variation * Uses a function to read sequence into an array * Uses another function to compute average of array values
  5. Variation * Uses a goroutine to read values from keyboard and put them on a channel * Uses another goroutine to compute average from an channel range * Second goroutine places average on a second channel to communicate with main
  6. Recursively compute factorial
  • Note: result completed before user starts typing input into Kata 2, Variation 2
  1. Compute 50th Fibanacci number efficiently
  2. Variation: Uses closure to maintain iteration state between invocations of inner function by main
  3. Variation: Uses closure to maintain table lookup state between invocations recursive inner function
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
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment