Saturday, April 2, 2016

Practice difference: How top sports player practice?

April, 2015

The best way for a software developer to take a break, is to study something else; let me propose an idea for myself today, and see if I can make a good shot or not.

See how top tennis player Male/ Female structure their practice? :-) Just kidding, I can only observe a few things as a player over 300, maybe, 500 hours.

Julia likes to study tennis teaching video, she learns a lot how to make a talk 2-3 minutes on a specific topic through coaching video.


Eugenie Bouchard - Fear Less

https://www.youtube.com/watch?v=4MVb3SR2yNA

https://www.youtube.com/watch?v=5YWdkxMQA6s

Li Na
https://www.youtube.com/watch?v=Qewi-SB5hWU

Novak Djokovic 

https://www.youtube.com/watch?v=HuWL65vrTJU

Murray's practice and his coach -
https://www.youtube.com/watch?v=YtvQRq0FvNI

https://www.youtube.com/watch?v=zR0U7wl213I&ebc=ANyPxKpEc8T3E79_tAtkvdPDj8KjfbAmn05rGWxNHe3BI7RzXCaZB24KHMMmRjUmTdSxsAgyZ60CP967G21vbREU5Pd3eFahuw

Overhead, and then, from forehand -> anywhere, receiving, and then, serving.

Just watch the hitting partner - the helper, how he can follow the instruction, last minute, when Novak calls wide, how the helper can place the tennis ball wide for him to receive.

Julia, you pay more attention to how they are focusing on training, and other technical things. Julia likes Novak using hand language to communicate to switch courts.

https://www.youtube.com/watch?v=ausQH8y3nQY

Hitting partner told Novak hitting outside - long just one inch.

Drills - Julia's favorite drills - double alley drill
2014 USPTA Tennis Teacher's Conference in New York City
https://goo.gl/bztNNE

Julia likes to organize some activity with sports to encourage people moving/ exercise, a lot of ideas for people in office, church etc. Julia loves the teaching how to do things on the court.
https://goo.gl/KD8RHa
Great teaching - medicine ball usage, foot work, forward to the ball.
https://www.youtube.com/watch?v=zpldQqYz2RE

plan to watch:
Mental skills for your players
https://www.youtube.com/watch?v=E8-7LA9-UOY

A few verses to memorize, every top tennis player loses, but still continues:
Genie Bouchard 2014 Montage - Good music always is welcomed! "In the Air Tonight" I want to be next version of me, not other person. What a good statement! 
https://www.youtube.com/watch?v=JZJ8K5857dk

Lyrics:
http://www.azlyrics.com/lyrics/philcollins/intheairtonight.html

HackerRank: string algorithm - Reverse Shuffle Merge (II) - next - forming a partial correct idea

April 2, 2016

  Problem statement is here.   

  Introduction


Julia likes to share her experience, advance level on HackerRank. It is not bad in the weekend, spend 2 hours messing around the ideas/ hackerRank, come out a clear greedy algorithm. The hackerRank definitely helps Julia to shape her idea from start to end.

Practice talk 


  First two hours work - failed twice, detail here in the blog.     

  Here is the idea after 2 hours intensive work:
of course, "abc" is the smallest one in lexicographical order, but the possible string formats:
  *a*b*c*, not *abc*, now * means any number of any chars.

 Let us count how many of a, b, c can be skipped when we do linear scan of a string.

 Now, it should be very easily to introduce greedy algorithm.

 For example, if linear scan from left to right, visiting char b, then, we have to check how many b's left can be skipped, if it is bigger than 0, we have to check any char before b has anything left or not. For example, if a still has some number left to skip; we hold on b, just skip current b.

 Otherwise, count current b into the string we are looking for, and decrease the number count of b (recording how many b can be skipped).

Use an example to explain:
  a2b2c2 case,
 ba*, the half should be a1b1c1,
 so, skip first char 'b', since greedy algorithm / let 'a' go first.

 Give it a try, implement the idea:

 Some statistics: advanced algorithm 4+ hours - A mountain - "Sea to sky Gondola" to climb

Spent 9:47 am - 11:47 am, wrote code, but still failed most of case; only pass "eggegg";
Hard to concentrate, and think about the issue - this reverse is tricky!

Here is the C# solution - 3 rd failed try. Code is here.

Baby hacker is crying, still score zero: 4 hours work. Code is here.

Now, it is 1:47 pm, another 2 hours with music, the code was submitted, now score 16.67/ 50. Still need to work on more before Julia plan to read other people's solution:

Some statistics: advanced algorithm 6+ hours - A mountain - Sea to sky Gondola to climb. Code is here. 

Need to stop, go to enjoy outdoor activities!

Baby hacker is showing off her baby steps, the report of test cases pass/ fail on Hackerrank is here.

Try to fix the error, give up - the design has another flaw,
test case:
djjcddjggbiigjhfghehhbgdigjicafgjcehhfgifadihiajgciagicdahcbajjbhifjiaajigdgdfhdiijjgaiejgegbbiigida
i=50, s[i] = 'g', the design let 'g' skip, but
i=52, s[i] = 'i', 'i' has to be added to the output, no more skip.

<-  Julia, think about stack, use some data structure to do reverse work <- such a great workout! Release all my stress and headache, and be humble!

5:12 pm, statistics: Another 3 hours, total: 9+ hours 

Follow up 


May 3, 2017

Thursday, March 31, 2016

HackerRank: string algorithm - Reverse Shuffle Merge (I) - First step: Failed twice

March 31, 2016

  Problem statement is here.

 Introduction


 The algorithm is in advanced category. 8:17 am - 10:08 am. Document 2 hours work as a hacker, Julia. First time, Julia thinks that hacker is a good name!

 Practice Talk


Start from 8:19 am, 9:18, tried twice, passed one test case, failed others with wrong answer;  then, need to pay attention to reverse string word.

Spent more than 20 minutes to think, but could not figure out the solution. Have to stop here. Write down the analysis first. Come back later.

The naive solution is to count string in each char in "abc...z", and then, half of count will construct a new string.

For example, if the string counting: a2b2c2
then, the string A is one of strings {abc, bac, cba, bac, aca, cab}

Of course, "abc" is the smallest one in lexicographical order, but the possible string formats:
  abc***
  *abc**
  **abc*
  ***abc

Or, go through each possible string - find the minimum one, smart way to compare with previous one, keep the smallest one.

Assuming that the string is matching.

Got the idea. Linear solution.  From 8:19 am - 8:45 am, more than 20 minutes to come out the idea.

9:00 am -
Two functions - one function is to count the number to determine that count for each char is even. Another step is to go over the string, take substring(i, 3).

20 minutes to write a code, a bug to fix: wrong answer
Need to make sure that substring count matching count first, otherwise, skip it! 
  
9:15 am, bug is not fixed; and then, notice that the string has to be reversed! 

10:16 am, still not fixed. Julia, this is a greedy algorithm, why is the greedy part? You missed merge part in the construction merge(reverse(A), shuffle(A)). So, you have to redesign the algorithm.

Conclusion


1. Design algorithm - advanced - know why it is advanced, examine the idea and see if you can make it first; Otherwise, waste time to write code

Two hours, failed two tries! A new hacker is getting her valuable lesson using 2 hours.

Here is the C# code.

Follow up 


Blog review on May 3, 2017

Wednesday, March 30, 2016

HackerRank: String algorithm - Palindrome index

March 30, 2016

  HackerRank, Easy questions, 1 hours 3 questions. More practice, please! Get some momentum!

  Things are looking for:
  1. Tips to cut time to write code; 
  2. Make the problem a simple problem - read the hint ! 
  3. Avoid writing too many lines code in less than 10 minutes. 
  4. More tips !!!

  Problem statement:
https://www.hackerrank.com/challenges/palindrome-index


  Julia worked on this solution in 15 minutes, but she only scored 23 out of 25. She tried to figure out how to score 25. She missed the statement: "There will always be a valid solution."

  Her C# solution (Time out last test case): Time complexity O(N^2), N is the length of string

Julia's practice using C#, solution is here.
 

  So, Julia goes over those two cases in 25 minutes. It takes time to find great ideas:

  Solution 2:

use recursive function, while loop. Time complexity is O(N).

Solution 2


  Solution 3:

use iterative solution, once a possible index is found, stop. You do not need to verify that the string is palindrome. Assuming that there is a valid solution.  Time complexity is O(N).

solution 3


  Solution 4:

solution 4


Follow up after 12 months


April 26, 2017






Sunday, March 27, 2016

Video watching: a guide to object-oriented practice

March 27, 2016

Spent 2 hours to watch the video:

https://mva.microsoft.com/en-us/training-courses/a-guide-to-objectoriented-practices-14329?l=PLMOEi2hB_904668937

Take some notes, and also write down tips helpful.

Look up those terms:

internal
readonly
expression-bodied member
SRP - Single Responsibility Principle
S.O.L.I.D. - OO principles



Read some blogs:
http://stackoverflow.com/questions/28411335/expression-bodied-function-members-efficiency-and-performance-in-c-sharp-6-0

http://yqcmmd.com/2014/06/12/%E6%95%B0%E4%BD%8Ddp%E4%B8%93%E9%A2%98/



HackerRank: Sherlock And Anagram (VI)

March 27, 2016

 Julia was surprised to have a workout on this moderate difficult string problem from 9:00am - 4:00pm. She did some code study, and then, read so many codes from Microsoft, box, and saleforce, Amazon, and then, she read linkin profile, and blogs. She is getting connected to all other programmers in the world. HackerRank is young, all the coders are in charge of business this world, right now! No complaint.

 Just learn one good code  a time. Pay attention to some details. Follow up with a revisit once a while. Julia, you will make your programmer life easy, just relax, and see how people are creative to solve problems. You should do so, just copy the idea. Make sure that think by yourself first, do not be a copycat.

 This code is her favorite. She is still learning, never use SortedDictionary before,


 code reference:
https://www.hackerrank.com/Relentless

http://anothercasualcoder.blogspot.ca/#!

 Julia is too busy to work on coding, so she chooses on easy to moderate questions. She waited until 7 - 10 string questions, and then, finally, she worked on her first moderate question on HackerRank after 1 - 2 months. But, she likes to read other people's code, and then, she just needs ideas to solve problems.

 Here is the code gist:

https://gist.github.com/jianminchen/22f8e0de115cf656995e

/*
 Julia likes to talk about design of the function, through debugging, she knows a few things:

  For string "abba", 
  First, go over string with length 1, 
  then, SortedDictionary - key 'a', 'b', values are 2, 2
  then, Hashtable htPairs - key: a2, value: 

  then, go over string with length 2, 
  then, SortedDictionary - key 'a', value 1; key 'b', value '1'

  "abba" go through a loop, to get substring with length 2, in the order:
    ^  ->
     |
    "ab", 
    "bb", 
    "ba"
1.   string "ab", , key "a1b1",   htPairs["a1b1"] = 1
2.  string "bb", key "b2",          htPairs["b2"] = 1
3.  string "ba",            hashTable contains the key, so the value htPairs["a1b1] = 2
  Hashtable key "a1b1", sortedDictionary, value 2

*/
 static BigInteger UnorderedAnagrams(string str)
    {
        Hashtable htPairs = new Hashtable();

        for (int len = 1; len <= str.Length; len++)
        {
            for (int i = 0; i + len <= str.Length; i++)
            {
                SortedDictionary<char, int> anagram = new SortedDictionary<char, int>();
                for (int j = i; j < i + len; j++)
                {
                    if (anagram.ContainsKey(str[j]))
                    {
                        anagram[str[j]] = (int)anagram[str[j]] + 1;
                    }
                    else
                    {
                        anagram.Add(str[j], 1);
                    }
                }

                string finalKey = "";
                foreach (char key in anagram.Keys)
                {
                    finalKey += key.ToString() + ((int)anagram[key]).ToString();
                }

                if (!htPairs.ContainsKey(finalKey))
                {
                    htPairs.Add(finalKey, 1);
                }
                else
                {
                    htPairs[finalKey] = (int)htPairs[finalKey] + 1;
                }
            }
        }

        BigInteger finalResult = 0;
        foreach (string k in htPairs.Keys)
        {
            finalResult += Combinatorial((int)htPairs[k], 2);
        }

        return finalResult;
    }
Blogs:
http://juliachencoding.blogspot.ca/2016/03/hackerrank-string-sherlock-and-anagrams.html


HackerRank: Sherlock and anagrams (V)

March 27, 2016

Problem statement:

Difficulty: Moderate

More C# solution:

Solution 1:
Julia, here is code you  should study; more advanced than yours.

a person works for Box Inc.
https://www.hackerrank.com/__run
https://gist.github.com/jianminchen/576ecf2cd127a703cb7a

Learn C# coding: readonly, Equals, override, constructor, use byte instead of int. Take some time off, learn C#, OO design basics:

Here are the code, make some comments to read some articles to catch up:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SherlockAndAnagrams
{
    class CharCount
    {
        protected bool Equals(CharCount other)
        {
            return Equals(Array, other.Array);
        }

        /*
             Design concern:
             hashcode for anagram strings - same 
             
             use unchecked function
             figure out this design: 
             a                         b                c           ...   y               z
             3                         1                                   1               1
             3*(26*13)^25        1*(26*13)^24                 1*(26*13)    1
        */
        public override int GetHashCode()
        {
            int hc = Array.Length;
            for (int i = 0; i < Array.Length; ++i)
            {
                hc = unchecked(hc * 13 + Array[i]);  // Julia, figure out how this hashcode is working for anagram
            }
            return hc;
        }

        public readonly byte[] Array;   // Julia, readonly, why to use byte[] 

        public CharCount()
        {
            Array = new byte[26];
        }

        public CharCount(CharCount charCount)
        {
            Array = new byte[26];
            for (int i = 0; i < 26; i++)
            {
                Array[i] = charCount.Array[i];
            }
        }

        public void AddChar(char ch)  // 
        {
            Array[ch - 'a']++;
        }

        public override bool Equals(object obj)  // override Equals function 
        {
            CharCount other = obj as CharCount;
            if (obj == null)
            {
                return false;
            }

            for (int i = 0; i < 26; i++)
            {
                int val = Array[i].CompareTo(other.Array[i]);  // byte.CompareTo 
                if (val != 0)
                {
                    return false;
                }
            }

            return true;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            int t = int.Parse(Console.ReadLine());
            for (int i = 0; i < t; i++)
            {
                HandleTestCase();
            }
        }

        private static void HandleTestCase()
        {
            IDictionary<CharCount, int> dictionary = new Dictionary<CharCount, int>();
            string str = Console.ReadLine();

            for (int i = 0; i < str.Length; i++)
            {
                CharCount charCount = new CharCount();
                for (int j = i; j < str.Length; j++)
                {
                    charCount.AddChar(str[j]);
                    if (!dictionary.ContainsKey(charCount))
                    {
                        dictionary.Add(new CharCount(charCount), 1);
                    }
                    else
                    {
                        dictionary[charCount] = dictionary[charCount] + 1;
                    }
                }
            }

            Console.WriteLine(dictionary.Values.Sum(value => ((value * (value - 1)) / 2)));
        }
    }

}


HackerRank: Sherlock and Anagrams IV

March 27, 2016

Problem statement:

Difficulty: Moderate

More C# solution:

Solution 1:
Julia, here is code you  should study; more advanced than yours.

a person works for Box Inc.
https://www.hackerrank.com/__run
https://gist.github.com/jianminchen/576ecf2cd127a703cb7a

Learn C# coding: readonly, Equals, override, constructor, use byte instead of int.

Solution 2:
use Dictionary class, string key for anagram string, use getHashCode() call to turn key as Int.

https://gist.github.com/jianminchen/ffcca0582b5f0d1d6a9b

Read about getHashCode() webpage:
https://msdn.microsoft.com/en-us/library/system.object.gethashcode(v=vs.110).aspx

Solution 3:
https://gist.github.com/jianminchen/8f6bd4631f0b5f0bdee7


Solution 4.
use Dictionary class, sort the key string, then anagram strings will be the same.

https://gist.github.com/jianminchen/59e326cbd1d8910c01c7

solution 5:
Excellent code, written by a programmer in salesforce.com
https://www.hackerrank.com/rest/contests/w13/challenges/sherlock-and-anagrams/hackers/rosharyg/download_solution
Julia likes the code:

https://gist.github.com/jianminchen/d2ccf6532524d8751c73

Solution 6:   <-  simple and quick, it can be written in less than 20 minutes. But not time efficient! O(n^2 * string length)

Use brute force, 3 loops, and then define anagramChecking function, just basic array, simple and quick.

https://gist.github.com/jianminchen/9f381875942d468ccb00









HackerRank: Sherlock and anagrams (II)

March 27, 2016

Problem statement:

Difficulty: Moderate

Summary of practice

This problem solving gets hot. Julia found something she struggled a lot. When Julia spent more than 2 hours on a problem in the Saturday evening, she knew that she is in trouble. She needs to be trained, and she needs a mentor.

Time Spent: March 26, 2016  Saturday evening 9:30 - 11:30
                                               Sunday morning  9:00 - 12:00 

Julia's practice is here.

Code Study

Let us get ideas how other people solve the problems, study the code. Julia is training herself thinking in C# using HackerRank:

1. Hash function design 

code source is provided by a person 19 Gold, unbelievable smart and quick/ fast / great expressive code. 


Code study - code is here. 

The anagram string function is composed to the design of key in the Dictionary. 

Julia added some comment above the hash function 

/*
precondition:
if two string are anagram, then key of these two strings should be the same

"ab" and "ba" are the anagram, key should be the same
"ab" and "bc" are not the anagram, so keys should not be the same.

Julia's comment: 701 is confusing, why it has to be this big number?
*/

int Fun(string s, int l, int r)
    {
        var ret = new int[26];
        for (int i = l; i <= r; i++)
            ret[s[i] - 'a']++;

        int x = 0;                  // Julia's comment: should be 1  
        for (int i = 0; i < 26; i++)
            x = x * 701 + ret[i];

        return x;
    }

Julia goes over the detail to check: 

Key is designed using math formula polynomial expression:
string a -> key is integer:  0
string b -> key:   1
string ab -> key:  x = 1
                            x =  1* 701 + 1
string ba -> 11 ->  key:  x = 1 * 701 + 1
string bc -> 011-> key:  x = 0 ,  count of a is 0
                             x = 1,   count of b is 1
                             x = 1 * 701 + 1
"ba" and "bc" are not anagram, so the key should be different: both are 1 * 701 + 1

string ad -> 1001 -> key x  = 1,               count of a is 1
                                        x = 701 + 0 ,    count of b is 0
                                        x = 701 *701 + 0
                               key = 701^3 + 1

Math or computer science

Julia found out that the idea can save a lot of time, she likes to work hard. But she is also "lazy" and likes to write less code. 

Julia changed the key design, and ran the code in HackerRank, it also passed the test cases. In Julia's opinion, the code has a bug in theory but pass the HackerRank test; so, Julia fixed the code anyway. 


Just practice! It is not a science of math, it is computer science. 

C# practice code is here.

Further code review on other things

Julia is still interested in writing loops, more expressive. Let us review how the code does:

public object Solve()
{
        for (int tt = ReadInt(); tt > 0; tt--)  // Julia's comment: put ReadInt() into a loop
        {
            string s = ReadToken();
            int n     = s.Length;
            int ans = 0;
            var count = new Dictionary<int, int>();

            // Julia's comment: substring length from 1 to n-1,
            for (int i = 1; i < n; i++)  
            {
                // substring start position - j, end position: j+i-1, and check j+i <=n, easy to reason - avoid bug
                for (int j = 0; j + i <= n; j++) 
                {
                    var key = Fun(s, j, j + i - 1);
                    if ( !count.ContainsKey(key) )
                    {
                        count[key] = 0;
                    }

                    count[key]++;
                }
            }

            foreach (var p in count)
            {
                ans += p.Value * (p.Value - 1) / 2;
            }

            writer.WriteLine(ans);
        }

        return null;
    }

701 prime number vs 26

One more step, improvement:  Failed. Number from 701 to 26, it does not work. It depends on the length of string, which is <=100. Julia tried to figure out some math, algebra, but she is sure that the number should be coefficient, so, 
at least >100. 

Julia, the key design for anagram string can be modified:  
/*
precondition:
if two string are anagram, then key of these two string should be the same

"ab" and "ba" are the anagram, key should be the same

"ab" and "bc" are not the anagram, so key should not be the same.

*/
int keyForAnagramString(string s, int l, int r)
{
        var ret = new int[26];
        for (int i = l; i <= r; i++)
            ret[s[i] - 'a']++;

        int x = 1;                  // Julia's comment: should be 1  

        for (int i = 0; i < 26; i++)
        {
            x = x * 26 + ret[i];
        }

        return x;
}

Julia spent 5 hacko to buy the test case input/ output: 


One more try - 101 

Because the string length is <=100, so that coefficient is less than 100.

Key design can be changed to a small number 701 to 101, it passes the HackerRank test:

/*
precondition:
if two string are anagram, then key of these two string should be the same

"ab" and "ba" are the anagram, key should be the same
"ab" and "bc" are not the anagram, so key should not be the same.
*/
int keyForAnagramString(string s, int l, int r)
{
        var ret = new int[26];
        for (int i = l; i <= r; i++)
            ret[s[i] - 'a']++;

        int x = 1;                  // Julia's comment: should be 1  

        for (int i = 0; i < 26; i++)
        {
            x = x * 101 + ret[i];
        }

        return x;
}

January 8, 2017

Come back to visit the blog, and then spent 10 - 20 minutes to work on layout, fixed grammar errors.