32
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

A Tour of Go 練習問題を解く

32
Last updated at Posted at 2017-03-04

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/",
		},
	},
}

32
21
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?