Sunday, 12 December 2021

Go cheating sheet

Find package

pkg.go.dev

Handle dependency

Create a go.mod

go mod init some_name

Install package

go mod tidy

Change default path to search for a module

go mod edit -replace example.com/greetings=../greetings

Run program

//run directly
go run sample.go

//compile and then run
go build sample.go
./sample

Format codes

go has declared a standard format to avoid pointless debate about trivial format details. Run command below to format codes.

go fmt mysample.go

Some syntax

Loop

//go does not have while loop. use for loop
for condition {
....
}

If statement

//The if expression may be preceded by a simple statement, 
//which executes before the expression is evaluated.
if x := f(); x < y {
    return x
}

Math

It does not have built in max or min function

// get 4
9/2

string

here is a discuss about string and the corresponding char array

Useful built-in strin function

var jewels = "abcd"
var jArr = []rune(jewels)

//convert array rune back to string
mystr :=string(jArr)

//loop through string. Here r is type of rune. However,
//str := "hello" str[0] is of type byte
for _, r := range "hello" {
	fmt.Println(r)
}

//cast a byte to string
var s = string(jwels[0])

//convert a string to int[26]
var arr1 [26]int
for _, r := range word1 {
	arr1[int(r)-97]++
}

//number to string
x=123
t :=strconv.Itoa(x)

//string to int
i, _ := strconv.Atoi("98")

//substring. result is "bc"
s := "abcdef"
fmt.Println(s[1:3])

//build big string. similiar to java string build approach
var ans bytes.Buffer
ans.WriteString("hello")

//back to string
return ans.String()

//split string by spaces to array
sample := "one    two   three four "
words := strings.Fields(sample) //["one", "two", "three", "four"]

//split by string
parts := strings.Split(path, "/")

//join back to sample
strings.Join(words, " ")

//convert int to binary string and convert back
bn := strconv.FormatInt(int64(num), 2)
k, _ :=strconv.ParseInt(string(result), 2, 64)
ans := int(k)

//use bytes package bytes.Buffer to build string
func comma(s string) string {
    var buf bytes.Buffer

    if len(s) <= 3 {
        return s
    }

    for i := 0; i < len(s); i++ {
    	//to write strind, do buf.WriteString("hi")
        buf.WriteByte(s[i])
        if (len(s)-1-i) > 0 && (len(s)-i-1)%3 == 0 {
            buf.WriteByte(',')
        }
    }

    return buf.String()

}

//remove all no alphnumeric chars from string
s := "A man, a plan, a canal: Panama"
reg, _ := regexp.Compile("[^a-zA-Z0-9]+")
   
processedString := reg.ReplaceAllString(s, "")
fmt.Println(processedString) // AmanaplanacanalPanama

//to lower case    
leo:= strings.ToLower(processedString)
fmt.Println(leo) //amanaplanacanalpanama

//convert byte to string. Also repeat a string
 var mb byte
 mb='n'
 mystr := strings.Repeat(string(mb),5)
 fmt.Println(mystr) //nnnnn
 
 //convert hex to int64  "0xde0b6b3a7640000" 1*10^18 wei = 1 
 //ETH "0x" means it is hex
 result, _ := strconv.ParseInt("de0b6b3a7640000", 16, 64)
 fmt.Println(result)
 
//create array of lower case letters
digits :=[]byte("abcdefghijklmnopqrstuvwxyz")

//substring s[start:end] end is exclusive
s := "Hello World"
fmt.Println(s[1:4])   // ell

//build int array. Here s is string of 26 lower case
var pool [26]int
for _, r := range s {
    pool[int(r)-97]++
}

//leetcode 2399
func checkDistances(s string, distance []int) bool {
    var myMap = make(map[rune]int)
    
    //loop through string and we get rune
    for _, r := range s {
        myMap[r] =1
    }
  
    for c, _ := range myMap {
        //rune convert to string
        var subs = string(c)
        
        //rune is int. Therefore, c-97 get index. Also use Index, LastIndex functions
        if strings.LastIndex(s, subs) - strings.Index(s, subs)-1 != distance[c-97] {
            return false;
        }
    }
   
    return true
}

//strings package has lots of useful functions
func maximumOddBinaryNumber(s string) string {
    one := strings.Count(s, "1");
    return strings.Repeat("1", one-1) + strings.Repeat("0", len(s)-one) + "1"; 
}

map

// int to int
 var myMap = make(map[int]int)

//key is rune and value is another map
 var myMap = make( map[rune]map[rune]int)
 
 //loop through map
 for key, val := range myMap {
 .....
 }
 
 //check if 2 is key is myMap. If it is, ok will be true
 j, ok := myMap[2]
 
 //also make(map[int]int) seems to  be default value to be 0.
 //The codes below prints out 0
 var myMap = make(map[int]int)
 fmt.Println(myMap[10])
 
 //default to be false. Print out false
 var myMap = make(map[int]bool)
 fmt.Println(myMap[10])
 
 //there is no clear map function. Therefore, just clear a new one
 myMap = make(map[int]int)
 
 //map as set
var mySet = make(map[int]bool)
mySet[1] = true
if mySet[1] {
    fmt.Println("have 1")
}

if mySet[2] {
    fmt.Println("have 2")
} else {
    fmt.Println("not have 2")
}

Array and Slices

//initiate an array. Type is array of [4]int
//To check type, can do fmt.Println(reflect.TypeOf(myArr))
var myArr [4]int

//if length is decided in runtime, have to use make
//type is []rune
myArr := make([]rune, len(indices))

//make a empty slice. type is []int
ans := make([]string, 0)

//another way. type is []int
ans := []int{}
        
//define slice. type is []int
var ans = []int{9, 6}

//two dimension
var trust = [][]int{{1,2},{2,8}}

//... the array length is determined by number of initializers
var ans = [...]int{9, 6} //type of int[2]

//loop through
for _, v := range ans {
}


//sort. all are in house sort
strs := []string{"c", "a", "b"}
sort.Strings(strs)
   
ints := []int{7, 2, 4}
sort.Ints(ints)

//sort array [26]int
var arr1 [26]int
sort.Ints(arr1[:])

//reverse sort. ints become 7, 4, 2
sort.Sort(sort.Reverse(sort.IntSlice(ints)))

//sort slices by lambdaish
//we want to sort [[4,5],[2,4],[4,6],[3,4],[0,0],[1,1],[3,5],[2,2]]
sort.Slice(intervals, func(i, j int) bool {
	return intervals[i][0] < intervals[j][0]
})  //intervals become [[0 0] [1 1] [2 4] [2 2] [3 5] [3 4] [4 6] [4 5]]

//append. can append multiple element
 var ans[] int
 ans = append(ans, 1, 2) //now ans = [1,2]
 
//join string array to a string
strings.Join(ans, " ")

//pop the first. Actually using sub array
arr := []int{1, 2, 3, 4, 5}
arr = arr[1:]
//get [2,3,4,5]
fmt.Println(arr)

//clone array array. First make an empty array. Then do append
temp := make([]int, 0)
temp = append(temp, score...)

//custom sort. can sort in desc
 var odd = []int {1,3,7}
 sort.Slice(odd, func(i, j int) bool {
     return odd[i] > odd[j]
 })
fmt.Println(odd) //7,3,1

//remove last element from array
stack = stack[:len(stack)-1]

Type convert

//convert byte to int. here n is 97
var a = 'a'
n := int(a)

type keyword

type keyword is there to create a new type

//create a new type Vertex which is type of struct
type Vertex struct {
  X int
  Y int
}

func main() {
  v := Vertex{1, 2}
  v.X = 4
  fmt.Println(v.X)
}

//another example
type Currency int

We can add a method to struct. Noted the syntax is different from normal function definition

package main

import (
    "fmt"
)

type Vertex struct {
    x int
    y int
}

//add a method to struct Vertex. Pay attention to syntax
func (v Vertex) distance() int {
    return v.x*v.x + v.y*v.y
}

func main() {
    v := Vertex{1, 2}
    fmt.Println(v.x)
    fmt.Println(v.distance())
}

enums and iota

Use to define a sequence of constants. For the below example, start USD to be 0

const (
    USD int = iota
    CAD
    RMB
)

func main() {
    fmt.Println(CAD) // 1
}

The below is example to use enum. Create a custom type and define backend raw type. Then use const to define enum

type combineType string

const (
    SAME combineType = "same"
    DIFF = "diff"
)

func makeS(a int, b int) string {
    var c combineType = SAME
    if a != b {
        c=DIFF
    }
    if c=="same" {
        return strconv.Itoa(a)
    } else {
        return strconv.Itoa(a) + "->" + strconv.Itoa(b)
    }
}

Some Leetcode solutions

Leetcode 1290

func getDecimalValue(head *ListNode) int {
    var ans bytes.Buffer
    
    for head.Next != nil {
        ans.WriteString(strconv.Itoa(head.Val))
        head = head.Next
    }
    ans.WriteString(strconv.Itoa(head.Val))
    
    
    result, _ := strconv.ParseInt(ans.String(), 2 , 64)
    return int(result)
}

A fake class

Below is a solution for Leetcode 2671

type FrequencyTracker struct {
    mapN map[int]int
    mapF map[int]int
    
}


func Constructor() FrequencyTracker {
    var m1 = make(map[int]int)
    var m2 = make(map[int]int)
    return FrequencyTracker{m1, m2}
}


func (this *FrequencyTracker) Add(number int)  {
    j, ok := this.mapN[number]
    if ok {
        this.mapN[number] = j+1
        this.decreaseF(j)
        this.increaseF(j+1)
    } else {
        this.mapN[number] =1
        this.increaseF(1)
    }
    
}


func (this *FrequencyTracker) DeleteOne(number int)  {
    j, ok := this.mapN[number]
    if (ok) {
        if j==1 {
            delete(this.mapN, number)
        } else {
            this.mapN[number] = j -1
        }

        this.decreaseF(j)
        this.increaseF(j-1)
    }
    
}

func (this *FrequencyTracker) decreaseF(f int)  {
    if f>0 {
        j, _ := this.mapF[f]
        if j==1 {
            delete(this.mapF, f)
        } else {
            this.mapF[f] = j-1
        }
    }
}

func (this *FrequencyTracker) increaseF(f int)  {
    if f>0 {
        j, ok := this.mapF[f]
        if ok {
            this.mapF[f] = j+1
        } else {
            this.mapF[f] = 1
        }
    }
}


func (this *FrequencyTracker) HasFrequency(frequency int) bool {
    _, ok := this.mapF[frequency]

    
    return ok
}


/**
 * Your FrequencyTracker object will be instantiated and called as such:
 * obj := Constructor();
 * obj.Add(number);
 * obj.DeleteOne(number);
 * param_3 := obj.HasFrequency(frequency);
 */

Linked List

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
 
 //create a linked list [9, 8]
    node := ListNode{}
    node.Val = 9
    
    //add another node
    node2 :=ListNode{}
    node2.Val = 8
    node.Next = &node2
    
    head := &node
   
   //Another example to create [1, 2, 3] if we return head
   //create a head node and let head point to its address
    node := ListNode{1, nil}
    head := &node
    
    //use cur as an tempary bridge to add more node
    cur := &node
   
    //create node and assign it to cur's next.
    //Then move cur to the next
    cur.Next = &ListNode{2, nil}
    cur = cur.Next
    
    //repeat the above step
    cur.Next = &ListNode{3, nil}
    cur = cur.Next

Run function

//to run test.go go run test.go
package main

import "fmt"

func main() {
	res := tribonacci(25)
	fmt.Println(res)
}

func tribonacci(n int) int {
	if n == 0 {
		return 0
	}

	if n <= 2 {
		return 1
	}

	dp := make([]int, n+1)
	dp[0] = 0
	dp[1] = 1
	dp[2] = 1

	for i := 3; i <= n; i++ {
		dp[i] = dp[i-1] + dp[i-2] + dp[i-3]
	}

	return dp[n]
}

No comments:

Post a Comment