Go

A Tour of Go Exercise 自己解答

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

© 2024 ビー鉄のブログ Powered by AFFINGER5