Showing posts sorted by relevance for query case study. Sort by date Show all posts
Showing posts sorted by relevance for query case study. Sort by date Show all posts

Sunday, June 9, 2019

5087/ 1079. Letter Tile Possibilities - case study "AAB"

June 9, 2019


Introduction


It is the algorithm I like to learn as many solutions as I can. I also think about how to use this algorithm in mock interview for me to explore the algorithm as much as I can in future interviews on interviewing.io as a mock interviewer.

Case study


Here is one elegant solution I like to explore, learn and write one.
I wrote C# code based on the above post. Here is the link. Also, I did case study on "AAB", and then I wrote a solution to show all tiles as well. Here is the link.

I also copy and paste the content here.

It is challenging job to write a case study, and then figure out how to interpret the code written in such an elegant solution, the solution post is here. I like to share the solution with case study "AAB" and extra output to show depth first search all result with "AAB" study case.
Case study "AAB"
I like to write down some explanation based on case study "AAB". I am just a learner with some curiousity. Follow me and let me know if I miss the important things in my analysis.
case study: "AAB"
count: A -> 2, B->1
length 1: "A", "B"
length 2:
For "A":
count: A->1, B->1
We can still pick either A, or B
So we have "AA,"AB"
For "B":
count: A->2, B->0
We can only pick A
So we have "BA"
The answer is 8. How to ensure uniqueness?
set prefix = ""
dfs("AAB") -> two distinct chars, 'A', 'B', each one sum variable increment one; related to tile: prefix + "A", prefix + "B".
For 'A' case, next step is to calculate dfs("AB"), what ever it has, the string should be prefixed with "A".
For 'B' case, next step is to calculate dfs("AA"), what ever it has, the string should be prefixed with "B".
So the output of search result is the following:
"A"
"AA"
"AAB"
"AB"
"ABA"
"B"
"BA"
"BAA"
Next step
Since the algorithm is to ask the total number of tile possibilities, we do not need to know all tiles. I mark those lines of code added just to be easily followed.
The code with debugging info
I made a few changes based on study code, so that it is easy to tell statement "sum++", what is the tile content.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _5087_Letter_tile_possibilities
{
    class Program
    {
        static void Main(string[] args)
        {
            NumTilePossibilities("AAB");
        }

        /// <summary>
        /// June 9, 2019
        /// study code:
        /// https://leetcode.com/problems/letter-tile-possibilities/discuss/308284/Concise-java-solution
        /// </summary>
        /// <param name="tiles"></param>
        /// <returns></returns>
        public static int NumTilePossibilities(string tiles)
        {
            int[] count = new int[26];
            foreach (var item in tiles)
            {
                count[item - 'A']++;
            }

            var all = new List<string>();
            return depthFirstSearch(count, "", all);
        }

        /// <summary>
        /// case study: "AAB"
        /// count: A -> 2, B->1
        /// length 1: "A", "B"
        /// length 2: 
        /// For "A":
        ///   count:  A->1, B->1
        ///   We can still pick either A, or B
        ///   So we have "AA,"AB"
        /// For "B":
        ///   count: A->2, B->0
        ///   We can only pick A
        ///   So we have "BA"
        /// Questions:
        /// 1. uniqueness - not duplicated one, how to ensure uniqueness
        /// 2. 
        /// </summary>
        /// <param name="numbers"></param>
        /// <returns></returns>
        private static int depthFirstSearch(int[] numbers, string prefix, List<string> tiles)
        {
            int sum = 0; 
            for(int i = 0; i < 26; i++)
            {
                if(numbers[i] == 0)
                {
                    continue;
                }

                sum++; 
                /* determine what is tile to be added*/
                char toChar = Convert.ToChar('A' + i);
                var nextPrefix = prefix + toChar.ToString();
                tiles.Add(nextPrefix);
                /**/

                numbers[i]--;
                sum += depthFirstSearch(numbers, nextPrefix, tiles);

                numbers[i]++;
            }

            return sum; 
        }
    }
}

Saturday, June 6, 2020

stock research: meeting notes

June 6, 2020

Introduction

I like to take some notes after the meeting. The meeting is such great opportunity for me to build a community around me and us to work together as a long term and short term investor.

Meeting notes

June 6 2020
Wechat zoom meeting
Time: 2:00 PM - 6:00 PM


  1. Use CNN premarket to check the price: https://money.cnn.com/data/premarket/
  2. Market open time is four hours short compared to US time; 6:00 AM - 1:00 PM in PST;
  3. Psychology of investment: Some people quit after one year or two; stress on the market down term - for example, 2001 after 911, 10% of fund, 10 year - 20 year recover 
  4. Zoom meeting - first time we met together, Julia believes that good communication is based on real communication, face-to-face, using voice and also life experience to help each other;
  5. Zoom meeting - the member has an account with up-to-500 people;
  6. Case study discussed: OVV.TO stock, March 27, 2020, 3.7/ share, June 6 14.00/ share, June 5 400% up after the discussion of wechat group
  7. Case study discussed: Boeing stock, 2 months to hold, no fund to trade
  8. Case study discussed: Boeing stock, 150 share, $130 price, 20850 
  9. Top business name, like Amazon, pros/ cons, it cannot be doubled, safe to invest, no big drop recently. 
  10. Case study Costo stock: 10 - 20 dollars day range - good for day trade 
  11. Case study: One member said two weeks ago, she proposed purchase $10,000 each for stocks like RCL, Boeing, GE etc. 
  12. Case study: China stock - Alibaba, online education
  13. Case study: GE stock - three of us purchased from $5.5 to $8, one purchased in January 2020
  14. More on step 13, 4000 share, $13 dollars, news came out, the stock went down to $5/ share; relate to China, if China purchases GE aviation product
  15. Case study: Facebook stock, good for day trading, no worry about big swings etc. 
  16. Case study: ENBL - why Anna likes the stock, price is cheap; Good thing about cheap, $4.00 stock take $0.40 10% return, good for short term gains. Market swing is good for low price. Go for 500 or 1000 share for one investment opportunity;
  17. How to handle stress of investment? Running, build a small community, how to work with each other, small business opportunities for consultation, zoom short meeting to relax when market down
  18. How to build a long term relationship if possible? Vancouver area meet-up after Coronavirus? Where the fund comes from? Casual and loose relationship, and Julia likes to purchase some stocks to memorize the first Zoom meeting, she emphasizes her needs for zoom meeting, social support for investment stress sometimes. 
  19. It is important to be healthy in order to invest on stock market
  20. Canada bank - CIBC - US stock trading
  21. Ms Fu thought about market crash, before July 1 earning season; Julia thinks that market needs to continue bull market, companies not in index fund still has 25% to 50% to recover
  22. Rules of small wechat group, size, and communication concern - Stay same size for another two to three weeks
  23. Julia talked about inviting a professional trader in China as a consultant, and she like to have zoom meeting ...
  24. Business relationship, investment $40,000 cash - OVV 4 times from March 27 - June 6, 2020
  25. How to consider gambling issue in stock investment?
  26. How to concentrate on work not looking at stock market? 
  27. How often to trade investment fund? Think about long term/ short term need. 
  28. Career summary: One works for hospital, one is having Ph.D. education background, one is working on personal business, and one works for IT industry as a software programmer
  29. Adobe stock: 2019 July $280, 2020 June $380, stock went up 
  30. Princeton university - human interface design education - career in Adobe, not 996
  31. UBC math education, college first year, Google intern
Thanks every one to contribute first meeting. Wish every one good health and build wealth in stock market. Be patient, and also keep learning. 


Monday, February 18, 2019

Case study: Where I spend money from 2010 to 2019?

Feb. 18, 2019

Introduction


It is hard for me to adapt to be a Canadian. I did my personal finance research, and I like to case study and try to figure out how I can push myself to learn how to survive in Canada. I have worked full time in Canada 8 years 9 months, I like to push myself to learn more about personal finance and conduct my case studies.

Case study


I did my vacation study, I spent five vacations to China from 2012 to 2018. I told my brother and sister on December 2018, since my mom passed away in Nov. 2017, I will no longer take vacation to China. I like to be independent and find ways to have my own housing in Canada.

Case study of my airline ticket expense, here is the link.
Case study of 2012 vacation in China, here is blog first 24 months in Canada.
Case study of 2014 vacation in China, California, Florida, Philadelphia. 
    Here is the blog of vacation to California. 
    Here is the blog of vacation to Philadephia. 
Case study from 2010 to 2019 clothing expense, here is the link. 
Case study of wanted not needed on citi credit card. Here is the link. 
My sponsor application project management. Here is the link. 
How much I paid coach May 2018? Here is the link. 
My car maintenance. Here is the blog.
My saving rate from 2010 to 2018. Here is the blog.


Actionable Items


I need to learn how to avoid scam, and also I need to limit myself to reduce risk, avoid renting the car, drive less, and also need to learn where the opportunity for me to invest with a moderate income as a software programmer.



Tuesday, June 23, 2020

Leetcode discuss: 301 remove invalid parentheses

Here is the link.

C# BFS approach without pruning practice in June 2020

June 23, 2020
301 remove minimum invalid parentheses
Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results.
How to study a solution written in BFS?
I did learn the idea back in 2018. After two years, I learned and value the case study method.
It is important for me to write down a few simple test cases first, and then go over one by one to explain to myself first, how to apply BFS and make it work.
Case study approach from Harvard business school teaching is my favorite learning technique now.
I like to study the BFS solution again written in Java. The link is here.
2020 June 23 - review BFS solution
I plan to write a C# solution using the same idea. I will write a case study to explain how to approach the problem.
I spent a few hours to write a solution on June 22, 2020, here is the link.
I debugged the code using string "())" step by step, it is hard for me to understand the design. So I decide to remove pruning part, focus on basic BFS algorithm. Keep minimum to solve the problem first using BFS.
I decided to continue to remove those code hard to understand, in other words, make it work for Leetcode online judge, remove those pruning ideas first.
Case study
I think that it is important to go over test cases and then talk about how to solve the problem. The following is to go over valid string, remove one parenthese, two parentheses three test cases.
Case study 1: "()", or any valid string
The string is valid, so first step in my design is to check original string is valid or not.
If it is, then return original string. Othewise at least one parenthese should be removed.
Case study 2: Remove one parentheses
For example "())", minimum number of invalid parentheses is 1, result is "()".
"(()"
How to design using BFS algorithm, using Queue to help.
Remove one char from index = 0 to last one, and see if the substring is valid or not.
index = 0, "))", not valid
index = 1, "()", valid
index = 2, "()", valid
The way to skip the duplicate valid string is to save in the hashset first, and then convert set to List object.
Rule 1:
Always consider to put "))" in the queue to process since original one "())" is not a valid string.
One more test to remove one char - case study 2
")()"
First, it is not valid parentheses string. So at least one parenthese should be removed.
Go over each index position of string ")()", remove the char,
First one is index = 0; "()" is valid one, so "()" is added to output;
Second one is index = 1; "))" is not valid, but output list is not empty, continue;
Third one is index = 2; ")(" is not valid one.
It is important to go over a few simple test cases to understand how BFS works, and then it is time to think about how to prune the algorithm and make it more efficient.
Here are those two important steps:
First, push Tuple<string, int>("())",0) into queue;
and then go over each index position from "())", remove each char, see if it is valid or not.
Case study 3: Remove two parentheses
String "())(()", how to find the valid string "()()" to remove two parentheses?
The above test case is so helpful for me to understand BFS, first remove one parenthese, all those substrings are not valid string, which should be queued for next removal of one more parenthese.
Work on the iteration. I will add more explanation for this test case.
"))(()", 0
"()(()", 1
"()(()", 2
"())()", 3
"())()", 4
"())((", 5
From the above four test cases, "())()", 4 should be same as "())()", 3. So it is not needed to be repeated.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _301_remove_invalid_parentheses___2020
{
    class Program
    {
        static void Main(string[] args)
        {
            //var reuslt  = RemoveInvalidParentheses("()"); // original one valid or not - step 1
            //var result2 = RemoveInvalidParentheses("())"); // need to remove one parentheses - step 2
            var result3 = RemoveInvalidParentheses("())(()");
        }

        /// <summary>
        /// code review on June 22, 2020
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static IList<string> RemoveInvalidParentheses(string s)
        {
            var set = new HashSet<string>(); 

            // return if it is valid
            if (IsValidParentheses(s))
            {
                set.Add(s);
                return set.ToList();
            }

            // How to design a queue - BFS to solve the problem? 
            // think about a string to remove two parentheses, "())(()", 
            // those strings with one char removed should be enqueued for next removal of char
            var queue = new Queue<Tuple<string, int>>();

            //The 2-Tuple is (string, startIndex)                        
            queue.Enqueue(new Tuple<string, int>(s, 0));            

            while (queue.Count > 0)
            {
                var current = queue.Dequeue();

                var search = current.Item1;
                var start = current.Item2;               

                // Start from last removal position 
                for (int index = start; index < search.Length; ++index)
                {
                    var visit = search[index];

                    //Not parentheses
                    bool isParenthese = visit == '(' || visit == ')';
                    if (!isParenthese)
                    {
                        continue;
                    }                                        

                    // remove visit char from the string
                    //var skipCurrent = search.Substring(0, index) + search.Substring(index + 1);
     var skipCurrent = search.Remove(index, 1);
     
                    //Check the string is valid
                    if (IsValidParentheses(skipCurrent))
                    {
                        set.Add(skipCurrent);
                        continue; // continue to iterate all index positions 
                    }

                    // think about test case: ())(() -> minimum is to remove two parentheses
                    // Strings with one char removed are not working, then BFS goes to second remove
                    // Four strings will be in the queue. 
                    // "))(()", 0
                    // "()(()", 1
                    // "()(()", 2
                    // "())()", 3
                    // "())()", 4 
                    // "())((", 5    
                    if (set.Count == 0)
                    {
                        queue.Enqueue(new Tuple<string, int>(skipCurrent, index));
                    }
                }
            }

            return set.ToList();
        }

        /// <summary>
        /// test case: 
        /// "()","(())", "()()"  true
        /// ")(","())"  false
        /// Time complexity: O(N)
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool IsValidParentheses(String s)
        {
            int count = 0;
            for (int i = 0; i < s.Length; ++i)
            {
                var visit = s[i];
                var isOpen = visit == '(';
                var isClose = visit == ')';

                if (isOpen)
                {
                    ++count;
                }

                if (isClose)
                {
                    bool noOpenToMatch = count <= 0;

                    if (noOpenToMatch)
                    {
                        return false;
                    }

                    count--;
                }
            }

            return count == 0;
        }
    }
}


Friday, August 23, 2019

33. Search in Rotated Sorted Array

I wrote a post and shared my practice.

C# introduce middle -1 and middle + 1 practice in August 23, 2019

Here is the link.

I am searching good ideas to practice. What I think is to write excecutable code for all kinds of ideas, and make it work first; Do not have bias on ideas, do not memorize the solution.
It is fine not coming out optimal solution. The following solution is hard to write compared to the one I wrote in August 22, 2019, avoid middle + 1 or middle -1. Here is the link.
Case study - given array [3, 1], target = 1
I like to write a case study on [3, 1], target = 1.
So first search, start = 0, end = 1;
middle = 0;
middle index position divides the array into two ranges.
First one is [start, middle - 1], [0,-1], the range is not existing.
Second one is [middle + 1, end], [1, 1], one node is in the range.
First one is not existing. So second one is in ascending order.
So numbers[1] = 1, comparing to target 1, the target is found.
Case study - given array [4, 5, 6, 7, 0, 1, 2], target = 3
I like to write a case study on [4, 5, 6, 7, 0, 1, 2], target = 3.
So first search, start = 0, end = 6;
middle = start + (end - start)/ 2 = 3;
middle index position divides the array into two ranges.
First one is [start, middle - 1], or [0,2], numbers in the range are {4, 5, 6}.
Second one is [middle + 1, end], or [4, 6], numbers in the range are {0, 1, 2}.
First one is in ascending order, target value 3 is not in the range [4,6]. So next search area is start = 4, end = 6, or the array {0, 1, 2}.
middle = start + (end - start)/2 = 5.
two ranges to consider, left one is [4, 4], or array {0}, it is in ascending order, target is not in. So next search area is [6,6], or array {2}.
I like to write some case studies since I learn that algorithm practice without getting hands dirty on concrete example is too risky. I should carefully consider what to choose, how to design, but my goal is to make any idea I thought about reality. Therefore, I can challenge myself to build strength as a problem solver.
Case study - given array [2], target = 3
The reason I like to do a case study is that I came cross TLE error. The base case should include the case, array with one number, but not target value.
What I like to do is to go over my design of diving into two halves, why it is not working for this case.
Array: [2], target = 3
start = 0, end = 0.
middle = start + (end - start)/2 = 0.
so left half [start, middle - 1], or [0, -1], not existed at all.
right half [middle + 1, end], or [1, 0], not existed at all.
Combining the above two cases, there is no work done to handle this case. That is the reason a new base should be added to handle it instead.
// Avoid time limit exceeded bug
if (start == end)
return -1;
Things get complicated?
Because I like to introduce middle - 1 and middle + 1 in binary search, I create extra tasks for me to handle. I also should go over a check list based on common mistakes to help me make the idea work perfectly. Just be patient, and work on a simple test case like given an array [2], target = 3.
Here are highlights:
  1. Use depth first search, middle is base case; one iteration at least one value will be get rid of, so there is no deadlock.
  2. Use middle position to divide into two ranges, [start, middle - 1], [middle + 1, end], the left range or right range may not exist at all, since middle - 1 < start may be true.
  3. Add constraint check in case of index-out-range error, (middle - 1) >= start for leftAsc;
  4. Add constraint check in case of index-out-range error, (middle + 1 <= end) for rightAsc
  5. I ran into Leetcode online judge TLE error, test case [4, 5, 6, 7, 0, 1, 2], target 3, so I added two more lines of code to avoid TLE; If the range is 1, return -1. The first of 193 cases is failed.
    if(start == end)
   return -1;
The following code passes online judge.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _33_Rotated_sorted_Array___Catchup
{
    class Program
    {
        static void Main(string[] args)
        {
            RunTestcase(); 
        }

        /// <summary>
        ///  TLE - time limit exceeded 
        /// </summary>
        public static void RunTestcase()
        {
            var result = Search(new int[] {4, 5, 6, 7, 0, 1, 2}, 3);
        }

        /// modified binary search 
        public static int Search(int[] numbers, int target)
        {
            if (numbers == null || numbers.Length == 0)
                return -1;

            var start = 0;
            var end = numbers.Length - 1;

            while (start <= end)
            {
                var middle = start + (end - start) / 2;
                var middleValue = numbers[middle];

                if (middleValue == target)
                    return middle;

                // Avoid time limit exceeded bug
                if (start == end)
                    return -1; 

                // two range [start, middle - 1], [middle + 1, end]
                // range can be one value only   
                // Range definition should be added
                var leftAsc  = (middle - 1) >= start && numbers[middle - 1] >= numbers[start]; 
                var rightAsc = (middle + 1 <= end) && numbers[end] >= numbers[middle + 1];

                // missing cases
                if (leftAsc)
                {
                    if (isInRange(target, new int[] { numbers[start], numbers[middle - 1] }))
                    {
                        end = middle - 1;
                    }
                    else
                    {
                        start = middle + 1; 
                    }
                }
                else if (rightAsc)
                {
                    if (isInRange(target, new int[] { numbers[middle + 1], numbers[end] }))
                    {
                        start = middle + 1;
                    }
                    else
                    {
                        end = middle - 1; 
                    }
                }
            }

            return -1;
        }

        private static bool isInRange(int target, int[] range)
        {
            return target >= range[0] && target <= range[1];
        }
    }
}
C# various practices in 2019, here is the link.