Help us understand the problem. What is going on with this article?

A Tour of Go 練習問題を解く

More than 1 year has passed since last update.

Go言語の公式チュートリアル A Tuor of Go の課題を自分で解いた結果です。

Exercise: Loops and Functions

exercise-loops-and-functions.go
package main

import (
    "fmt"
    "math"
)

/*
func Sqrt(x float64) float64 {
    z := x
    for i := 0; i < 10; i++ {
        z = z - (z*z-x)/(2*z)
    }
    return z
}
*/
func Sqrt(x float64) float64 {
    z0, z := 1.0, x
    for math.Abs(z-z0)/z > 1e-15 {
        z0, z = z, z-(z*z-x)/(2*z)
    }
    return z
}

func main() {
    fmt.Println(Sqrt(2))
}

Exercise: Slices

exercise-slices.go
package main

import "golang.org/x/tour/pic"

func Pic(dx, dy int) [][]uint8 {
    pic := make([][]uint8, dy)
    for y, _ := range pic { ///@note for y := 0; y < dy; y++  の方が良いかも.
        pic[y] = make([]uint8, dx)
        for x, _ := range pic[y] {
            pic[y][x] = uint8(x ^ y)
        }
    }
    return pic

}

func main() {
    pic.Show(Pic)
}

Exercise: Maps

exercise-maps.go
package main

import (
    "golang.org/x/tour/wc"
    "strings"
)

func WordCount(s string) map[string]int {
    count := make(map[string]int)
    words := strings.Fields(s)
    for _, w := range words {
        count[w]++
    }
    return count
}

func main() {
    wc.Test(WordCount)
}

Exercise: Fibonacci closure

exercise-fibonacci-closure.go
package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    z0, z1 := 0, 1
    return func() int {
        r := z0
        z0, z1 = z1, z0+z1
        return r
    }
}

func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}

Exercise: Stringers

exercise-stringers.go
package main

import "fmt"

type IPAddr [4]byte

// TODO: Add a "String() string" method to IPAddr.
func (a IPAddr) String() string {
    return fmt.Sprintf("%d.%d.%d.%d", a[0], a[1], a[2], a[3])
}

func main() {
    hosts := map[string]IPAddr{
        "loopback":  {127, 0, 0, 1},
        "googleDNS": {8, 8, 8, 8},
    }
    for name, ip := range hosts {
        fmt.Printf("%v: %v\n", name, ip)
    }
}

Exercise: Errors

exercise-errors.go
package main

import (
    "fmt"
    "math"
)

type ErrNegativeSqrt float64

func (e ErrNegativeSqrt) Error() string {
    return fmt.Sprintf("cannot Sqrt negative number: %v", float64(e))
}

func Sqrt(x float64) (float64, error) {
    if x < 0 {
        return 0, ErrNegativeSqrt(x)
    }
    z0, z := 1.0, x
    for math.Abs(z-z0)/z > 1e-15 {
        z0, z = z, z-(z*z-x)/(2*z)
    }
    return z, nil
}

func main() {
    fmt.Println(Sqrt(2))
    fmt.Println(Sqrt(-2))
}

Exercise: Readers

exercise-reader.go
package main

import "golang.org/x/tour/reader"

type MyReader struct{}

// TODO: Add a Read([]byte) (int, error) method to MyReader.
func (a MyReader) Read(rb []byte) (n int, e error) {
    ///@alt for i, _ := range rb { rb[i] = 'A'; n++; }
    for n, e = 0, nil; n < len(rb); n++ {
        rb[n] = 'A'
    }
    return
}

func main() {
    reader.Validate(MyReader{})
}

Exercise: rot13Reader

exercise-rot-reader.go
package main

import (
    "io"
    "os"
    "strings"
)

type rot13Reader struct {
    r io.Reader
}

func (a *rot13Reader) Read(rb []byte) (n int, e error) {
    n, e = a.r.Read(rb)
    if e == nil {
        for i, v := range rb {
            switch {
            case v >= 'A' && v <= 'Z':
                rb[i] = (v-'A'+13)%26 + 'A'
            case v >= 'a' && v <= 'z':
                rb[i] = (v-'a'+13)%26 + 'a'
            }
        }
    }
    return
}

func main() {
    s := strings.NewReader("Lbh penpxrq gur pbqr!")
    r := rot13Reader{s}
    io.Copy(os.Stdout, &r)
}

Exercise: Images

exercise-images.go
package main

import "golang.org/x/tour/pic"
import "image"
import "image/color"

type Image struct{}

func (a Image) ColorModel() color.Model {
    return color.RGBAModel
}
func (a Image) Bounds() image.Rectangle {
    return image.Rect(0, 0, 256, 100)
}
func (a Image) At(x, y int) color.Color {
    v := uint8(x^y)
    return color.RGBA{v, v, 255, 255}
}

func main() {
    m := Image{}
    pic.ShowImage(m)
}

Exercise: Equivalent Binary Trees

exercise-equivalent-binary-trees.go
package main

import "golang.org/x/tour/tree"

// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
    var walk_sub func(*tree.Tree)
    walk_sub = func(t *tree.Tree) {
        if t != nil {
            walk_sub(t.Left)
            ch <- t.Value
            walk_sub(t.Right)
        }
    }
    walk_sub(t)
    close(ch)
}

// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
    ch1 := make(chan int)
    ch2 := make(chan int)
    go Walk(t1, ch1)
    go Walk(t2, ch2)
    for v1 := range ch1 {
        v2, ok := <-ch2
        if !ok || v1 != v2 {
            return false
        }
    }
    return true
}

func main() {
    ch := make(chan int)
    go Walk(tree.New(1), ch)
    for v := range ch {
        println("tree:", v)
    }
    println("same 1,1", Same(tree.New(1), tree.New(1)))
    println("same 1,2", Same(tree.New(1), tree.New(2)))
}

Exercise: Web Crawler

exercise-web-crawler.go
package main

import (
    "fmt"
    "sync"
    "time"
)

type Fetcher interface {
    // Fetch returns the body of URL and
    // a slice of URLs found on that page.
    Fetch(url string) (body string, urls []string, err error)
}

// pages starting with url, to a maximum of depth.
func Crawl(url string, depth int, fetcher Fetcher) {
    cache := make(map[string]int)
    var mutex sync.Mutex
    var crawl_sub func(string, int)
    crawl_sub = func(url string, depth int) {
        if depth <= 0 {
            fmt.Printf("too deep: %s\n", url)
            return
        }
        // Don't fetch the same URL twice.
        mutex.Lock()
        cache[url]++
        c := cache[url]
        mutex.Unlock()
        if c > 1 {
            fmt.Printf("fetched: %s\n", url)
            return
        }
        // Fetch URLs in parallel.
        body, urls, err := fetcher.Fetch(url)
        if err != nil {
            fmt.Println(err)
            return
        }
        fmt.Printf("found: %s %q\n", url, body)
        for _, u := range urls {
            go crawl_sub(u, depth-1)
        }
    }
    crawl_sub(url, depth)
    time.Sleep(time.Second) // goルーチンの完了待ち. chanを使って待ち合わせたほうが良い.
    return
}

func main() {
    Crawl("http://golang.org/", 4, fetcher)
}

// fakeFetcher is Fetcher that returns canned results.
type fakeFetcher map[string]*fakeResult

type fakeResult struct {
    body string
    urls []string
}

func (f fakeFetcher) Fetch(url string) (string, []string, error) {
    if res, ok := f[url]; ok {
        return res.body, res.urls, nil
    }
    return "", nil, fmt.Errorf("not found: %s", url)
}

// fetcher is a populated fakeFetcher.
var fetcher = fakeFetcher{
    "http://golang.org/": &fakeResult{
        "The Go Programming Language",
        []string{
            "http://golang.org/pkg/",
            "http://golang.org/cmd/",
        },
    },
    "http://golang.org/pkg/": &fakeResult{
        "Packages",
        []string{
            "http://golang.org/",
            "http://golang.org/cmd/",
            "http://golang.org/pkg/fmt/",
            "http://golang.org/pkg/os/",
        },
    },
    "http://golang.org/pkg/fmt/": &fakeResult{
        "Package fmt",
        []string{
            "http://golang.org/",
            "http://golang.org/pkg/",
        },
    },
    "http://golang.org/pkg/os/": &fakeResult{
        "Package os",
        []string{
            "http://golang.org/",
            "http://golang.org/pkg/",
        },
    },
}

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away