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)))
}