7/26/2017

Install Chewing on Ubuntu 16.04

Install ibus-chewing

sudo apt-get purge hime hime-chewing
sudo apt-get install ibus-chewing 
im-config -n ibus 
ibus-setup 
ibus restart


Add Input Method

Go to  System settings -> Text Entry, add 'Chinese(Chewing)'



7/20/2017

[Deep Learning] Batch Normalization note

Batch Normalization (BN)
• Normalizing input (LeCun et al 1998 “Efficient Backprop”)
• BN: normalizing each layer, for each mini-batch
• Greatly accelerate training
• Less sensitive to initialization
• Improve regularization

S. Ioffe & C. Szegedy. Batch normalization: Accelerating deep network training by reducing internal covariate shift. ICML 2015

'Deep Residual Learning for image recognition', presents that do batch normalization before active function will be better.


7/19/2017

Vagrant command lines

Install Vagrant from official website

  If you use apt or yum to download Vagrant, the version might be too old to be compatible to your virtualbox or vmware. Therefore, please download it from the official website .


Download VirtualBox from website

  Please download the suitable version of VirtualBox.


Common and useful commands:

Download and init vagrant box
$ vagrant init <Vargant box>
E.g : Download vagrant box which has Kubernetes.
vagrant init flixtech/kubernetes

Note: The box file will be stored in ~/.vagrant.d/boxes/
Creates and configures guest machines according to your Vagrantfile.
$ vargant up

Bring the machine up with the given provider. By default, this is "virtualbox".
$ vargant up --provider x

E.g : Change the provider to vmware
$ vagrant up --provider vmware

Check the current machine states
$ vagrant status

List all of base boxes for Vagrant
$ vagrant box list

Shut the current machine
$ vagrant halt

Stops the running machine and destroys all resources that were created 
$ vagrant destroy

SSH into a running Vagrant machine
$ vagrant ssh

JFrog setup gradle artifacts

Run JFrog

Create a directory which stores JFrog's persistent data, then run JFrog using Docker. We change the PORT to 8085 instead of using 8081 because 8081 port was occupied by my Jenkins server.
$ mkdir -p jfrog_data 
$ docker run --name jfrogartifactory -d -v jfrog_data:/var/opt/jfrog/artifactory -p 8085:8081 docker.bintray.io/jfrog/artifactory-oss
I created a makefile for running and stopping the container and backup data.
init:
 mkdir -p jfrog_data
run:
 docker run --name jfrogartifactory -d -v `pwd`/jfrog_data:/var/opt/jfrog/artifactory -p 8085:8081 docker.bintray.io/jfrog/artifactory-oss
stop:
 docker stop jfrogartifactory;docker rm jfrogartifactory
clean:
 rm -rf jfrog_data
 docker rmi -f docker.bintray.io/jfrog/artifactory-oss
backup:
 zip -r jfrog_data.zip jfrog_data
After running JFrog, you can check it by entering http://localhost:8085/

Create gradle and generic repositories


Create a group, permission, account




Log out of admin account

Publishing your library using Gradle

Step 1: Add org.jfrog.buildinfo:build-info-extractor-gradle:4.0.1 dependency to the project gradle
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.2'
        classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.0.1"
    }
}
Also, add the variables to gradle.properities to let module use
artifactory_user=XXXX
artifactory_password=YYYY
artifactory_contextUrl=http://10.70.70.40:8085/artifactory

Step 2: Append the below snippet code to then end of your module's gradle file 

apply plugin: 'com.jfrog.artifactory'
apply plugin: 'maven-publish' def libraryGroupId = 'AA.BB.CC' def libraryArtifactId = 'Test' def libraryVersion = '1.0.0' publishing { publications { aar(MavenPublication) { groupId libraryGroupId version libraryVersion artifactId libraryArtifactId artifact("$buildDir/outputs/aar/${artifactId}-release.aar") } } } artifactory { contextUrl = "${artifactory_contextUrl}" publish { repository { repoKey = 'gradle-release-local' username = "${artifactory_user}" password = "${artifactory_password}" } defaults { publications('aar') publishArtifacts = true properties = ['qa.level': 'basic', 'q.os': 'android', 'dev.team': 'core'] publishPom = true } } }

Go to command line to publish your module to your private JFrog artifactory
$ ./gradlew assembleRelease artifactoryPublish
Then, your artifacts will be located at http://localhost:8085/artifactory/webapp/builds/

Import the library in other projects

Step 1: Add repository dependency

    repositories {
        jcenter()
        maven {
            url "http:/[IP]:8085/artifactory/gradle-release-local"
        }
    }
Step 2: Import the library in your module and compile it
compile "com.pakcage:module:version"
It's done!


Upload other artifact using JFrog

Jfrog with free version supports that you can create a generic version and upload anything

Then, you can use curl command to push your artifact to that. Ex:
curl -u<USERNAME>:<PASSWORD> -T <PATH_TO_FILE> "http://10.70.70.44:8085/artifactory/<REPO KEY>/<TARGET_FILE_PATH>


My makefile file : https://github.com/tzutalin/docker/tree/master/JFrog

7/03/2017

Run OpenGrok using docker

  Thanks to Docker. It makes us to use a lot of web service easier.  In the past, we would like to install OpenGrok, we have to install java, tomcat, etc..
  Now, it is easy to run OpenGrok if you know Docker. The steps are quietly simple, please checkout the below steps:

Step1 : Install Docker
$ apt-get update -qq
$ apt-get install -qqy \
  apt-transport-https \
  ca-certificates \
  curl \
  lxc \
  iptables

$ curl -sSL https://get.docker.com/ | sh
$ usermod -a -G docker  $USER

Step2: Pull the image from my Dockerhub .
$  docker pull tzutalin/opengrok
Alternatively, you can check out my Dockerfile on Github, and build the image from scratch.


Step3: Run the OpenGrok using the below commands. Rember to replace <XXXX> with your source directory.

$ docker run -t -d --name=opengrok -v [Absolute path]:/src -p 8080:8080 tzutalin/opengrok
tzutalin/opengrok container will periodically update the index. So you didn't need to update index by yourself.

Open your browser http://0.0.0.0:8080/source/. The result looks like :


Reference: https://github.com/tzutalin/docker/tree/master/OpenGrok

6/23/2017

手機當行車紀錄器

  前陣子換手機, 又多了一隻Android舊手機, 剛好最近也買了一個車用手機架, 就把我舊手機當行車紀錄器. 但我在google play 上, 都沒有用到喜歡的行車紀錄器app, 因此自己寫花了幾個周末寫了一個可以在背景錄影、記錄移動軌跡、並打開就馬上錄的的行車紀錄器app. 希望能幫助到一些人.
App可以到https://play.google.com/store/apps/details?id=com.dayun.driverecorder&hl=zh_TW 下載
截圖如下:


車用手機架則可以上PCHome買
https://24h.pchome.com.tw/store/DEADCG

6/19/2017

Running Qt GUI apps with Docker

  In the past three weeks, I was playing around Docker and CI/CD pipeline, and I was getting familiar with Docker and its toolbox. In the meanwhile, I tried to dockerize most of my own applications, tools, and algorithms which can run, build, or test inside Docker container.
  Here is one of my projects on Github, it's called labelImg which was written in Python + PyQt. You can follow the below videos or the snippet of the commands to run Python + PyQt GUI application inside the Docker container.

Step1: Clone the source code from Github
$ git clone https://github.com/tzutalin/labelImg.git

Step2: Pull the Docker image which is based on Python + PyQt. You can refer to its Dockerfile.
$ docker pull tzutalin/py2qt4
Step3: Get started with the application and container
docker run -it \
--user $(id -u) \
-e DISPLAY=unix$DISPLAY \
--workdir=$(pwd) \
--volume="/home/$USER:/home/$USER" \
--volume="/etc/group:/etc/group:ro" \
--volume="/etc/passwd:/etc/passwd:ro" \
--volume="/etc/shadow:/etc/shadow:ro" \
--volume="/etc/sudoers.d:/etc/sudoers.d:ro" \
-v /tmp/.X11-unix:/tmp/.X11-unix \
tzutalin/py2qt4
Then, you will see that we can run GUI inside the container.

If you want to get more detailed information, you can check out the following video.

6/05/2017

Create insecure and private docker resistry

Pre-requirements on the host and clients:

Installed Docker and Docker-compose

Host

Create a folder for Docker registry
$ mkdir docker-registry;cd $_;mkdir data
Create a  docker-compose.yml for docker-compose.
registry:
  restart: always
  image: registry:2
  ports:
    - 5000:5000
  environment:
    REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
  volumes:
    - ./data:/data
Get any image from the hub and tag it to point to your registry:
$ docker pull ubuntu && docker tag ubuntu localhost:5000/ubuntu
Then, push it to your registry:
$ docker push localhost:5000/ubuntu

Clients

Because the above setting is an insecure and private registry. You need to add --insecure-registry to /etc/default/docker as below.
DOCKER_OPTS="$DOCKER_OPTS --insecure-registry=HOST:5000"
Afterward, you can pull the image from host server by running the below command
$ docker pull HOST:5000/ubuntu

5/12/2017

Setup Jenkins on Ubuntu


Installation
wget -q -O - https://pkg.jenkins.io/debian/jenkins-ci.org.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
sudo apt-get install jenkins

Upgrade

Once installed like this, you can update to the later version of Jenkins (when it comes out) by running the following commands:
sudo apt-get update
sudo apt-get install jenkins

Setting
Add user jenkins to your username group to allow it to read and write the your folder
sudo usermod -a -G YOUR_USERNAME jenkins
If you would like to change the port, you can edit the /etc/default/jenkins to replace the line
HTTP_PORT=8080
by
HTTP_PORT=8880
sudo service jenkins restart 
Then, try to open 0.0.0.0:8880, you will see authentication page. Now, you need to enter the password, you should get /var/libs/jenkins/secrets/ to see the password.


After that, you can go to a configuration page to set up your env variable.
http://localhost:8880/configure

For example, if you are using Android and gradle to build, you should setup ANDROID_HOME, ANDROID_NDK_HOME,  and JAVA_HOME as env variable.
  ANDROID_HOME : /home/darrenl/tools/android-sdk-linux
ANDROID_NDK_HOME
JAVA_HOME = /usr/lib/jvm/java-1.8.0-openjdk-amd64

Extra nice plugins

* Locale Plugin
* Email Extension Plugin
* Role Strategy Plugin

Run Jenkins with Do

Please refer to
https://github.com/tzutalin/docker/tree/master/Jenkins
https://github.com/jenkinsci/docker/blob/master/Dockerfile
https://github.com/maxfields2000/dockerjenkins_tutorial/tree/master/tutorial_07


Other references
Jenkins: Change Workspaces and Build Directory Locations
How to change build periodic
Jenkis pipeline with docker
Use email-plugin
Use email-plugin2
Create a test smtp server 
Simple project which use travis

5/02/2017

flock c/c++ Sample Code


flock() is to apply or remove an advisory lock on an open file. It is available on most of OS, and I have tried it and it can work on Linux and Android OS. It can resolve the problem which muti-processes access the same file.

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/file.h>
#include <iostream>

void lockUnLock() {
  int fd, i;
  char path[] = "test.txt";
  fd = open(path, O_WRONLY | O_CREAT);
  if (fd != -1) {
    std::cout << "open file " << path << std::endl;
    std::cout << "Please input a number to lock the file" << path << std::endl;
    scanf("%d", &i);
    if (flock(fd, 2) == 0) {
      std::cout << "The file was locked " << std::endl;
    } else {
      std::cout << "The file was not locked " << std::endl;
    }
    std::cout << "please input a number to unlock the file " << std::endl;
    scanf("%d", &i);
    if (flock(fd, 8) == 0) {
      std::cout << "The file was unlocked. " << std::endl;
    } else {
      std::cout << "The file was no unlocked. " << std::endl;
    }
    close(fd);
  } else {
    std::cout << "Cannot open file " << path << std::endl;
  }
}

int main() {
  lockUnLock();
  return 0;
}

Src code: : https://gist.github.com/tzutalin/ad4277e8ee24392b9ea23765452d6528
Note: You can also use semget/semop to do that, but Android Bionic does not support that..

3/27/2017

JNI Should I call DeleteLocalRef

In JNI, FindClass method returns a local reference.
Sample code:
 jclass arrayListClass = env->FindClass("java/util/ArrayList");
 ....
 env->DeleteLocalRef(arrayListClass);
Is it necessary to call DeleteLocalRef ? In fact, it is unnecessary to call DeleteLocalRef in most of the cases. However, JNI has a limited (but configurable) number of local references available. So, the best practice is to delete if the reference is created in a loop

3/21/2017

C++ Version header template

Make a note for the usage of my version.hpp.
I can not only get the string of version from LIB_VERSION but also get major/minor/patch versions separately.
#pragma once
//  A *string*, LIB_VERSION, in the form "x.y.[z]"
//  where x is the major version number,
//  y is the minor version number,
//  and z is the patch level

#define LIB_VERSION_MAJOR    0
#define LIB_VERSION_MINOR    4
#define LIB_VERSION_PATCH    12

#define AUX_STR_EXP(__A)     #__A
#define AUX_STR(__A)         AUX_STR_EXP(__A)

#define LIB_VERSION          AUX_STR(LIB_VERSION_MAJOR) "."
        \ AUX_STR(LIB_VERSION_MINOR) "." 
        \ AUX_STR(LIB_VERSION_PATCH)
  

Besides, I wrote a python script to update the patch.
REG_VERSION_LINE = r"ASUS_VISION_LIB_VERSION_PATCH.  +([0-9:]+)"

def changeSoVersion(versionFile):
    # Read in the file
    filedata = None
    with open(versionFile, 'r') as file:
        filedata = file.read()
        matches = re.finditer(REG_VERSION_LINE, filedata)
        for matchNum, match in enumerate(matches):
            oldVersion = match.group(1)
            newVersion = str(int(match.group(1)) + 1)
            print oldVersion
            print newVersion
            if len(oldVersion) > 0 and len(newVersion) > 0:
                filedata = filedata.replace(oldVersion, newVersion)

    # Write the file out again
    with open(versionFile, 'w') as file:
        file.write(filedata)
  

3/03/2017

什麼是 closed-form solution and numerical solution

最近正在學解決multivariate analysis和optimalization問題, 遇到一個英文名詞close-form solution. close-form solution中文文獻稱閉合解. 白來來說就是給予一些觀察到的資料, 然後問題可以用函數和數學運算來表示, 這樣的方程式就是close-form solution or numerical solution, 差別在於一個是exact, 一個是approximate. 舉例來說, 在Linear regression中的 Least square equation就是close-form solution, Non-linear regression是numerical solution.

2/05/2017

[Interview type questions] Task sequence arragnement

Given a task sequence and the cool down time(k), rearrange the task sequence such that the execution time is minimal.
Solution:
 public static void main(String[] args) {
  char[] task = findBestTaskArrangement(String.valueOf("AAABBB").toCharArray(), 2);
  System.out.println(task);
  System.out.println("Total time: " + computeTatalTaskTime(task, 2));
  // ABABAB
  // Total time:8
 }
 
 public static char[] findBestTaskArrangement(char[] tasks, int k) {
  int n = tasks.length;
  Map<Character, Integer> map = new HashMap<>();
  for (char task : tasks) {
   map.put(task, map.getOrDefault(task, 0) + 1);
  }

  PriorityQueue<Task> queue = new PriorityQueue<>(new Comparator<Task>() {

   @Override
   public int compare(Task a, Task b) {
    return b.frequency - a.frequency;
   }
  });

  for (Map.Entry<Character, Integer> entry : map.entrySet()) {
   queue.offer(new Task(entry.getKey(), entry.getValue()));
  }
  
  tasks = new char[n];
  int i = 0;
  while (!queue.isEmpty()) {
   int c = 0;
   List<Task> nextRoundTask = new ArrayList<>();
   while(c++ < k && !queue.isEmpty()) {
    Task task = queue.poll();
    task.frequency--;
    // Locate the next empty slot
    tasks[i++] = task.id;
    if (task.frequency > 0)
     nextRoundTask.add(task);
   }
   for (Task task : nextRoundTask) {
    queue.offer(task);
   }
  }

  return tasks;
 }

 // helper class
 public static class Task {
  char id;
  int frequency;

  Task(char i, int f) {
   id = i;
   frequency = f;
  }
 }

 public static int computeTatalTaskTime(char[] tasks, int k) {
  HashMap<Character, Integer> taskLastTimeMap = new HashMap<>();
  int currTime = 0;
  for (char task : tasks) {
   if (taskLastTimeMap.containsKey(task)) {
    int exceptedTime = taskLastTimeMap.get(task) + k + 1;
    if (exceptedTime > currTime) {
     currTime = exceptedTime;
    } else
     currTime++;
   } else {
    currTime++;
   }
   taskLastTimeMap.put(task, currTime);
  }
  return currTime;
 }

[Interview type questions] MinQueue

Leetcode had a question about min stack, but there is no question about min queue. In this article, I wrote a simple one for min queue.

Solution:
 public static void main(String[] args) {
  MinQueue queue = new MinQueue();
  // Input 3 -> 1 -> 4 -> 2
  queue.offer(3).offer(1).offer(4).offer(2);
  //  0 0 0 1 1 1
  while(queue.isEmpty() == false) {
   System.out.println(queue.getMin());
   queue.poll();
  }
  // Output should be 1 -> 1 -> 2 -> 2
 }
 
 static class MinQueue {
  private Queue<Integer> mQueue = new LinkedList<>();
  private Deque<Integer> mMinDeque = new ArrayDeque<>();
  
  MinQueue offer(int val) {
   int min = val;
   while(!mMinDeque.isEmpty() && mMinDeque.getLast() > val) {
    mMinDeque.pollLast();
    min = val;
   }
   int size = mQueue.size() - mMinDeque.size();
   for (int i = 0; i <= size; i++) {
    mMinDeque.addLast(min);
   }
   mQueue.offer(val);
   return this;
  }
  
  int poll() {
   mMinDeque.poll();
   return mQueue.poll();
  }
  
  boolean isEmpty() {
   return mQueue.isEmpty();
  }
  
  int getMin() {
   return mMinDeque.peek();
  }
 }       

2/04/2017

Given a million points (x, y), give an O(n) solution to find the k's points closest to (0, 0).

Use quick select/partial sorting to resolve.
Solution:
 static class Point {
  int x;
  int y;

  public Point(int x, int y) {
   this.x = x;
   this.y = y;
  }

  public double getDistFromCenter() {
   return Math.sqrt(x * x + y * y);
  }
 }

 public static void main(String[] args) {
  Point[] points = new Point[7];
  points[0] = new Point(0, 0);
  points[1] = new Point(1, 7);
  points[2] = new Point(2, 2);
  points[3] = new Point(2, 2);
  points[4] = new Point(3, 2);
  points[5] = new Point(1, 4);
  points[6] = new Point(1, 1);
  int k = 3;
  qSelect(points, k - 1);
  for (int i = 0; i < k; i++) {
   System.out.println("" + points[i].x + "," + points[i].y);
  }
  // Output will be
  //        0,0
  //        1,1
  //        2,2
 }

 // in-place qselect and zero-based
 static void qSelect(Point[] points, int k) {
  int l = 0;
  int h = points.length - 1;
  while (l <= h) {
   int partionInd = partition(l, h, points);
   if (partionInd == k) {
    return;
   } else if (partionInd < k) {
    l = partionInd + 1;
   } else {
    h = partionInd - 1;
   }
  }
 }

 static int partition(int l, int h, Point[] points) {
  // Random can be better
  // int p = l + new Random.nextInt(h - l + 1);
  int p = l + (h - l) / 2;
  int ind = l;
  swap(p, h, points);
  Point comparePoint = points[h];
  for (int i = l; i < h; i++) {
   if (points[i].getDistFromCenter() < comparePoint.getDistFromCenter()) {
    swap(i, ind, points);
    ind++;
   }
  }
  swap(ind, h, points);
  return ind;
 }

 static void swap(int i, int j, Point[] points) {
  Point temp = points[i];
  points[i] = points[j];
  points[j] = temp;
 }

1/28/2017

[Interview type questions] First pair non matching leaves

Input: Given two (binary) trees, return the first pair of non-matching leaves Tree 1: A, B, C, D, E, null, null Tree 2: A, D, B
Output: (E,B)

Example:
Tree1 :              
      A
     /   \
   B     C
  /  \
D    E    

Tree2 :
    A
  /    \
D     B

Solution:
 static class TreeNode {
  public TreeNode(char v) { val = v;}
  char val;
  TreeNode left;
  TreeNode right;
 }
 
 static class MyIterator {
  Stack<TreeNode> stack = new Stack<>();
  MyIterator(TreeNode root) {
   pullAll(root);
  }
  
  void pullAll(TreeNode node) {
   while(node != null) {
    stack.push(node);
    node = node.left;
   }
  }
  
  public TreeNode next() {
   TreeNode next = stack.pop();
   if (next.right != null) {
    pullAll(next.right);
   }
   return next;
  }
  
  public TreeNode nextLeaf() {
   while(hasNext()) {
    TreeNode next = next();
    if (next.left == null && next.right == null) {
     return next;
    }
   }
   return null;
  }
  
  boolean hasNext() {
   return stack.isEmpty() == false;
  }
 }
 
 public static void main(String[] args) {
  TreeNode root1 = new TreeNode('A');
  root1.left = new TreeNode('B');
  root1.right = new TreeNode('C');
  root1.left.left = new TreeNode('D');
  root1.left.right = new TreeNode('E');
  TreeNode root2 = new TreeNode('A');
  root2.left = new TreeNode('D');
  root2.right = new TreeNode('B');
  char[] res = findFirstNonMatch(root1, root2);
  System.out.println(res);
 }
 
 static char[] findFirstNonMatch(TreeNode root1, TreeNode root2) {
  MyIterator iter1 = new MyIterator(root1);
  MyIterator iter2 = new MyIterator(root2);
  while(true) {
   TreeNode leaf1 = iter1.nextLeaf();
   TreeNode leaf2 = iter2.nextLeaf();
   if (leaf1 == null || leaf2 == null) break;
   if (leaf1.val != leaf2.val) {
    return new char[] {leaf1.val, leaf2.val};
   }
  }
  return new char[] {};
 }
       

[Interview type questions] Construct Binary search tree from given preorder array

Input: Give a preorder array
Output: Tree root

Example: If the given traversal is {10, 5, 1, 7, 40, 50}, then the output should be root of following tree.
     10
   /   \
  5     40
 /  \      \
1    7      50

Solution:
 static class TreeNode {
  public TreeNode(int v) { val = v;}
  int val;
  TreeNode left;
  TreeNode right;
 }

 public static void main(String[] args) {
  //       10
  //    5     40
  //  1  7       50
  int pre[] = new int[] { 10, 5, 1, 7, 40, 50 };
  int size = pre.length;
  TreeNode root = constructTree(pre, 0, size - 1);
  printInorder(root);
 }

 public static TreeNode constructTree(int[] pre, int l, int h) {
  if (l > h) return null;
  if (l == h) return new TreeNode(pre[l]);
  TreeNode root = new TreeNode(pre[l]);
  int ind = l + 1;
  // Find the first index which is greater than or equal to root
  for (int i = l + 1; i <= h; i++) {
   if (root.val < pre[i]) {
    ind = i;
    break;
   }
  }
  root.left = constructTree(pre, l + 1, ind - 1);
  root.right = constructTree(pre, ind, h);
  return root;
 }

 public static TreeNode constructTreeIterative(int[] pre, int l, int h) {
  if (l > h) return null;
  Stack<TreeNode> stack = new Stack<>();
  TreeNode root = new TreeNode(pre[l]);
  stack.push(root);
  for (int i = l + 1 ; i <= h ; i++) {
   int val = pre[i];
   // Handle left side
   if (stack.peek().val > val) {
    TreeNode left = new TreeNode(val);
    stack.peek().left = left;
    stack.push(left);
   } else {
    // Handle right side and find its paraent
    TreeNode rightParent = null;
    while(!stack.isEmpty() && stack.peek().val < val) {
     rightParent = stack.pop();
    }
    rightParent.right = new TreeNode(val);
    stack.push(rightParent);
   }
  }
  return root;
 }

 public static void printInorder(TreeNode node) {
  if (node == null) {
   return;
  }
  printInorder(node.left);
  System.out.print(node.val + " ");
  printInorder(node.right);
 }
       

1/27/2017

[Interview type questions] Divide friends into two groups, and people in the same group do not know each other

Input: Give edges to represent their relations.
Output: Divide the friends into two groups, and people in the same group do now know each other.

Example: Give 4 persons. [0, 1] [1, 2] [1, 3]
         0 and 1 know each other, 1 and 2 know each other...
         We can take 0,2 as group 1 and 1,3 as group 2.

Solution: Use bipartite graph with BFS to resolve this problem:
  int n = 4;
  int[][] relations = new int[][] { { 0, 1 }, { 1, 2 }, { 2, 3 } };

  // Build a graph and initialize groups
  HashMap<Integer, Set<Integer>> graph = new HashMap<>();
  int[] group = new int[4];
  Arrays.fill(group, -1);
  for (int[] edge : relations) {
   Set neighbors = graph.getOrDefault(edge[0], new HashSet<>());
   neighbors.add(edge[1]);
   graph.put(edge[0], neighbors);
  }
  // BFS, start with 0
  Queue queue = new LinkedList<>();
  queue.offer(0);
  int groupdId = 0;
  group[0] = groupdId;
  while(queue.isEmpty() == false) {
   int v = queue.poll();
   groupdId = 1 - group[v];
   // Get its neighbors
   // No neighbors..
   if (graph.get(v) == null) continue;
   for (int neighbor : graph.get(v)) {
    if (group[neighbor] == -1) {
     group[neighbor] = groupdId;
     queue.offer(neighbor);
    } else if (group[neighbor] == group[v]) {
     // It cannot be divided into two group. Invalid bipartite graph
     break;
    }
   }
  }
  
  for (int g : group) {
   System.out.println(g);
  }
       

1/10/2017

Serialize/De-serialize data to a file using Flatbuffers


Read & Write

       

#include "flatbuffers/util.h"

flatbuffers::FlatBufferBuilder builder;

// Create something using builder
// ......

// Save to file
bool result = flatbuffers::SaveFile(filename.c_str(),
                                      (const char *) builder.GetBufferPointer(),
                                      (size_t) builder.GetSize(), true);

// Load from file
std::string buffer;
result = flatbuffers::LoadFile(fileName, true, &buffer);
printf("\nLoadFile Result = %d", result);


// You can write your own Save/load function
bool MySaveFile(const char *name, const char *buf, size_t len,
                     bool binary) {
  std::ofstream ofs(name, binary ? std::ofstream::binary : std::ofstream::out);
  if (!ofs.is_open()) return false;
  ofs.write(buf, len);
  return !ofs.bad();
}

bool MyLoadFileRaw(const char *name, bool binary, std::string *buf) {
  std::ifstream ifs(name, binary ? std::ifstream::binary : std::ifstream::in);
  if (!ifs.is_open()) {
    return false;
  }
  if (binary) {
    // The fastest way to read a file into a string.
    ifs.seekg(0, std::ios::end);
    auto size = ifs.tellg();
    (*buf).resize(static_cast(size));
    ifs.seekg(0, std::ios::beg);
    ifs.read(&(*buf)[0], (*buf).size());
  } else {
    // This is slower, but works correctly on all platforms for text files.
    std::ostringstream oss;
    oss << ifs.rdbuf();
    *buf = oss.str();
  }
  return !ifs.bad();
}