I'm trying to pick up the basics of the Go programming language. Here are my solutions for the exercises presented in 'A Tour of Go'.
Exercise: Loops and Functions #25
The following code returns an approximation for the square root of 2 and compares the result to Go's math.Sqrt()
function.
package main
import (
"fmt"
"math"
)
func Sqrt(x float64) float64 {
// initialize variables
z, d := float64(1), float64(1)
// if delta is greater than 1e-15, seek closer approximation
for d > 1e-15 {
z0 := z
z = z - (z * z - x)/(2 * z)
d = math.Abs(z - z0)
}
return z
}
func main() {
fmt.Println(Sqrt(2))
fmt.Println(math.Sqrt(2))
}
Exercise: Slices #38
The following code creates an image with a repeating pattern.
package main
import "code.google.com/p/go-tour/pic"
func Pic(dx, dy int) [][]uint8 {
// initialize the image
image := make([][]uint8, dy)
// iterate over each pixel
for x := 0; x < dy; x++ {
image[x] = make([]uint8, dx)
for y := 0; y < dx; y++ {
// set a color value for each pixel
image[x][y] = uint8((x ^y) * (x ^ y))
}
}
return image
}
func main() {
pic.Show(Pic)
}
Exercise: Maps #43
The following code counts the number of instances of each word within a string.
package main
import (
"code.google.com/p/go-tour/wc"
"strings"
)
func WordCount(s string) map[string]int {
// initialize the wordMap variable
wordMap := make(map[string]int)
// separate the strings into words
words := strings.Fields(s)
// iterate over the words to count each instance
for _, word := range words {
wordMap[word]++
}
return wordMap
}
func main() {
wc.Test(WordCount)
}
Exercise: Fibonacci closure #46
A simple Fibonacci sequence function. The Fibonacci sequence is the sequence of numbers where the value(n) = value(n-1) + value (n-2)
with the seed values value(0) = 0
and value(1) = 1
.
package main
import "fmt"
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
first, second := 0, 1
return func() int {
first, second = second, first + second
return first
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
Advanced Exercise: Complex cube roots #50
The following function uses Newton's method for finding an approximation for cube roots and iterates over it 1000 times to get a rough value for a cube root of a number.
package main
import(
"fmt"
"math/cmplx"
)
func Cbrt(x complex128) complex128 {
z := complex128(1)
for i := 0; i < 1000; i++ {
z = z - (cmplx.Pow(z, complex128(3)) - x)/(3 * cmplx.Pow(z, complex128(2)))
}
return z
}
func main() {
fmt.Println(Cbrt(2))
}
Exercise: Errors #58
Returning an error if the user tries to find the square root of a negative number.
package main
import (
"fmt"
)
// error type
type ErrNegativeSqrt float64
// error function for the error type
func (e ErrNegativeSqrt) Error() string {
return fmt.Sprintf(
"Can't find the Sqrt of a negative number: %v", float64(e))
}
func Sqrt(f float64) (float64, error) {
// return error if number is negative
if f < 0 {
return 0, ErrNegativeSqrt(f)
// otherwise find an approximation for the square root
} else {
z := float64(1)
for i := 0; i < 1000; i++ {
z = z - (z * z - f)/(2 * z)
}
return z, nil
}
}
func main() {
fmt.Println(Sqrt(2))
fmt.Println(Sqrt(-2))
}
Exercise: HTTP Handlers #60
package main
import (
"net/http"
"fmt"
)
type String string
type Struct struct {
Greeting string
Punctuation string
Who string
}
func (s String) ServeHTTP(
w http.ResponseWriter,
r *http.Request) {
fmt.Fprint(w, s)
}
func (s Struct) ServeHTTP(
w http.ResponseWriter,
r *http.Request) {
fmt.Fprint(w, s.Greeting, s.Punctuation, s.Who)
}
func main() {
http.Handle("/string", String("I'm a frayed knot."))
http.Handle("/struct", &Struct{"Hello", ":", "Gophers!"})
http.ListenAndServe("localhost:4000", nil)
}
Exercise: Images #62
This function defines and creates a test image.
package main
import (
"code.google.com/p/go-tour/pic"
"image"
"image/color"
)
// create the custom image type
type Image struct{
width, height int
pColor uint8
}
// set the image dimensions and location
func (self *Image) Bounds() image.Rectangle {
return image.Rect(0, 0, self.width, self.height)
}
// set the image color model
func (self *Image) ColorModel() color.Model {
return color.RGBAModel
}
// set the image color per pixel
func (self *Image) At(x, y int) color.Color {
return color.RGBA{
self.pColor + uint8(x), self.pColor + uint8(y), 255, 255}
}
// create and show the image
func main() {
m := Image{100, 100, 128}
pic.ShowImage(&m)
}
Exercise: Rot13 Reader #63
The following code decrypts strings of Rot13 text.
package main
import (
"io"
"os"
"strings"
)
type rot13Reader struct {
r io.Reader
}
func (rot rot13Reader) Read(p []byte) (n int, err error) {
n, err = rot.r.Read(p)
// for each letter read from io.Reader
for i := 0; i < len(p); i++ {
// if the letter's index is between A - N, add 13 to its index
if (p[i] >= 'A' && p[i] < 'N') || (p[i] >='a' && p[i] < 'n') {
p[i] += 13
// if the letter's index is between M - Z, subtract 13 from its index
} else if (p[i] > 'M' && p[i] <= 'Z') || (p[i] > 'm' && p[i] <= 'z'){
p[i] -= 13
}
}
return
}
// test to make sure it works
func main() {
s := strings.NewReader(
"Lbh penpxrq gur pbqr!")
r := rot13Reader{s}
io.Copy(os.Stdout, &r)
}