Sunday, 15 May 2022

AWS Application Load Balancer

You only need to expose the load balancer to the outside world. The load balancer then forwards requests to the EC2 instances or other services behind it. AWS provides different load balancers. Application load Balancer supports HTTP and HTTPS protocols.

ALB consists of these parts

  • Load balancer
  • Listener - it links to a target group. It sets up rules based on the port, protocol, query string etc to decide which target group to send
  • Target Group - it defines your group of backends

Wednesday, 11 May 2022

Amazon EC2

Security Group

Security group controls incoming and outcoming traffic to the resources which are associated with that security group such as your virtual machine, your database, or your load balancer with a firewall. It acts as a virtual firewall

  • A resource can associated with multiple security group
  • A security group can assigned to multiple resources
  • income source can be ip, and it can be security group

If get connection timeout,it may be caused by security group. Check the security group associated with that resource.

SSH to EC2 Instance

Connect to EC2 instance. Click the connect tab of that instance to find public ip address and user name. issue the below. That pem file is generated when you create the EC2 instance. When create a EC2 instance, it will ask if you want to generate key pair.

If key pair is lost, you can not recover it because AWS does not store a copy of it. If you can only find a private ip, it is inside a vpc. Therefore, need to vpn to that network and use private ip to connect.

//see bad permission. chmod 400 mykey.pem to fix it
ssh -i EC2-tutorial.pem ec2-user@54.189.138.151

IAM Role

We can attach a IAM role to instance. We can perform some actions after log into the instance based on permissions assigned to that IAM role. Never do aws config inside instance directly

  • To see RAM role attached, click security tab
  • To attache RAM role, select action drop down and select security option. Then choose Modify RAM role

Instance Types

  • General Purpose
  • Compute Optimized
  • Memory Optimized
  • Accelerated Computing
  • Storage Optimized ( great for workloads requiring high, sequential read/write access to large data sets on local storage)

Tuesday, 5 April 2022

PHP Monolog

PHP Monolog can route log into different destinations such as database, file etc. The below is an example to put log into a file.

<?php
require "vendor/autoload.php";
use Monolog\Logger;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler;

//create a info handler
$infoHandler = new StreamHandler("/var/src/log/err.log", Logger::INFO);
$formatter = new LineFormatter(null, null, false, true);
$infoHandler->setFormatter($formatter);

//associate handler to log
$logger = new Logger('TestApp01');
$logger->pushHandler($infoHandler);

//log something
$logger->info('Try to test of my application logging.');

Also we can route log to stdout. In PHP slim framework, we can see these log info in application log for stdout.

$log = new Logger("stdout");
$streamHandler = new StreamHandler('php://stdout', Logger::DEBUG);
$log->pushHandler($streamHandler);

$log->debug('Foo foo');

When do PHPUnit Test, we can

fwrite(STDERR, "some variable");

Tuesday, 29 March 2022

Useful SQL Query

GROUP_CONCAT

# Leetcode 1484
select sell_date, count(*) as num_sold, 
group_concat(product order by product) as products
from

(select distinct sell_date, product
from Activities
) as new_table

group by sell_date;

If Statement

#leetcode 1407
select name, if (sum(distance) is null, 0, sum(distance)) as travelled_distance 
from Users
left join Rides on (Rides.user_id = Users.id)
group by Users.id
order by travelled_distance  desc, name asc;

Case Statement

# partial solution of Leetcode 1179. Sytax case when ... then ..
#when .. then ... else ... end
select id,
    sum(case when month="Jan" then revenue else null end) as Jan_Revenue
from Department
group by id;

count(distinct id)

select teacher_id, count(distinct subject_id) as cnt
from Teacher
group by teacher_id;

Tuesday, 22 March 2022

Set Initial Data in Redux Form

Some time we need to set initial values for some elements in Redux Form.

Assume we have two fields in the form

<Field name='data.customer_id'   .... />

<Field name='type' .... />

To set initial data, we can use initialValues prop of Redux Form

//noted that the first name of Field has used dot notation format
let values = {
	data: {customer_id:100}, type: "car"
}

<myForm initialValues={values} ...... />

Modify other field value by change handler of another field

//can change value for filed data.customer_id
function onChangeForOurTypeField (val) {
        this.props.change("data", {customer_id: 0})
}

Saturday, 19 March 2022

Code examples for some algorithm

Provide my code examples to use some useful algorithms

Priority Queue

Java Queue

Binary Search

When mid is equals, sometimes we need to return. Sometimes, we need to move boundary. However, based one business logic, we may move in the different direction.

For python, it has built function

 c = max(0, bisect_right(starts, p) - bisect_left(ends,p))
//part of solution for Leetcode 1011
function shipWithinDays(weights: number[], days: number): number {
  let low = Math.max(...weights);
  let minC = low;
  let high = 0;
  for (let w of weights) high = high + w;

  while (low <= high) {
    let mid = Math.floor((low + high) / 2);

    if (canLoad(weights, days, mid)) {
      high = mid - 1;
    } else {
      low = mid + 1;
    }
  }

  //make sure that small is not below initial low
  //also check if small is good enough. Noted that high
  //should be smaller than low after done with search
  let small = Math.max(high, minC);
  
  if (canLoad(weights, days, small)) return small;

  return low;
}

Slid Window

  • Start window for index 0
  • Move the end index of window one by one
  • Create a check to see if current window is good
  • Move start window util window is goog again if current window is not good. Sometime, can jump to end index of current slid window directly (Leetcode 1839)
  • Think carefully when decide where to move start to
//solution for Leetcode 424. Can solve 1004, 2024 by using this skill
class Solution {
    public int characterReplacement(String s, int k) {
        //used to store count of char. char value - 'A' is index
        var arr = new int[26];
        
        var l = s.length();
      
        int wStart, wEnd, ans, curLength;
        wStart=wEnd=ans=curLength=0;
        
        for (wEnd=0; wEnd<l; wEnd++) {
            arr[s.charAt(wEnd)-'A']++;
            curLength = wEnd -wStart+1;
            
            //see if good. we keep the most occurence of a char
            //the difference between the most occurence and length
            //is the number of chars to be replaced
            if (curLength - this.max(arr) <=k) {
                ans = Math.max(ans, curLength);
                continue;
            }
            
            //if not good. make it good by slid the start of window
            //this is core part of slid window
            while (curLength - this.max(arr) >k) {
                arr[s.charAt(wStart)-'A']--;
                wStart++;
                curLength = wEnd-wStart+1;
            }
            
        }
        
        return ans;
 
    }
    
    //find max value of array
    private int max(int[] arr) {
        var ans = 0;
        for (int n: arr) {
            ans = Math.max(ans, n);
        }
        
        return ans;
    }

}

Bucket Sort

If we are talking about a frequency problem, may think of bucket sort. The main point is to create an list of buckets. Put some elements into a one bucket. The below we use ascii value of chars as index of an array, so we can put the same chars into the same bucket.

//Leetcode 415
class Solution {
    public String frequencySort(String s) {
        //create a bucket. use ascii vaues as index.
        //all letters are fit into this bucket.
        var arr = new int[150];
        for (int i=0; i<s.length(); i++) {
            var c = s.charAt(i);
            arr[c]++;
        }
        
      
       var map = new TreeMap<Integer, Integer>(Collections.reverseOrder());
       for (int n: arr) map.put(n, 1);
        
        var b = new StringBuilder();
        for (int k : map.keySet()) {
            if (k==0) break;
            
            for (int i=0; i<150; i++) {
                if (arr[i]==k) {
                    char c= (char)(i);
                    for (int j=0; j<k; j++) b.append(c);
                }
            }
            
        }
 
        return b.toString();
        
    }
}

Linked List

  • check is null. list == null
  • Create a head. Let a temp = head. Then move temp
  • To move. temp.next = new node. temp = new node
  • Initiate a empty node. ListNode node = null
//Leet code 2
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode ans = null;
        ListNode temp = null;
        var n1 = 0;
        var n2 = 0;
        var sum = 0;
        var carry = 0;
        var cur = 0;
        
        while (l1!=null || l2!=null) {
            n1 = l1!=null ? l1.val : 0;
            n2 = l2!=null ? l2.val : 0;
            
            sum = (n1+n2+carry);
            
            
            
            carry = sum/10;
            cur = sum%10;
            
            var node = new ListNode(cur);
            
            //have not created yet
            
            if (ans==null) {
                ans = node;
                temp = ans;
            } else {
                //will move temp
                temp.next = node;
                temp = node;
            }
            
            if (l1 != null)  l1=l1.next;
            
            if (l2 != null) l2=l2.next;
         
        }
        
        //after loop all l1 and l2, see if we have carry
        if (carry>0) {
            temp.next = new ListNode(carry);
        }
        
        return ans;
        
    }
}

Stack

Java stack provide function pop(), peek(), push(), empty() and size() etc

//leetcode 921
class Solution {
    public int minAddToMakeValid(String s) {
        var stack = new Stack<Character>();
        
        for (int i=0; i<s.length(); i++) {
            char c = s.charAt(i);
            if (stack.empty() || c=='(') {
                stack.push(c);
                continue;
            }
            
            if (stack.peek() == '(') {
                stack.pop();
            } else {
                stack.push(c);
            }
         
        }
       
        return stack.size();
    }
}

Can put object into stack. In some cases, this Java Pair object is very useful

//Leetcode 1209
class Solution {
    public String removeDuplicates(String s, int k) {
        var stack = new Stack<Pair <Character, Integer>>();
        
        //not need to check if stack is empty
        stack.push(new Pair('$', 1));
        
        for (char c: s.toCharArray()) {
            if (c != stack.peek().getKey()) {
                stack.push(new Pair(c, 1));
            } else {
                var p = stack.pop();
                if (p.getValue()<k-1) {
                    //push back
                    stack.push(new Pair(c, (int)p.getValue()+1));
                }
            }
        }
        
        var ans = new StringBuilder();
        for (Pair<Character, Integer> p: stack) {
            char c = p.getKey();
            int count = p.getValue();
            if (c=='$') continue;
            
            for (int j=0; j<count; j++) ans.append(c);
        }
        
        return ans.toString();
    }
}

For Python, we can use list as stack. append() to add the end of list. pop() remove from the end of list

#leetcode 56
class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        intervals.sort(key=lambda x:[x[0], x[1]])
       
        ans = []
        ans.append(intervals[0])
        i=1
        l = len(intervals)
        
        while i < l:
            cur = intervals[i]
            pre = ans.pop()
            
            if pre[1] >= cur[0]:
              
                ans.append([pre[0], max(pre[1], cur[1]) ])
            else:
                ans.append(pre)
                ans.append(cur)
            i+=1
           
        return ans

Tree Inorder Traverse

//Leetcode 94
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        var ans = new ArrayList<Integer>();
        var stack = new Stack<TreeNode>();
        
        var cur = root;
        
        while (cur!=null || !stack.isEmpty()) {
            while(cur!=null) {
                stack.add(cur);
                //visit left first
                cur = cur.left;
            }
            
            //read the end of left
            cur = stack.pop();
            ans.add(cur.val);
            
            //visit right. Although last left does not have right. not last left
            //may have right. paht is lowest left, parent node, left node.
            cur = cur.right;
        }
        
        return ans;
    }
}

Here is a example to traverse right, parent and left using the same skill

//Leetcode 1038
class Solution {
    public TreeNode bstToGst(TreeNode root) {
        //sum so far
        int sum = 0;
        
        //in order search. However, right first
        var stack = new Stack<TreeNode>();
        
        var cur = root;
        
        while (cur!=null || !stack.isEmpty()) {
            while (cur!=null) {
                stack.add(cur);
                cur = cur.right;
            }
            
            cur = stack.pop();
            sum = cur.val + sum;
            cur.val = sum;
            
            cur = cur.left;
        }
        
        return root;
    }
}

Tree Preorder traverse

root, left, right..

//leetcode 144
  class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        var list = new ArrayList<Integer>();
        
        var s = new Stack<TreeNode>();
        var cur = root;
        
        while (cur!= null || !s.isEmpty()) {
            while (cur!=null) {
                //do something here. Inorder traversal, we do something outside while loop!
                list.add(cur.val);
                s.add(cur);
                cur = cur.left;
            }
            
            
            cur= s.pop();
            cur = cur.right;
        }
        
       return list;
    }
}

Build a tree from array list

 TreeNode root1 = new TreeNode(list.get(0));
//this node is first connected to root. Then act as moving part
        TreeNode temp = root1;
   
        for (int i=1; i<list.size(); i++) {
            var node = new TreeNode(list.get(i));
            
            temp.right = node;
            temp = node;
            
        }
        return root1;

Dynamic Programming

Try to solve a complex problem by solving sub problems.

  • Sub problem is easy to solve.
  • Solution for sub problem can be used to solve that big problem
  • Need to figure out how to merge a sub problems to a big problem. It is also called state transition
  • Normally need a one dimension array or a two to remeber the solutions for sub problems.
  • Need to fill array or table in some sequence. Therefore, we can do state transition

Here is a solution for Leetcode 516. Longest Palindromic Subsequence.

class Solution {
    public int longestPalindromeSubseq(String s) {
        int l = s.length();
        
        //row number is the start of string
        //col number is the end of string
        var dp = new int[l][l];
        
        //fill equal. if i==i, value is 1.
        for (int i=0; i<l; i++) dp[i][i]=1;
        
        for (int i=l-1; i>=0; i--) {
            for (int j=i+1; j<l; j++) {
            	//if end char is the same as the start char, at least get 2
                if (s.charAt(i)==s.charAt(j)) {
                    if (j-i ==1) {
                        dp[i][j]=2;
                    } else {
                        dp[i][j] = 2 + dp[i+1][j-1];
                    }
                    
                } else {
                	//not equals, we can drop one char from one of the end
                    //and use the max value of this two casess
                    dp[i][j] = Math.max(dp[i][j-1], dp[i+1][j]);
                    
                }
            }
        }
        
       return dp[0][l-1]; 
    }
   
}

deep first search

It can be used to traverse graph including binary tree.

//Leetcode 1971
class Solution {
    public boolean validPath(int n, int[][] edges, int source, int destination) {
        // store vetexs where one vetex can go
        var map = new HashMap<Integer, ArrayList<Integer>>();
        
        //populate map. Because it is a bi-directional graph,
        //need to populate both end of the edge
        for(int[] e: edges) {
            if (map.containsKey(e[0])) {
                var list = map.get(e[0]);
                list.add(e[1]);
                map.put(e[0], list);
            } else {
                var list = new ArrayList<Integer>();
                list.add(e[1]);
                map.put(e[0], list);
            }
           
            // the other direction
            if (map.containsKey(e[1])) {
                var list = map.get(e[1]);
                list.add(e[0]);
                map.put(e[1], list);
            } else {
                var list = new ArrayList<Integer>();
                list.add(e[0]);
                map.put(e[1], list);
            }
        }
        
       
        //visited map to remember if this vertex has been visited
        var visited = new HashMap<Integer, Integer>();
        
        //store vetexs to visit
        var stack = new Stack<Integer>();
        
        //start
        stack.add(source);
        
        //do dfs search
        while (!stack.isEmpty()) {
            int cur = stack.pop();
            
            //only not visited node is to be processed.
            //in the other hand, if the vetex has been visited,
            //it will be pop out stack and do nothing with it
            if (!visited.containsKey(cur)) {
                //step one: mark as visited
                visited.put(cur, 1);
                
                //step two: check if it is the destination
                if (cur == destination) return true;
                
                //step three: put all adjacent vetexs into stack
                if (map.containsKey(cur)) {
                    var aEdges = map.get(cur);
                    for (int e: aEdges) {
                        stack.add(e);
                    }
                }
            }
        
        }
        
        return false;
        
    }
}

Recursive version of dfs

//Leetcode 1971
class Solution {
    public boolean validPath(int n, int[][] edges, int source, int destination) {
        // store adjecent edges
        var map = new HashMap<Integer, ArrayList<Integer>>();
        
        //populate map
        for(int[] e: edges) {
             
            if (!map.containsKey(e[0])) {
                map.put(e[0], new ArrayList<Integer>());
            }
            map.get(e[0]).add(e[1]);
            
            if (!map.containsKey(e[1])) {
                map.put(e[1], new ArrayList<Integer>());
            }
            map.get(e[1]).add(e[0]);
     
        }
        
        return dfs(map, source, destination, new HashSet<Integer>());
    
    }
    
    public boolean dfs(HashMap<Integer, ArrayList<Integer>> map, int source, int destination, HashSet<Integer> visited) {
        
        if (source==destination) return true;
        //has visited all
        if (map.size()==visited.size()) return false;
       
        for(Integer n: map.get(source)) {
            if (visited.contains(n)) continue;
            
            //visit n. Then dfs on n
            visited.add(n);
            
            if (n==destination) {
                return true;
            } else {
                var ans = dfs(map, n, destination, visited);
                if (ans) return true;
            }
        }
        
        return false;
   
    }
}

Minimum Spanning Tree

Use the Prim-Jarnik algorithm to build a minimum spanning tree. The main idea is to start with a vertex. For every iteration, try to find a minum weight edege and add that edege to the tree. When we add all vertexs into tree, we are done. Here is an example to build a tree for a Leetcode problem. We build a tree to find the mininal total weights. LeetCode 1584

LeetCode 1584
class Solution {
    public int minCostConnectPoints(int[][] points) {
        //pre cal distance between all points
        int l = points.length;
        int[][]dists = new int[l][l];
        
        for (int i=0; i<l; i++) {
            var p = points[i];
            for (int j=0; j<l; j++) {
                var q = points[j];
                dists[i][j] = getDis(p, q);
            }
        }
        
        int ans =0;
        
        //build tree.
        //pick a point as start point for tree. Every time, pick the point which
        //has the shortest distance with tree. Need to consider point to the current
        //added tree point and points which are in the tree before.
        var tree = new HashSet<Integer>();
        
        //store min distance to tree for every points
        var disToTree = new int[l];
        for (int i=0; i<l; i++) disToTree[i] =Integer.MAX_VALUE;
        
        //add first point as base
        var cur = 0;
        tree.add(0);
        
        //update dis for point 0
        disToTree[0] = 0;
        
        while (tree.size()<l) {
            //store possible selected point and min distance so far
            int selectedP = 0;
            int minDis = Integer.MAX_VALUE;
            
            for (int i=0; i<l; i++) {
              //if this point is in the tree, skip
               if (tree.contains(i)) continue;
                
                //calculate distance between current tree point and candidate
                //update tree distnace for i
                int cost = dists[cur][i];
                disToTree[i] = Math.min(cost, disToTree[i]);
                
                //if we get smaller distance, update candidate
                if (disToTree[i] < minDis) {
                    minDis = disToTree[i];
                    selectedP = i;
                }
            }
            
            //update tree
            tree.add(selectedP);
          
            //update ans
            ans = ans + minDis;
            
            //update current vetex
            cur = selectedP;
        }
        
        return ans;
        
    }
    
    //cal distance between two points
    private int getDis(int[]p, int[]q) {
        return Math.abs(p[0] - q[0]) + Math.abs(p[1] - q[1]);
    }
}

Union Find

Find which group a set should be in; then union disjoint-set data. Union Find

//LeetCode 1202
class Solution {
    //store parents for every index of string
    int[] parent;
    public String smallestStringWithSwaps(String s, List<List<Integer>> pairs) {
        int n = s.length();
        parent = new int[n];
        
        //set parent of every index to be itself
        for (int i=0; i<n; i++) parent[i]=i;
        
        //do union find. Use find function to find parent of a swap list.
        //then union them
        for (List pair: pairs) {
            var p1 = find((int)pair.get(0));
            var p2 = find((int)pair.get(1));
            if (p1>=p2) {
                parent[p1] = parent[p2];
            } else {
                parent[p2] = parent[p1];
            }
        }
        
        //we use some short cut to do union and not a strictly union find
        //we need to update parent array once to solve the short cut problem
        //this is not a necessary step for other union find problem
        for (int i=0; i<n; i++) {
            parent[i] =find(parent[i]);
        }
       
        //use a hashMap to group indexes which has the same parent
        //the values are stored in a tree set, so it is sorted
        var groups = new HashMap<Integer, TreeSet<Integer>>();
        for (int i=0; i<n; i++) {
             int p = parent[i];
            if (groups.containsKey(p)) {
                var set = groups.get(p);
                set.add(i);
                groups.put(p, set);
            } else {
                var set = new TreeSet();
                set.add(i);
                groups.put(p,set);
                    
            }
        }
        
        //handle string. For every groups, all chars can be swaped with each other.
        //then we find chars in the same group, sort them, and put them back
        var ans = new char[n];
        for (int key: groups.keySet()) {
            var set = groups.get(key);
            
            //get char array
            var arr = new char[set.size()];
            int c = 0;
            for (Integer h: set) {
                arr[c] = s.charAt((int)h);
                c++;
            }
            
            Arrays.sort(arr);
            
            //put back char into original string
            c=0;
            for (Integer h: set) {
                ans[(int)h] = arr[c];
                c++;
            }
   
        }
        
        //convert array back to string
        var sb = new StringBuilder("");
        for (char c: ans) sb.append(c);
        return sb.toString();
      
    }
    
    //this find function to find parenet of a index recursively
    private int find(int a) {
        if (parent[a] == a)
            return a;
        parent[a] = find(parent[a]);
        return parent[a];
    }
}

Dijkstra's Algorithm to solve the shortest path problem

//Leetcode 1631
class Solution {
    int[][] d;
    PriorityQueue<int[]> q;
    HashSet<Integer> set;
    int r;
    int c;
    int[][] myHeights;

    /**
     * use Dijkstra's Algorithm. Here v is (0,0) of matrix. Will calculate the shortest
     * distance from every point (u) to this v.
     */
    public int minimumEffortPath(int[][] heights) {
        //step one: initiate values. for 0, 0 distance is 0 for other, dist is max integer val
        var max = Integer.MAX_VALUE;
        r = heights.length;
        c = heights[0].length;
        myHeights = heights;

        d = new int[r][c];

        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++)
                d[i][j] = max;
        }

        d[0][0] = 0;

        //step two, put D[u] into a priority queue. q's key is int[3] ({value, i, j})
        //it uses the first value of array to do comparation. This value is the distance
        //between u and v
        q = new PriorityQueue<>(Comparator.comparingInt(a -> a[0]));

        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                int[] key = { d[i][j], i, j };
                q.add(key);
            }
        }

        //step three: set up a set to remember our current cloud. use a interger of postion
        //to represent a vertex in matrix. For example, for matrix[3*3], (0,0) has value
        //of 0, (3,3) has value of 8
        set = new HashSet<Integer>();

        //step four: loop until every vertex is in the set
        while (set.size() != r * c) {
            var point = q.poll();

            // put this vertex into our cloud
            set.add(point[1] * c + point[2]);

            // try to update value for the adjecent vertexs. Try to left, right, up and down
            var row = point[1];
            var col = point[2];

            update(point, row - 1, col);
            update(point, row + 1, col);
            update(point, row, col - 1);
            update(point, row, col + 1);
        }

        return d[r - 1][c - 1];
    }

    //used to update distance for adjecent points
    public void update(int[] point, int x, int y) {
        //if point is in our current cloud, do nothing. If point is in outside matrix, do nothing.
        if (set.contains(x * c + y)) return;
        if (x < 0 || x >= r) return;
        if (y < 0 || y >= c) return;

        // this is height of this point
        var h = myHeights[point[1]][point[2]];

        //calculate new distince for D if we want to go to v by current picked point
        var newVal = Math.max(point[0], Math.abs(h - myHeights[x][y]));

        var oldVal = d[x][y];

        //only need to update if we get shorter path
        if (newVal < oldVal) {
            d[x][y] = newVal;

            int[] key = { newVal, x, y };
            q.add(key);
        }
    }
}

Friday, 18 March 2022

Lowercase English Letter Question

There are lots of questions which need to count occurence of English letters in a string. For the first thought, you may think of using map. However, we can take advantage of how language treat char, and we may be able to use array instead.

Here is ASCII table

We see 'a' has value of 97 and 'A' has value of 65

Count occurences of letters in a string which consists of lowercase English letters.

//for Java
var counts = new int[26];
for(char c: s.toCharArray()) counts[c-97]++;

//lower letter string to [26]int
func convertToLetterArr(s string) [26]int {
    
    var letters[26] int
    
    for _, c := range []rune(s) {
        
        letters[c-97]++
    }
    
    return letters
    
}

Sunday, 6 March 2022

Smart Contract Lab One

Get balance of an account

Use this tool. Look like it works for only test network.

Go codes to convert hex to weis and eth

package main

import (
    "fmt"
    "strconv"
)

//convert hex weis to weis(deci) and eth
func main() {
	//weis in hex format
    hex := "ddf7d27685de8f1"
    //weis for one eth
    var weis float64 = 1000000000000000000
    value, err := strconv.ParseInt(hex, 16, 64)
    if err != nil {
        fmt.Printf("Conversion failed: %s\n", err)
    } else {
        //convert to float64 before do division
        var val = float64(value)
        var ans = val / weis
        fmt.Printf("%d wei\n", value)
        fmt.Printf("%f eth\n", ans)
    }
}

Show testnet in Metamask

By default, you can not see testnet in Metamask. To see testnet, need to enable it in Metamask setting.

Development tools

Hardhat

It is a development environment to compile, deploy, test and debug Ethereum software.

npm install --save-dev hardhat

Ethers.js

It wraps standardJSON-RPC methods with more user friendly method. This library makes it easier to interact and make requests to Ethereum.

npm install --save-dev @nomiclabs/hardhat-ethers ethers

Connect hardhat project with Metamask and Alchemy

Create a .env file

API_URL = "https://eth-ropsten.alchemyapi.io/v2/your_api_key"
PRIVATE_KEY = "your_metamask_private_key"

Verify contract on Etherscan

npx hardhat verify --network ropsten 0x4827E8a9858f73d061262fB3BAaa4FA8461F7904 'Hello World!'

See codes

See codes

Saturday, 26 February 2022

Unicode in Go

The type rune is a synonym int32. byte is a synonym uint8. We can create [] rune (or [] int32) for a unicode string. For a string which only has ASCII characters, we can create [] byte, [] uint8 or [] rune. To convert this array back to string, use string(array value). See the below example.

package main

import (
    "fmt"
)

func main() {
    var s, t string
    var r, k []rune
    s = "世界和平"

    //create an array of rune. Also can do r =[]int32(s)
    r = []rune(s)

    //change back to string
    t = string(r)

    fmt.Println(t)

    k = []rune{19990, 30028, 21644, 24179}

    fmt.Println(string(k))
}

convert string to array; Then convert back for string which has only ASCII characters

package main

import (
    "fmt"
)

func main() {
    var s, t string
    var r []uint8
    s = "hello world"

    r = []uint8(s)

    //change back to string
    t = string(r)

    fmt.Println(t)

}

Friday, 11 February 2022

TypeScript

Types

/** a is type of any */
let a

/** a is type of number */
let a :number;

/** if initalize when define, will figure out type. Here is number too*/
let a=1

/** possible types */
let a :number
let b :boolean
let c :string
let d :any

/** type aliases */
type Age = number
let age :Age = 55

type Person = {name:string, age:Age}
let driver:Person = {name:"leo", age:age}

/** below is array type */
let e : number[] = [1,2,3]

/** enum type. Red will assign to be 0 .... */
enum Color {Red, Green, Purple, Yellow}
/** use enum */
let myColor = Color.Green
/** will show 1 */
console.log(myColor)

/** tuple tyep. It is similiar to array. However, it can consist different types*/
let person:[string, number] = ['john', 30]
console.log(person.length)

person.push("male")
console.log(person)

/**the following will generate error because boolean is not allowed in person tuple.*/
person.push(true)

Literal types

literal type's value can ONLY be itself. It mostly is used by combining literals into unions

let x: "hello" = "hello";
let i:3=3

Interface as type

interface Point {
    x: number;
    y: number;
}

let p:Point = {x:1, y:2}
console.log(p)

//create array of points
const points: Point[] = [
    {x:1, y:2},
    {x:2, y:8}
]

Type Assertion

Set the type of value and ask compiler not to infer it

/** although code is defined as type any, we can set it to be number*/
let code: any = 123; 
let employeeCode = <number> code; 

/** another way. in jsx, should use this way */
let code: any = 123; 
let employeeCode = code as number;

Class

class Point {
    x: number;
    y: number;
    constructor(x:number, y:number) {
        this.x = x
        this.y = y
    }
    draw() {
        console.log(this.x)
        console.log(this.y)
    }
}

let p = new Point(1,6 )
p.draw()

We can reduce some lines of code for the above example. The below will behave the same as above. Actually, they will generate the same js code.

class Point {
    constructor(public x:number, public y:number) {
        
    }
    draw() {
        console.log(this.x)
        console.log(this.y)
    }
}

let p = new Point(1,6)
p.draw()

Also can make constructor parameter optional

 constructor(x:number, y?:number) {
        this.x = x
        this.y = y
    }

Accessors in class

class Point {
    constructor(private x:number, private y:number) {
        
    }

    get X() {
        return this.x
    }

    set X(val) {
        this.x = val
    }

    draw() {
        console.log(this.x)
        console.log(this.y)
    }
}

/** will output 1, 12, 6*/
let p = new Point(1,6)

/** access x by X */
console.log(p.X)

/** modify x by setter X */
p.X = 12
p.draw()

When complie, get error

tsc main.ts

 error TS1056: Accessors are only available when targeting ECMAScript 5 and higher
 
 //to solve the error:
 tsc -t es5 main.ts
 
 test.ts:2:21 - error TS2583: Cannot find name 'Map'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2015' or later.
//to solve
tsc -t es2015 test.ts

Use tsconfig.json

Create a tsconfig.json

tsc --init

To use it. Only type tsc. Will try to use setting in tsconfig.json and convert ts files into js files.

#watch mode
tsc --watch

Prevent from generating js file if there is error in ts file, set the below

"noEmitOnError": true

To prevent from compiling libraies files(node_modules), set

"skipLibCheck": true

Generics

This is simliar to what Java has done. The type can be dynamic in defining the function and can pass along the type variable. When call the function, specify the type.

function check<Type>(arg:Type):Type {
    return arg
}

let ans = check<string>("good")
console.log("ans:", ans)

let ans2 = check<number>(99)
console.log(ans2)

When we say an array of some type, we can do: Array<T>. Create a new Array of T: new Array<T>()

function cpArray<T>(items : T[] ) : T[] {
    return new Array<T>().concat(items);
}

let myNumArr = cpArray<string>(["a", "b"]);

HashMap

HashMap Methods

//Leetcode 2206
function divideArray(nums: number[]): boolean {
    let myMap = new Map<number, number>();
    
    for (let n of nums) {
        if (myMap.has(n)) {
            myMap.set(n, 1+myMap.get(n))
        } else {
            myMap.set(n, 1)
        }
    }
    
    for (let k of myMap.keys()) {
        if (myMap.get(k)%2 !=0) {
            return false
        }
    }
    return true

};

Install TypeScript locally

npm init -y
install typescript --save-dev

To use it:

npx tsc [cmd]
npx tsc -v

Use stage 2 decorator

  • tsc version > 5
  • disable experimental decorator config flag!( if enabled, will go back to stag 1 syntax)

Check optional parameter

//output: person age is undefined
interface Person {
  name: string;
  age?: number;
}

let p: Person = {
  name: "leo",
};

if (p.age === undefined) {
  console.log("person age is undefinde");
} else {
  console.log("person age is defined");
}

Solve exports Error

After compile ts file and try to run it in browser, got the following error.

app.js:2 Uncaught ReferenceError: exports is not defined

Here is original ts files

// myModule.ts
export class MyClass {
    public greet() {
        return "Hello from MyClass!";
    }
}

export function myFunction() {
    return "Hello from myFunction!";
}

//app.ts
import { MyClass, myFunction } from './myModule';

const instance = new MyClass();
console.log(instance.greet()); // Output: "Hello from MyClass!"
console.log(myFunction()); // Output: "Hello from myFunction!"

The following is app.js got

//app.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const myModule_1 = require("./myModule");
const instance = new myModule_1.MyClass();
console.log(instance.greet()); // Output: "Hello from MyClass!"
console.log((0, myModule_1.myFunction)()); // Output: "Hello from myFunction!"
To solve the problem
  • change index.html
    -  <script src="dist/app.js" defer></script>
    +  <script type="module" src="dist/app.js" ></script>
  • change app.ts
    -import { MyClass, myFunction } from './myModule';
    +import { MyClass, myFunction } from './myModule.js';
  • change tsconfig.json (in "compilerOptions" section)
    -    "module": "commonjs",                                
    +    "module": "es2015",  

app.js got after applying the above changes

//app.js
import { MyClass, myFunction } from './myModule.js';
const instance = new MyClass();
console.log(instance.greet()); // Output: "Hello from MyClass!"
console.log(myFunction()); // Output: "Hello from myFunction!"

vscode

Format file in mac

In the botton right, make sure the format show as JavaScript React. In mac, select text; then Shift + Option + F will format the selected text. In ubuntu, Crt + Shift + I

auto save

In file option, click auto save to toggle it. When auto save has a check mark, auto save is on

Terminal

click Terminal tab and select new Terminal to open a terminal. Click delete to get rid of terminal

Search in the file

For ubuntu Crtl + F In mac Command + F

How to find out "Problems in this file" errors in VS Code?

For mac cmd + shift + M

Search file in work space

For mac cmd + p Then type file name

Delete a line

For linux, crtl + shift + k

Coment out multi lines

For linux, choose multi line and crtl + /

For vim

# go to the end of a file
shift + g 

# go to the beginning of a file
g + g

vscode does not recognize Django

1. in vscode terminal to find python version used to install Django

pip show Django

2. in right botton corner of vscode, click python version. Choose the same version which is used to inst all Django

Copy / Paste short cut ubuntu

copy: crtl + c
paste: crtl + shift + v

Select entire file

In mac, do it by: command + a

Ask copilot

ctrl + i (ubuntu)

Tuesday, 25 January 2022

GitHub

Error:Key already in use

When I try to add a ssh public key to my GitHub account, I got that error. To figure out which account has that key

ssh -T -ai ~/.ssh/id_rsa git@github.com

Output: Hi liysysy! You've successfully authenticated, but GitHub does not provide shell access.

to solve it, remove from other account and add to this account

Ask user name when push codes

If you have upload a ssh public key and it still asks for user name when push codes, it is mostly that you are using https://.. as origin. You need to use ssh origin such as git@github.com:rllslslls

To change origin

git remote set-url origin git@github.com:rdgdfghh.git

Create a PR

git push -u origin feature/KLMP-4071

Wednesday, 19 January 2022

Use Google API

To use Google API, need several steps

  1. Create a developer token
  2. Create a project
  3. Get client id and client secret for the project
  4. Get a refresh token from user by asking them to grant permission to the project (see the below)

Ask user to grant permission to get refresh token

  1. Create a return url which will process code after user grant the permission
  2. Add the above url to authorized redirect URIs field of the project
  3. Use client library to generate an onboard url and redirect user to this url
  4. After user redirect to that url, user will be asked to grant permission

With developer token, project's client id and secret, and user's refresh token, we can implement the project using Google's client library to implement the project.

Use ngrok as tunnels to localhost

set up

  1. register an account at ngrok
  2. download ngrok and unzip
  3. find authtoken
  4. ./ngrok authtoken 23siywfFYojsSVe8ojvO0yTEgf4_7dsx9NCr9cZHoc7gb3abc

./ngrok authoken .. only needs to run once. It will create a ~/.ngrok2/ngrok.yml

usage

If have used /etc/host define different domains, use -host-header flag

./ngrok http  --host-header local.mowedhdhmedia.com 80

If only have to point to localhost

./ngrok http 80

copy the url generated by ngrok. This url can be accessed from anywhere to connect to your local host.

Friday, 7 January 2022

Blockchain

Satoshi Nakamoto's Paper

How to Store Bitcoin

Good Tutorials

Good tutoria about smart contract

Block

Every block has the previous block's hash. It has it's own hash which is generated by hashing previous hash and own data.


{data: "some data", previous_block_hash: "hash value", own_hash: "own hash value"}

hashfunction( data, previous_block_hash) => this block's hash

Chain Blocks

For the first block, we give it some randon string as the previous block hash because it does not have previous block. For every other block, it has the previous block's hash. Use hash to link blocks and these blocks become a blockchain.

Verify Block Chain

traverse through the chain, for every block, verify it's hash by using the hash function. Also, except the first block, check the previous hash property does match the hash of the previous block.

keccak256 value

use ruby. Need to install a gem first

gem install keccak256
require "keccak256"
code = Digest::Keccak256.new.hexdigest 'hello1'
puts code

Private and public key

require 'openssl'

key = OpenSSL::PKey::RSA.generate(2000)
key.public_key

puts key.public_key
puts key

Smart contract hello world

Hello World Totorial

//I made an adjustment in order to compile the contract successfully
//change to this solidity version in HelloWorld.sol
pragma solidity ^0.8.0;
//because in hardhat.config.js
solidity: "0.8.4",

Voila! successfully deploy the smart contract to a test net!

npx hardhat run scripts/deploy.js --network ropsten
//voila
Contract deployed to address: 0x4827E8a9858f73d061262fB3BAaa4FA8461F7904

See Contract Details

Screenshot of the transaction

Labs

Lab One

AWS CloudWatch Logs Insights etc

AWS CloudWatch Logs Insights

Logs Insights Syntax

Sample

#need to select a log group first. Like is case sensitive. Two filter is and logic
fields @timestamp, @message
|filter @message like "pay"
|filter @message like "POST"
|sort @timestamp desc
|limit 20

To add time range, use UT and pick absolute and then write down range. Need to pick UTC

AWS S3

Can store some public files in S3 and copy back to a Docker image
  1. Upload the file into AWS S3
  2. Edit permission to make it public
  3. Copy the url for this object
  4. Use curl to copy file in Dockerfile
    RUN curl "https://my-assets.s3.us-west-2.amazonaws.com/good-assets/grpc.so" --output /usr/lib/php8/modules/grpc.so

Amazon Elastic Container Service (ECS)

ECS runs and manages docker-enabled applications in amazon EC2 instances.

Amazon EC2 container registry stores docker images.

To use ECS

  1. Create EC2 Cluster. These instances are linked in a virtual private cloud(VPC)
  2. Create task defintion to define a container. It is a configuration for running a docker image
  3. Deploy containers using task definition to run on the cluster
  4. Use Serive to manage tasks. Serice includes task defintion, desired count and task placement strategy
  5. Update Service with new task defintions to replace old tasks

Some my aws blog links

Dynamodb

Intrinsic functions

Amazon EC2

Thursday, 6 January 2022

Make Google API Call

To make a Google API call, need to set up the below

  1. need a developer token
  2. client need to create app. For example, if use Google ads api, Google ads account customer needs to create app
  3. get client id and client secret of that app
  4. that app needs to grant permission to use Google specific api. After grant, should get a refresh access token
  5. with developer token, client id, client secret and refresh access code, we can make a Google API call (see the below)

How app to grant permission to use Google api. Use Google ads api as example

Option 1: Use Google oauth play ground

  1. add https://developers.google.com/oauthplayground under Authorized redirect URIs of that App
  2. go to https://developers.google.com/oauthplayground/
  3. click setting and click use your own OAuth credentials. Provide app client id and client secret
  4. select a Google api and click grant permission
  5. Then can convert verification code to access code and refresh access code

Option 2: build a webpag (for web app) to ask user to grant permission

Tuesday, 28 December 2021

Django framework

route request

When routes a request, it is doing a url mapping. It uses path function. This function accepts three parameters. The first is url, the second is the function to call in the view module. The third one is the name for this path. It will be used when we want to add a link in other pages. We use the name to refer to the page.

from django.urls import path
from . import views

app_name = 'learning_logs'

urlpatterns = [
    # home page
    path('', views.index, name='index'),
    path('topics/', views.topics, name='topics')
]

Access django sqlite3 db

If get this error message: CommandError: You appear not to have the 'sqlite3' program installed or on your path, install sqlite3 in machine first

sudo apt-get install sqlite3
# need to do it in virtual env (source ..bin/activate)
python manage.py dbshell
# also can do this
sqlite3 filename

# list tables
.tables

# see all table schema
.schema

# show table content. use normal sql select

Start server

# 9000 is port number. If port number is not provided, will use 8000 as default port
python manage.py runserver 9000

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

Sunday, 5 December 2021

Java cheating sheet

Syntax and tricks

Array

//initial
var arr = new int[10];

int[] myIntArray = {1, 2, 3};

int[][] move = { { r - 1, c }, { r + 1, c }, { r, c - 1 } };

//add another array list into list.
List<List<String>> ans = new ArrayList<>();

//use List.of to build a list
List<String> arr = List.of("a", "b");
System.out.println(arr.size());
System.out.println(arr.get(0));

//length
var l = arr.length;

//sort
Arrays.sort(arr);

String and Char

//String length. call function
s.length();

//check if char is lower case or upper case
Character.isUpperCase(c)
Character.isLowerCase(c)

//loop through string by chars
for (int i=0; i<s.length(); i++) {
     var c = s.charAt(i);
}

//char to string
Character.toString(c);

//string to int
Integer.parseInt("09")

//int to string
var s = Integer.toString(98);

number char '9' to int

int v = '9' - '0';

map

//To get default value. assume key is int 6 and default value is 0
var val = map.getOrDefault(6, 0);

//can use ArrayList as map key
var map1 = new HashMap<List<Integer>, String>();

//can use array as map value
var map = new HashMap<Integer, int[]>();

//see if hash has key
if (map.containsKey(n)) continue;

//loop through
for (int k: map.keySet()) System.out.println(map.get(k));

//create a reverse order tree map
var map = new TreeMap<Integer, Integer>(Collections.reverseOrder());
 
 //empty map
 map.clear();

set

//add element
set.add(n);

//set size;
return set.size();

//contains key
set.contains(key)

//find intersection of two set
var set1 = new HashSet<Integer>();
var set2 = new HashSet<Integer>();
//copy elements.  So, elements in set1 and set2 will not change
var intersection = new HashSet<Integer>(set1);
intersection.retainAll(set2);

Stack

//pop or push
stack.pop()
stack.peek()
stack.push(c)

//stack can hold array
var stack = new Stack<int[]>();
int[] point = {1,2};
stack.push(point);

StringBuilder

var builder = new StringBuilder();
 for (char c: stack) builder.append(c);
        
return builder.toString();

Noted in code snippets below, some <type> is missing because of shortcoming of code highlight

var keyword in Java

The var keyword was introduced in Java 10. It does not make Java dynamically typed. Compiler will figure out type using information from the variable's initializer.

  • var is used to declaring local variables and an initializer is required on the right-hand side
  • var can not be used as fields, method parameters and method return type
  • can not initiate with null

The below is a code snippet to use var. This is a solution for Leet code 2094


class Solution {
    public int[] findEvenNumbers(int[] digits) {
        var d =new int[10];
        for (var i: digits) d[i]=d[i]+1;
        
        var number= 100;
        
        
        var ans = new ArrayList<Integer>();
        
        while (number<999) {
            // find three digit to build this number
            var d1 = number/100;
            var d2 = (number-d1*100)/10;
            var d3 = number-d1*100-d2*10;
            
            //check if we get enough digits
            var check = Arrays.copyOf(d, 10);
         
            check[d1] = check[d1]-1;
            check[d2] = check[d2]-1;
            check[d3] = check[d3]-1;
           
            if (check[d1]>=0 && check[d2]>=0 && check[d3]>=0) ans.add(number);
               
            number=number+2;
        }
        
        var result = new int[ans.size()];
        for (var i=0; i<ans.size(); i++) result[i]=ans.get(i);
        
        return result;
        
    }
}

Can not find symbol var problem

Test.java:15: error: cannot find symbol var 
java -version
openjdk version "11.0.11" 2021-04-20

javap -verbose Test | grep "major"
 major version: 52
 //okay, not good. 52 =>JVM 8
 
 //install jdk-11 (before used sudo apt-get install default-java)
 sudo apt-get install openjdk-11-jdk

 //check. It is good now
 javap -verbose Test | grep "major"
  major version: 55

Lambda expression


import java.util.*;

class test3 {
	public static void main(String[] args) {
		List<String> names = Arrays.asList("leo", "winkey", "scott", "jeniffer");
		Collections.sort(names, (String a, String b) -> {
				return a.compareTo(b);
			}

		);

	}
}

The below is lambda expression

Lambda was introduced in Java 8

(String a, String b) -> {
	return a.compareTo(b);
}

For one line expression, can skip both return and curly brace

(String a, String b) ->  a.compareTo(b)

Java will figure out type here. Therefore the expression can be

(a,b)->a.compareTo(b)
//sort list of list
pairs.sort((l1, l2) -> l1.get(0).compareTo(l2.get(0)));

//sort arrayList
Collections.sort(list);

//sort array
Arrays.sort(need);

//use Lamda to sort array. Result is "yy", "ddd", "oldyy"
//if want to sort int array by lambda, array needs to be: var arr = new Integer(10)
 String[] hb = {"ddd", "yy", "oldyy"};
 Arrays.sort(hb, (a,b) ->a.length()-b.length());
 
 //sort that two dimension array
 Arrays.sort(nums, (a, b) -> b[1]-a[1]);
 
 //sort by two cols
 Arrays.sort(
      res,
      Comparator.<int[]>comparingInt(arr -> arr[0]).thenComparing(arr -> arr[1])
    );
 
 

Stream

local variable in the lambda function need to be final or effectively final. For object, if we do not change reference, it is effectively final. Then we can use StringBuilder object defined outside in the example below.


List<String> myList =
    Arrays.asList("ab", "cd", "cf", "ed");

myList
    .stream()
    .filter(s -> s.startsWith("c"))
    .map(String::toUpperCase)
    .sorted()
    .forEach(System.out::println);
    
//another example. chars return a int stream for string
StringBuilder sb = new StringBuilder("");
        
s.chars().forEach(i->sb.append(Character.toLowerCase((char)i)));

HashMap

//key reversed (big to small) treemap
var map = new TreeMap<Integer, Integer>(Collections.reverseOrder());

//leetcode 2190
class Solution {
    public int mostFrequent(int[] nums, int key) {
        var hashmap = new HashMap<Integer, Integer>();
        
        for (int i=1; i<nums.length; i++) {
            if (nums[i-1]==key) {
                hashmap.put(nums[i], 1 + hashmap.getOrDefault(nums[i], 0));
            }
        }
        
        int maxC = 0;
        int ans = 0;
        
        
        for(Integer k : hashmap.keySet()) {
            if (hashmap.get(k)>maxC) {
                maxC = hashmap.get(k);
                ans = k;
            }
        }
        return ans;
    }
}

//create ArrayList of arr
var list = new ArrayList<String[]>();

cast between char, string and integer

//int to string
var s = String.valueOf(x);

//solution for leetcode 2194
class Solution {
    public List<String> cellsInRange(String s) {
        
        var row = new int[2];
        
        //cast string "2" to integer
        row[0]  = Integer.parseInt(s.substring(1,2));
        
        row[1]  = Integer.parseInt(s.substring(4,5));
        
        //cast char 'A' to integer
        var col = new int[2];
        col[0] = (int)s.charAt(0);
        col[1] = (int)s.charAt(3);
       
        var ans = new ArrayList<String>();
        
        for (int c= col[0]; c<=col[1]; c++) {
            
            for (int r=row[0]; r<=row[1]; r++) {
            	//int to char; char to string
                var cell = Character.toString((char)c) + r;
                ans.add(cell);
            }
        }
        
        return ans;
   
    }
}

bit operation

bitwise and. & AND Sets each bit to 1 if both bits are 1


int a = 4&3;
System.out.println(a); //0 because 100 &011

Bit shift


    // 2 bit left shift operation
    int number = 2;
    int result = number << 2;
    System.out.println(result); // prints 8

    // 1 bit left shift operation
    int number2 = 2;
    int result2 = number2 << 1;
    System.out.println(result2); // prints 4

The fastest way to check if a number is a prime


private int isPrime(int n) {
    if (n <= 1) return 0;
    if (n == 2 || n == 3) return 1;
    if (n % 2 == 0 || n % 3 == 0) return 0;
    for (int i = 5; i * i <= n; i = i + 6) {
      if (n % i == 0 || n % (i + 2) == 0) return 0;
    }
    return 1;
  }

Find all primes less than n


  //find all primes LESS THAN n
  //if want to primes less or equals, set argument to 
  //be n+1 when call this function.
  public ArrayList<Integer> countPrimes(int n) {
    ArrayList<Integer> arr = new ArrayList<>();
    boolean[] notPrime = new boolean[n];

    for (int i = 2; i < n; i++) {
      if (notPrime[i] == false) {
        arr.add(i);

        for (int j = 2; i * j < n; j++) {
          notPrime[i * j] = true;
        }
      }
    }

    return arr;
  }

TreeSet floor and ceiling

It will find a value for the set. floor: greast value less or equals the given value. ceiling: smalles value greater or equals to the given value.

//solution for Leetcode 2817
class Solution {
    public int minAbsoluteDifference(List<Integer> nums, int x) {
        int ans = Integer.MAX_VALUE;
        TreeSet<Integer> set = new TreeSet<>();

        for (int i=x; i<nums.size(); i++) {
            set.add(nums.get(i-x));
            
            Integer val = set.floor(nums.get(i));
            if (val!=null) ans = Math.min(ans, Math.abs(val - nums.get(i)));

            val = set.ceiling(nums.get(i));
            if (val!=null) ans = Math.min(ans, Math.abs(val - nums.get(i)));
        }

        return ans;
        
    }
}

Run codes

//javac Solution.java | java Solution
class Solution {

  public boolean canMakeSquare(char[][] grid) {
    if (isGood(grid, 0, 0)) return true;
    if (isGood(grid, 1, 0)) return true;
    if (isGood(grid, 0, 1)) return true;
    if (isGood(grid, 1, 1)) return true;

    return false;
  }

  private boolean isGood(char[][] grid, int row, int col) {
    int b = 0;
    int w = 0;

    for (int i = row; i <= row + 1; i++) {
      for (int j = col; j <= col + 1; j++) {
        if (grid[i][j] == 'B') {
          b++;
        } else {
          w++;
        }
      }
    }

    return b >= 3 || w >= 3;
  }

  public static void main(String[] args) {
    Solution obj = new Solution();
    char[][] test = { { 'B', 'W', 'B' }, { 'B', 'W', 'W' }, { 'B', 'W', 'B' } };

    var ans = obj.canMakeSquare(test);
    System.out.println(ans);
  }
}

Java Queue

Java Queue