Created
June 17, 2018 10:07
-
-
Save falgon/fe1ebde33f0da774e3030bfa4e8eb941 to your computer and use it in GitHub Desktop.
My solutions of A Tour of Go and other practice golang codes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"sort" | |
"golang.org/x/tour/tree" | |
) | |
func Walk(t *tree.Tree, ch chan int) { | |
defer close(ch) | |
var walk func(*tree.Tree) | |
walk = func(t *tree.Tree) { | |
if t == nil { | |
return | |
} | |
walk(t.Left) | |
ch <- t.Value | |
walk(t.Right) | |
} | |
walk(t) | |
} | |
func test() bool { | |
ch, s := make(chan int), make([]int, 0) | |
go Walk(tree.New(1), ch) | |
for v := range ch { | |
s = append(s, v) | |
} | |
return sort.IntsAreSorted(s) | |
} | |
func Same(t1, t2 *tree.Tree) bool { | |
c1, c2 := make(chan int), make(chan int) | |
go Walk(t1, c1) | |
go Walk(t2, c2) | |
for v := range c1 { | |
if vt, ok := <- c2; v != vt || !ok { | |
return false | |
} | |
} | |
return true | |
} | |
func main() { | |
fmt.Printf("test: %t\n%t\n%t\n", | |
test(), | |
Same(tree.New(1), tree.New(1)), | |
Same(tree.New(1), tree.New(2))) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) (z float64, er error) { | |
z, er = 2., nil | |
if x < 0 { | |
er = ErrNegativeSqrt(z) | |
z = 0 | |
return | |
} | |
s := float64(0) | |
for i := 0; i < 10; i++ { | |
z = z - (z * z - x) / (2 * z) | |
if math.Abs(z - s) < 1e-10 { | |
break | |
} | |
s = z | |
} | |
return | |
} | |
func main() { | |
fmt.Println(Sqrt(2)) | |
fmt.Println(Sqrt(-2)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "fmt" | |
func fibonacci() func() int { | |
a, b := 0, 1 | |
return func () (r int) { | |
r = a | |
a, b = b, a + b | |
return | |
} | |
} | |
func main() { | |
f := fibonacci() | |
for i := 0; i < 10; i++ { | |
fmt.Println(f()) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "golang.org/x/tour/pic" | |
import "image" | |
import "image/color" | |
type Image struct{} | |
func (_ Image) At(x, y int) color.Color { | |
v := uint8(x ^ y + x ^ y) | |
return color.RGBA{v, v, 255, 255} | |
} | |
func (_ Image) Bounds() image.Rectangle { | |
return image.Rect(0, 0, 256, 256) | |
} | |
func (_ Image) ColorModel() color.Model { | |
return color.RGBAModel | |
} | |
func main() { | |
m := Image{} | |
pic.ShowImage(m) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"math" | |
) | |
func Sqrt(x float64) (z float64) { | |
z = 2. | |
s := float64(0) | |
for i := 0; i < 10; i++ { | |
z = z - (z * z - x) / (2 * z) | |
if math.Abs(z - s) < 1e-10 { | |
break | |
} | |
s = z | |
} | |
return | |
} | |
func main() { | |
fmt.Println(Sqrt(2)) | |
fmt.Println(math.Sqrt(2)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"golang.org/x/tour/wc" | |
"strings" | |
) | |
func WordCount(s string) (m map [string]int) { | |
m = make(map[string]int) | |
for _, f := range strings.Fields(s) { | |
m[f]++ | |
} | |
return | |
} | |
func main() { | |
wc.Test(WordCount) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"math/rand" | |
"sort" | |
"time" | |
"runtime" | |
"reflect" | |
) | |
func main() { | |
ar := shuffle(mkSeq(0, 10)) | |
fmt.Println(ar) | |
f := func(a []int) string { | |
return res2str(sort.IntsAreSorted, a) | |
} | |
res1, res2 := qsort(ar, func(x, y int) bool { return x < y }), qsort(ar, func(x, y int) bool { return x > y }) | |
fmt.Printf("%s%s", f(res1), f(reverse(res2))) | |
} | |
func reverse(ar []int) []int { | |
for i, j := 0, len(ar) - 1; i < j; i, j = i + 1, j - 1 { | |
ar[i], ar[j] = ar[j], ar[i] | |
} | |
return ar | |
} | |
func res2str(f func([]int) bool, ar []int) string { | |
return fmt.Sprintf("%v\n%s: %t\n", ar, runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name(), f(ar)) | |
} | |
func getFromComp(c func(int, int) bool) func(*int, *int) *int { | |
return func(x, y *int) *int { | |
if c(*x, *y) { | |
return x | |
} | |
return y | |
} | |
} | |
func flip(fn func(int, int) bool) func(int, int) bool { | |
return func(x, y int) bool { | |
return fn(y, x) | |
} | |
} | |
func qsort(ar []int, comp func(int, int) bool) (res []int) { | |
if len(ar) < 2 { | |
return ar | |
} | |
min_p, max_p := getFromComp(comp), getFromComp(flip(comp)) | |
med3_p := func(x, y, z *int) *int { | |
return max_p(min_p(x, y), min_p(max_p(x, y), z)) | |
} | |
p_swap := func(x, y *int) { | |
*y, *x = *x, *y | |
} | |
p_swap(&ar[0], med3_p(&ar[0], &ar[len(ar)/2], &ar[len(ar)-1])) | |
piv := ar[0] | |
left := []int{} | |
right := []int{} | |
for _, v := range ar[1:] { | |
if comp(v, piv) { | |
left = append(left, v) | |
} else { | |
right = append(right, v) | |
} | |
} | |
res = append(qsort(left, comp), piv) | |
res = append(res, qsort(right, comp)...) | |
return | |
} | |
func shuffle(ar []int) []int { | |
s := rand.NewSource(time.Now().Unix()) | |
rs := rand.New(s) | |
for i := len(ar) - 1; i >= 0; i-- { | |
r := rs.Intn(i + 1) | |
ar[i], ar[r] = ar[r], ar[i] | |
} | |
return ar | |
} | |
func mkSeq(min, max int) []int { | |
ar := make([]int, max-min+1) | |
for i := range ar { | |
ar[i] = min + i | |
} | |
return ar | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "golang.org/x/tour/reader" | |
type MyReader struct{} | |
func (_ MyReader) Read(rb []byte) (n int, er error) { | |
for i, _ := range rb { | |
rb[i] = 'A' | |
n++ | |
} | |
return | |
} | |
func main() { | |
reader.Validate(MyReader{}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"io" | |
"os" | |
"strings" | |
) | |
type rot13Reader struct { | |
r io.Reader | |
} | |
func (this *rot13Reader) Read(rb []byte) (n int, er error) { | |
if n, er = this.r.Read(rb); er == nil { | |
for i, c := range rb { | |
if c != ' ' { | |
t := 1 | |
if (c >= 'N' && c <= 'Z') || (c >= 'n' && c <= 'z') { | |
t *= -1 | |
} | |
rb[i] = c + byte(t * 13) | |
} | |
} | |
} | |
return | |
} | |
func main() { | |
s := strings.NewReader("Lbh penpxrq gur pbqr!") | |
r := rot13Reader{s} | |
io.Copy(os.Stdout, &r) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "golang.org/x/tour/pic" | |
func Pic(dx, dy int) (pic [][]uint8) { | |
pic = make([][]uint8, dy) | |
for i := range pic { | |
pic[i] = make([]uint8, dx) | |
for j := range pic { | |
pic[i][j] = uint8(i ^ j + j ^ i) | |
} | |
} | |
return | |
} | |
func main() { | |
pic.Show(Pic) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "fmt" | |
type IPAddr [4]byte | |
func (this IPAddr) String() string { | |
return fmt.Sprintf("%d.%d.%d.%d", this[0], this[1], this[2], this[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) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"sync" | |
) | |
type Fetcher interface { | |
Fetch(url string) (body string, urls []string, err error) | |
} | |
type Visited struct { | |
uri map[string]bool | |
m sync.Mutex | |
} | |
func (this *Visited) TestAndSetVisited(url string) bool { | |
defer func() { | |
this.uri[url] = true | |
this.m.Unlock() | |
}() | |
this.m.Lock() | |
return this.uri[url] | |
} | |
func Crawl(url string, depth int, fetcher Fetcher, vis *Visited, wg *sync.WaitGroup) { | |
defer wg.Done() | |
if depth <= 0 || vis.TestAndSetVisited(url) { | |
return | |
} | |
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 { | |
wg.Add(1) | |
go Crawl(u, depth - 1, fetcher, vis, wg) | |
} | |
return | |
} | |
func main() { | |
var wg sync.WaitGroup | |
wg.Add(1) | |
go Crawl("http://golang.org/", 4, fetcher, &Visited{ uri: make(map[string]bool) }, &wg) | |
wg.Wait() | |
} | |
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) | |
} | |
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/", | |
}, | |
}, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment