Showing posts with label memoization. Show all posts
Showing posts with label memoization. Show all posts

Friday, May 12, 2017

Maximum Score - Rookie 3 (II)

May 12, 2017

Introduction 


It is a good idea to continue to work on maximum score algorithm, and also ask a question on code review. Learning memoization and bit mask is not an easy task, also Julia likes to learn the time complexity analysis algorithm better through the study.

Julia wrote a blog to document her learning experience on the algorithm, from the contest performance to after-contest catching up.


Code review preparation 



C# code in the contest is here. Score 3.5 of 35 points. 

May 12, 2017 11:16 pm 

Code review of C# code in the contest, and then move the memoization out-of-for-loop, scored 10.50 of 35 points. C# code is here.


Memoization Analysis Challenge


Instead of going over the recurrence formula, Julia likes to use an example to explain what can be in memoization. And what is her mistake in the contest? What is the reason causing the false analysis?

Suppose that the array has two numbers, int[] numbers = new int[]{1, 2}. The problem is to find the maximum sum such that the order of two numbers to put into scoring make the value maximum.

What is the subproblem of max score?

Guess what is the subproblem


May 13, 2017 11:03pm

First, add sum of the array. The array new int[]{1, 2}'s sum is 3.

To choose the last number, two options, either 1 or 2. If the last number is 1, array's index is 0, then the 0th score is (3 - 1) % 1 = 0. Next number is 2, sum is 0, and then the 1th score is 0 % 2 = 0. The sum of score values (0th, 1th) is 0.

In other case, if the last number is 2, array's index is 1, then the score is (3 - 2) % 2 = 1. Next number is 1, sum is 0, and then 0 % 1 = 0. The sum of score values is 1.

From the above two cases, the maximum score is 1 by taking 2 as last number and then taking 1 as the first number. Just remind friendly that the order is opposite from end to start.

The maximum value is to choose maximum value from a set with two values.

The memoization process is to record to Dictionary<string, int> calculated.
["0", 1]
["1", 0]
["", 1]


One more test case 


Suppose that the array has two numbers, int[] numbers = new int[]{1, 2, 1}.

Calculated variable as Dictionary<string, int> has the following:
[0 1, 0]
[0 2, 0]
[0, 1]
[1 2, 0]
[1, 0]
[2, 1]
[,1]

Debug the code, and check how many times the dictionary is looked up. 3 times.
key = "0 1", "0 2", "1 2".

Draw a recursion tree for this simple test case. Here is the graph:

Argument: If you can work on this simple test case and also work out the recursion tree correctly, then I believe that you can solve the problem using memoization and recursive, DP solution correctly as well.


Common advice




Do not memo one more item in one recursive call; Stay outside the for loop; Memo before return statement.

Julia, if you are very good at unit testing, and work on simple and very good test case in the design of algorithm, your performance on Hackerrank can improve at least 20%.

Make it all


It is the first challenge Julia worked on since last January on hackerrank, on the topic of bit mask, dp, memoization, subset. So she likes to make the algorithm everything. Learn one algorithm a time. Do not rush.

Julia likes to review a list of things on the algorithm. Bit mask, memoization, time complexity analysis.

Use bit mask, the code passes all test cases. 
C# practice code is here.


Hackerrank Editorial Notes


In order to write a good question on code review, Julia also have to write down some notes from editorial notes from hackerrank on the maximum score algorithm.

Here is the link of editorial notes.

Julia's note:
time complexity: O(2n * n)

Recursion tree - a major flaw, same recursive call many times; It results in exponential running time.


Actionable Items


Read book "Testable JavaScript" and then figure out a few things I can do in order to have a good sense of setting up test cases to help Hackerrank contest.

The algorithm is also on code review.stackexchange.com, the link is here.


Saturday, May 6, 2017

Max Score - RookieRank 3

May 6, 2017


Plan to work on the algorithm: Max Score in next 1 - 2 hours. Time is 5/6/2017, 12:53 pm.

Follow up 


May 7, 2017 9:20am

C# code in the contest is here, scored 3.5 out of 35.

Follow up 


Study the discussion about the solution, the link is here.

1. The following implementation uses memoization, backtracking, and backward processing:

C# practice code is here which passes all test cases.

2. Continue to work on my code submission, change the key of memoization, relax to the sum instead of the string concatenated by various array's element.
Score 14 out of 30, timeout test cases 7 - 10.
C# practice code is here.

3. Bit mask - pass all test cases
C# practice code is here.

Bit manipulation 4 things to review

1. Get integer 2i:
//use left shift i times,
bitToCheck = 1 <<  i

2. Check ith bit is 1:
// int bitmask
bitmask & bitToCheck

3. Get ith bit:
bitmask |= bitToCheck,

4. Unmask the ith bit:
// backtracking
bitmask &= ~bitToCheck


4. Bit mask - replace the integer using int[], size of array is 20.
May 11, 2017
Timeout on test cases from 6 to 10. Score 10.50 out of 30.
C# practice code is here.
string.Join(",", bitmask) takes too much time.

Julia learned the lesson. Take some time to write bit manipulation instead of using int[]. Bit manipulation expedites the process, use int instead of int[].

5. Continued to work on code written in the contest,
May 12, 2017 11:11 pm
C# practice code is here. Score 10.50, pass test case 0 - 5, and timeout on test case 6 - 10.

Learn when to do memorization, it should be out-of-for-loop, memo on the used HashSet<int>, actually encode all used indexes of the array to a string. Move the memoization from inside for-loop to outside for-loop.

Algorithm analysis


It is most important to come out the recurrence formula for the algorithm. Try to work backwards instead of starting from the first number and forward.

The maximum score of k problem can be solved by choosing any number as the last kth number, and then work on the maximum score of k - 1 problem. Use bitmask as key to do memoization.


Actionable Items


Review previous practice, and find some cases to use bitmask.

Top coder - fun with bits, the article link is here.

Take some notes:
Use bits of an integer to represent a set. Not only does it produce an order-of-magnitude improvement in both speed and size, it can often simplify code at the same time.

Go over the most popular set manipulations in the following:

Set union        
A | B

Set intersection
A & B

Set subtraction
A & ~B

Set negation
ALL_BITS ^ A

Set bit
A |= 1 << bit

Clear bit
A &= ~(1 << bit)

Test bit
(A & 1 << bit) != 0

Extracting every last bit

Counting out the bits

2. Hackerearth.com dynamic programming and bit masking, article link is here.

Thursday, June 25, 2015

Cache design, dynamic programming - matrix region sum

June 25, 2015

Introduction

It is my firs time to read the algorithm and I am so surprised to learn the algorithm. I love the learning and also very happy to read the blog with good and very clear explanation of the algorithm.

Problem statement:
Given the integer matrix, top left and bottom right coordinates of the rectangular region, calculate the region sum.
Here is one of blogs I like to read and share. 

Make it more time efficient


Naive solution, O(n x m) calculation of addition to get the sum. How to get it as O(1) using cache, how big the cache space?
Naive way to design the cache, it takes O( n2 x m2) space. The efficient way is O(n x m), using dynamic programming.
Share the practice C# code, here is the link.