Go

A Tour of Go Exercise 自己解答

投稿日:2018/04/28 更新日:

A Tour of Goの各Exerciseを自分で解いたもの。

取り急ぎは結果だけあってればOKとして、まだ他の回答例を見ていないのですがふさわしいコードではないと思います。

Loops and Functions


package main

import (
    "fmt"
    "math"
)

func Sqrt(x float64) float64 {
    z := 1.0
    n := 0.0
    for i := 0; i < 10; i++ {
        z -= (z*z - x) / (2 * z)
        if math.Abs(z-n) < 0.0000001 {
            return z
        }
        n = z
    }

    return z
}

func main() {
    x := 2.0
    fmt.Println(Sqrt(x))
    fmt.Println(math.Sqrt(x))
}

Slices


package main

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

func Pic(dx, dy int) [][]uint8 {
    images := make([][]uint8, dy)
    for y := 0; y < dy; y++ {
        s := make([]uint8, dx)
        for x := 0; x < dx; x++ {
            v := (x + y) / 2
            s[x] = uint8(v)
        }
        images[y] = s
    }

    return images
}

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

Maps


package main

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

func WordCount(s string) map[string]int {
    m := make(map[string]int)
    words := strings.Fields(s)
    for i := 0; i < len(words); i++ {
        word := words[i]
        v, ok := m[word]
        if ok {
            v++
        } else {
            v = 1
        }
        m[word] = v

    }
    return m
}

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

Fibonacci closure


package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    v1 := 1
    v2 := 0
    return func() int {
        f := v1 + v2
        v1 = v2
        v2 = f
        return f
    }
}

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

Stringers


package main

import "fmt"

type IPAddr [4]byte

func (ipaddr IPAddr) String() string {
    return fmt.Sprintf("%d.%d.%d.%d", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[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)
    }
}

Errors


package main

import (
    "fmt"
    "math"
)

type ErrNegativeSqrt float64

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

func Sqrt2(x float64) (float64, error) {
    if x < 0 {
        return 0, ErrNegativeSqrt(x)
    }

    z := 1.0
    n := 0.0
    for i := 0; i < 10; i++ {
        z -= (z*z - x) / (2 * z)
        if math.Abs(z-n) < 0.0000001 {
            return z, nil
        }
        n = z
    }

    return z, nil
}

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

無限ループになる件は原因まではわからず・・・。
もう少し理解を深めて考えることにして次に進む。

Readers


package main

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

type MyReader struct{}

func (reader MyReader) Read(b []byte) (int, error) {
    for i := 0; i < len(b); i++ {
        b[i] = 'A'
    }

    return len(b), nil
}

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

rot13Reader


package main

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

type rot13Reader struct {
    r io.Reader
}

func (reader rot13Reader) Read(buffer []byte) (int, error) {
    c, err := reader.r.Read(buffer)
    if err != nil {
        return c, err
    }

    for i := 0; i < c; i++ {
        b := buffer[i]
        if (b >= 'A' && b <= 'M') || (b >= 'a' && b <= 'm') {
            buffer[i] = b + 13
        } else if (b >= 'N' && b <= 'Z') || (b >= 'n' && b <= 'z') {
            buffer[i] = b - 13
        }

    }

    return c, err
}

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

mapで変換テーブル作ろうと思ったのですがコード判定にしました。
一撃で変換できないか考えたのですが残念ながら到達することができず・・・。

Images


package main

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

type Image struct{}

func (i Image) ColorModel() color.Model {
    return color.RGBA64Model
}

func (i Image) Bounds() image.Rectangle {
    return image.Rect(0, 0, 250, 250)
}

func (i Image) At(x, y int) color.Color {
    v := uint8((x + y) / 2)
    return color.RGBA{v, v, 255, 255}
}


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

Equivalent Binary Trees

すごい時間がかかりました・・・。
Channelの概念がいまいち理解できていなくてPrint文を出していろいろ考えました。
言い方が正しいか不明ですがストリームみたいなものと考えると少し理解ができました。
ですが単に動くだけ。
goroutineはまだまだ実践不足と思います。


package main

import (
    "golang.org/x/tour/tree"
    "fmt"
)

// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
    if t == nil {
        return
    }
    Walk(t.Left, ch)
    ch <- t.Value
    Walk(t.Right, 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 func() {
        Walk(t1, ch1)
        close(ch1)
    }()
    go func() {
        Walk(t2, ch2)
        close(ch2)
    }()

    for {
        v1, close1 := <- ch1
        v2, close2 := <- ch2
        if v1 != v2 {
            return false
        }
        if !close1 && !close2 {
            return true
        }
    }

    return false
}

func main() {
    // Walk
    t := tree.New(1)
    ch := make(chan int)
    go func() {
        Walk(t, ch)
        close(ch)
    }()
    for n := range ch {
        fmt.Println(n)
    }

    // Same
    fmt.Println("tree 1 eq 1 = ", Same(tree.New(1), tree.New(1)))
    fmt.Println("tree 1 eq 2 = ", Same(tree.New(1), tree.New(2)))
}

-Go

執筆者:


comment

メールアドレスが公開されることはありません。

関連記事

A Tour of Go Exercise: Maps

マップのエクササイズ。 コード的にGoらしく美しいかは不明ですが無事完了。 package main import ( “golang.org/x/tour/wc” “strings” ) func …

A Tour of GoのExercise: Loops and Functionsが難しい・・・

昨日からA Tour Of Goをはじめました。 皆さんオリジナル(英語版)をやって見るようにと進めてくれているのですが、まずは日本語を進めています。 そして早速Exercise: Loops and …

Go言語の環境構築 WIndows10版

ふとGo言語でツールを作って見ようと思ったので環境構築をメモ。 今回はWindows10で構築します。 Goをダウンロード GoからWindows版をダウンロードします。 今回はgo version …

A Tour of Go Exercise: Slices

スライスのエクササイズ。 スライス自体の概念がイマイチしっくり来ていないところがありますがLoops and Functionsのエクササイズに比べるとあんまり悩むことなく実装はできた感じ。 ただGo …