Skip to content

Instantly share code, notes, and snippets.

@harpresing
Last active July 7, 2020 00:33
Show Gist options
  • Save harpresing/a5541bdcd878cdafd6288f4637207c0c to your computer and use it in GitHub Desktop.
Save harpresing/a5541bdcd878cdafd6288f4637207c0c to your computer and use it in GitHub Desktop.

Question 1

Use newtons method to find square roots

Solution

package main

import (
    "fmt"
)

func Sqrt(x float64) float64 {
    del :=  0.0000001
    srt, prevSrt := x, x * 2
    for prevSrt - srt > del  {
        prevSrt = srt
        srt = srt - (srt*srt - x)/(2 * srt)
        //fmt.Printf("Difference of prev - srt = %v\n", prevSrt-srt)
        }
    return srt
}

func main() {
    fmt.Println(Sqrt(25))
}

Question 2

Implement Pic. It should return a slice of length dy, each element of which is a slice of dx 8-bit unsigned integers. When you run the program, it will display your picture, interpreting the integers as grayscale (well, bluescale) values.

The choice of image is up to you. Interesting functions include (x+y)/2, x*y, and x^y.

(You need to use a loop to allocate each []uint8 inside the [][]uint8.)

(Use uint8(intValue) to convert between types.)

Solution

package main

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

func Pic(dx, dy int) [][]uint8 {
    b := make([][]uint8, dy)
    for i:= range b{
        b[i] = make([]uint8, dx)
        for j:=range b[i]{
        b[i][j] = uint8((i*j)/10)
        } 
    }
    return b
}

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

Question 3

Implement WordCount. It should return a map of the counts of each “word” in the string s. The wc.Test function runs a test suite against the provided function and prints success or failure.

You might find strings.Fields helpful

Solution

package main

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

func WordCount(s string) map[string]int {
	var ok bool
	count := make(map[string]int)
	words := strings.Fields(s)
	for _, word:= range words{
		_, ok = count[word]
		if ok == false { 
			count[word] = 1
		}else { 
			count[word] += 1 
		}
	}
	return count
}

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

Question 4

Let's have some fun with functions.

Implement a fibonacci function that returns a function (a closure) that returns successive fibonacci numbers (0, 1, 1, 2, 3, 5, ...).

Solution

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
	x := 0
	y := 1
	return func() int{
		x, y = y, x+y
		return y
	}
}

func main() {
	f := fibonacci()
	fmt.Println("0\n1")
	for i := 0; i < 20; i++ {
		fmt.Println(f())
	}
}

Question 5

Exercise: Stringers Make the IPAddr type implement fmt.Stringer to print the address as a dotted quad.

For instance, IPAddr{1, 2, 3, 4} should print as "1.2.3.4".

Solution

package main

import "fmt"

type IPAddr [4]byte

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

Question 6

Exercise: Errors Copy your Sqrt function from the earlier exercise and modify it to return an error value.

Sqrt should return a non-nil error value when given a negative number, as it doesn't support complex numbers.

Create a new type

type ErrNegativeSqrt float64 and make it an error by giving it a

func (e ErrNegativeSqrt) Error() string method such that ErrNegativeSqrt(-2).Error() returns "cannot Sqrt negative number: -2".

Note: a call to fmt.Sprint(e) inside the Error method will send the program into an infinite loop. You can avoid this by converting e first: fmt.Sprint(float64(e)). Why?

Change your Sqrt function to return an ErrNegativeSqrt value when given a negative number.

Solution

package main

import (
	"fmt"
)

type ErrNegativeSqrt float64

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

func Sqrt(x float64) (float64, error) {
	if x < 0 {
		return x, ErrNegativeSqrt(x)
	} else {
    	del :=  1e-9
    	srt, prevSrt := x, x * 2
		for prevSrt - srt > del  {
        	prevSrt = srt
        	srt = srt - (srt*srt - x)/(2 * srt)
        }
	  return srt, nil
	}
}

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

Question 7

Exercise: Readers Implement a Reader type that emits an infinite stream of the ASCII character 'A'.

Solution

package main

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

type MyReader struct{}

func (m MyReader) Read(b []byte) (int, error) {
	for i := range b {
		b[i] = 'A' 
	}
	return len(b), nil
}

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

Question 8

Exercise: rot13Reader A common pattern is an io.Reader that wraps another io.Reader, modifying the stream in some way.

For example, the gzip.NewReader function takes an io.Reader (a stream of compressed data) and returns a *gzip.Reader that also implements io.Reader (a stream of the decompressed data).

Implement a rot13Reader that implements io.Reader and reads from an io.Reader, modifying the stream by applying the rot13 substitution cipher to all alphabetical characters.

The rot13Reader type is provided for you. Make it an io.Reader by implementing its Read method.

package main

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

type rot13Reader struct {
	r io.Reader
}

func (rt rot13Reader) Read(b []byte) (int, error) {
	n, err := rt.r.Read(b)
	for i:=0; i < n; i++ {
		if b[i] >= 60 && b[i] <= 77 || b[i] >= 90 && b[i] <= 105 {
			b[i] += 13
		} else if b[i] > 77 && b[i] <= 90 || b[i] > 105 && b[i] <= 122 {
			b[i] -= 13
		}
	}
	return n, err
}

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

Question 9


Question 10

Exercise: Equivalent Binary Trees

  1. Implement the Walk function.

  2. Test the Walk function.

The function tree.New(k) constructs a randomly-structured binary tree holding the values k, 2k, 3k, ..., 10k.

Create a new channel ch and kick off the walker:

go Walk(tree.New(1), ch) Then read and print 10 values from the channel. It should be the numbers 1, 2, 3, ..., 10.

  1. Implement the Same function using Walk to determine whether t1 and t2 store the same values.

  2. Test the Same function.

Same(tree.New(1), tree.New(1)) should return true, and Same(tree.New(1), tree.New(2)) should return false.

The documentation for Tree can be found here.

Solution:

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 {
	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{
	c1, c2 := make(chan int), make(chan int)
	go Walk(t1, c1)
	go Walk(t2, c2)
	if <-c1 == <-c2 {
		return true
	}else {
		return false
	}
}

func main() {
	t1 := tree.New(1)
	t2 := tree.New(8)
	ch := make(chan int)
	go Walk(t1, ch)
	go Walk(t2, ch)
	fmt.Println("the two trees are")
	for i:=0; i<20; i++{
		fmt.Println(<-ch)
	}
	fmt.Println("the two trees are same?", Same(t1, t2))
}

Question 11

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment