Tour Of Go Solutions

#Golang

I've been writing Go professionally since 2022, but have never gotten around to fully reading The Tour of Go. It's the Go to resource when it comes to getting started with Golang.

I actually learned quite a few new things that I wasn't aware of before.

Well anyway, here are my solutions.

Flow Control

https://go.dev/tour/flowcontrol/8

1package main
2
3import (
4  "fmt"
5  "math"
6)
7
8func Sqrt(x float64) float64 {
9  z := 1.0
10  prev := -1.0
11  for i := 0; i < 10; i++ {
12    if math.Abs(z-prev) < 0.0001 {
13      break
14    }
15    prev = z
16    z -= (z*z - x) / (2 * z)
17  }
18
19  return z
20}
21
22func main() {
23  fmt.Println(Sqrt(2))
24}
25

Slices

https://go.dev/tour/moretypes/18

1package main
2
3import "golang.org/x/tour/pic"
4
5func Pic(dx, dy int) [][]uint8 {
6  result := make([][]uint8, dy)
7  for x := range result {
8    result[x] = make([]uint8, dx)
9    for y:= range result[x] {
10      result[x][y] = uint8(x^y)
11    }
12  }
13
14  return result
15}
16
17func main() {
18  pic.Show(Pic)
19}
20

Maps

https://go.dev/tour/moretypes/23

1package main
2
3import (
4  "golang.org/x/tour/wc"
5  "strings"
6)
7
8func WordCount(s string) map[string]int {
9  wordCounts := map[string]int{}
10  for _, word := range strings.Fields(s) {
11    wordCounts[word]++
12  }
13
14  return wordCounts
15}
16
17func main() {
18  wc.Test(WordCount)
19}
20

Fibonacci Closure

https://go.dev/tour/moretypes/26

1package main
2
3import "fmt"
4
5func fibonacci() func() int {
6  x, y := 0, 1
7
8  return func() (z int) {
9    z, x, y = x, y, x+y
10    return
11  }
12}
13
14func main() {
15  f := fibonacci()
16  for i := 0; i < 10; i++ {
17    fmt.Println(f())
18  }
19}
20

Stringers

https://go.dev/tour/methods/18

1package main
2
3import (
4  "fmt"
5  "strconv"
6  "strings"
7)
8
9type IPAddr [4]byte
10
11func (ip IPAddr) String() string {
12  parts := make([]string, 0, len(ip))
13  for _, b := range ip {
14    part := strconv.Itoa(int(b))
15    parts = append(parts, part)
16  }
17
18  return strings.Join(parts, ".")
19}
20
21func main() {
22  hosts := map[string]IPAddr{
23    "loopback":  {127, 0, 0, 1},
24    "googleDNS": {8, 8, 8, 8},
25  }
26  for name, ip := range hosts {
27    fmt.Printf("%v: %v\n", name, ip)
28  }
29}
30

Errors

https://go.dev/tour/methods/20

1package main
2
3import (
4  "fmt"
5  "math"
6)
7
8type ErrNegativeSqrt float64
9
10func (e ErrNegativeSqrt) Error() string {
11  return fmt.Sprintf("cannot Sqrt negative number: %v", float64(e))
12}
13
14func Sqrt(x float64) (float64, error) {
15  if x < 0 {
16    return 0, ErrNegativeSqrt(x)
17  }
18
19  z := 1.0
20  prev := -1.0
21  for i := 0; i < 10; i++ {
22    if math.Abs(z-prev) < 0.0001 {
23      break
24    }
25    prev = z
26    z -= (z*z - x) / (2 * z)
27  }
28
29  return z, nil
30}
31
32func main() {
33  fmt.Println(Sqrt(2))
34  fmt.Println(Sqrt(-2))
35}
36

Readers

https://go.dev/tour/methods/22

1package main
2
3import "golang.org/x/tour/reader"
4
5type MyReader struct{}
6
7func (r MyReader) Read(in []byte) (n int, err error) {
8  n = len(in)
9  for i := 0; i < n; i++ {
10    in[i] = 'A'
11  }
12
13  return n, nil
14}
15
16func main() {
17  reader.Validate(MyReader{})
18}
19

rot13Reader

https://go.dev/tour/methods/23

1package main
2
3import (
4  "io"
5  "os"
6  "strings"
7)
8
9type rot13Reader struct {
10  r io.Reader
11}
12
13func (r rot13Reader) Read(b []byte) (n int, err error) {
14  n, err = r.r.Read(b)
15  for i := 0; i < n; i++ {
16    if isFirstHalf(b[i]) {
17      b[i] += 13
18    } else if isSecondHalf(b[i]) {
19      b[i] -= 13
20    }
21  }
22
23  return n, err
24}
25
26func isFirstHalf(b byte) bool {
27  return (b >= 'a' && b < 'n') || (b >= 'A' && b < 'N')
28}
29
30func isSecondHalf(b byte) bool {
31  return (b >= 'n' && b <= 'z') || (b >= 'N' && b <= 'Z')
32}
33
34func main() {
35  s := strings.NewReader("Lbh penpxrq gur pbqr!")
36  r := rot13Reader{s}
37  io.Copy(os.Stdout, &r)
38}
39

Images

https://go.dev/tour/methods/25

1package main
2
3import (
4  "golang.org/x/tour/pic"
5  "image"
6  "image/color"
7)
8
9type Image struct{
10  Width int
11  Height int
12}
13
14func (img Image) Bounds() image.Rectangle {
15  return image.Rect(0, 0, img.Width, img.Height)
16}
17
18func (img Image) ColorModel() color.Model {
19  return color.RGBAModel
20}
21
22func (img Image) At(x, y int) color.Color {
23  v := uint8(x * y)
24  return color.RGBA{v, v, 255, 255}
25}
26
27func main() {
28  m := Image{256, 256}
29  pic.ShowImage(m)
30}
31

Equivalent Binary Trees

https://go.dev/tour/concurrency/8

1package main
2
3import (
4  "golang.org/x/tour/tree"
5  "fmt"
6)
7
8func Walk(t *tree.Tree, ch chan int) {
9  if t == nil {
10    return
11  }
12  Walk(t.Left, ch)
13  ch <- t.Value
14  Walk(t.Right, ch)
15}
16
17func Same(t1, t2 *tree.Tree) bool {
18  chanOne, chanTwo := make(chan int), make(chan int)
19
20  go func() {
21    Walk(t1, chanOne)
22    close(chanOne)
23  }()
24
25  go func() {
26    Walk(t2, chanTwo)
27    close(chanTwo)
28  }()
29
30  for {
31    nodeOne, chanOneOpen := <-chanOne
32    nodeTwo, chanTwoOpen := <-chanTwo
33
34    if !chanOneOpen && !chanTwoOpen {
35      return true // both channels closed, trees are same
36    }
37
38    if chanOneOpen != chanTwoOpen {
39      return false // different number of nodes
40    }
41
42    if nodeOne != nodeTwo {
43      return false // different values
44    }
45  }
46}
47
48func main() {
49  fmt.Println("Trees are equivalent:", Same(tree.New(1), tree.New(1)))
50}
51

Web Crawler

https://go.dev/tour/concurrency/10

1package main
2
3import (
4  "fmt"
5  "sync"
6)
7
8type Fetcher interface {
9  Fetch(url string) (body string, urls []string, err error)
10}
11
12type Cache struct {
13  v  map[string]bool
14  mu sync.Mutex
15}
16
17func (cache *Cache) Set(key string, value bool) {
18  cache.mu.Lock()
19  cache.v[key] = value
20  cache.mu.Unlock()
21}
22
23func (cache *Cache) Get(key string) bool {
24  cache.mu.Lock()
25  defer cache.mu.Unlock()
26  return cache.v[key]
27}
28
29func Crawl(url string, depth int, fetcher Fetcher, visited *Cache, wg *sync.WaitGroup) {
30  if depth == 0 || visited.Get(url) {
31    wg.Done()
32    return
33  }
34  visited.Set(url, true)
35
36  body, urls, err := fetcher.Fetch(url)
37  if err != nil {
38    fmt.Println(err)
39    wg.Done()
40    return
41  }
42
43  fmt.Printf("found: %s %q\n", url, body)
44
45  for _, u := range urls {
46    wg.Add(1)
47    go Crawl(u, depth-1, fetcher, visited, wg)
48  }
49  wg.Done()
50}
51
52func main() {
53  visited := Cache{v: make(map[string]bool)}
54
55  var wg sync.WaitGroup
56  wg.Add(1)
57
58  Crawl("https://golang.org/", 4, fetcher, &visited, &wg)
59
60  wg.Wait()
61}
62
63type fakeFetcher map[string]*fakeResult
64
65type fakeResult struct {
66  body string
67  urls []string
68}
69
70func (f fakeFetcher) Fetch(url string) (body string, urls []string, err error) {
71  if res, ok := f[url]; ok {
72    return res.body, res.urls, nil
73  }
74
75  return "", []string{}, fmt.Errorf("not found %s", url)
76}
77
78var fetcher = fakeFetcher{
79  "https://golang.org/": &fakeResult{
80    "The Go Programming Language",
81    []string{
82      "https://golang.org/pkg/",
83      "https://golang.org/cmd/",
84    },
85  },
86  "https://golang.org/pkg/": &fakeResult{
87    "Packages",
88    []string{
89      "https://golang.org/",
90      "https://golang.org/cmd/",
91      "https://golang.org/pkg/fmt/",
92      "https://golang.org/pkg/os/",
93    },
94  },
95  "https://golang.org/pkg/fmt/": &fakeResult{
96    "Package fmt",
97    []string{
98      "https://golang.org/",
99      "https://golang.org/pkg/",
100    },
101  },
102  "https://golang.org/pkg/os/": &fakeResult{
103    "Package os",
104    []string{
105      "https://golang.org/",
106      "https://golang.org/pkg/",
107    },
108  },
109}
110

Thanks for visiting. © 2025. Stay curious, keep coding. 🚀