Sunday, May 19, 2019

Dutch National Flag Partitioning

Dutch National Flag Partitioning

Problem Statement

Partitioning is a common process used in other algorithms such a quicksort. In this problem, we are given an Array A and an index i. We have to rearrange A such that , all elements less than A[i] appears first followed by all elements equal to A[i] followed by all elements greater than A[i]. 

Problem Solving

  • Not lying but since I have done such a problem sometime in past, this has quickly led me to think of using iterators that spans 3 ranges of less than, equal to and greater than values. 
  • However the first question is to where to position each initially. 
  • First I thought of positioning them at begin and end -1 position, but just initializing them there because we do not have other option is breaking the invariant that at any time those iterator should point to correct values. 
  • Also there can be a case where all values are same then there would be no point in doing anything. 
  • This also means that we should skip the part that is correct and hence post skipping we could arrive at the correct iterator location. 
  • So first iterate from both ends and get to a location for both iterators where they are in accordance with the arrangement that left iterator has values less than A[i] and the right one has values greater than A[i] 
  • when this process ends we would reach the exact range we need to actually rearrange and bonus point if there is no range left to process. 
  • Once we reach this range. We need to create another iterator that starts at begin + 1, to iterate till right iterator. 
  • at every point we check if the iterator is less than A[i] then we swap it with left itr and increment left itr and similarly if it is greater than A[i] then we swap it with right itr.
  • And yes that should do it. 
  • It should also be able to handle cases where all values fall into one range, since that we would skip at the beginning only.
  • I wrote it, it failed and corrected it and ran correctly then. 
  • Find Code here.

Learning  

  • Never doubt yourself In the first attempt the answer came out wrong and I immediately jumped to the conclusion that the comparison mechanism is incorrect since I have recalled it from past memory. 
  • However it turns out that all that was missing was one more iteration that I did not perform. 
  • This also makes me aware of the fact whenever we talk about iteration we need to be accurate about what are iteration limits. 
  • The complexity for this solution straight forward is constant since we are only swapping elements by traversing the array once and no extra memory is required. 
  • Also I learned the best way to swap elements of iterators are iter_swap a built in function in algorithms library. 
  • Hmm.. simple one but panic caused a lot of time waste.   

Monday, May 6, 2019

Cops and the Thief Devu

Cops and the Thief Devu

Link here.
There are 100 houses located on a straight line. The first house is numbered 1 and the last one is numbered 100. Some M houses out of these 100 are occupied by cops.
Thief Devu has just stolen PeePee's bag and is looking for a house to hide in.
PeePee uses fast 4G Internet and sends the message to all the cops that a thief named Devu has just stolen her bag and ran into some house.
Devu knows that the cops run at a maximum speed of x houses per minute in a straight line and they will search for a maximum of y minutes. Devu wants to know how many houses are safe for him to escape from the cops. Help him in getting this information.

Input

First line contains T, the number of test cases to follow.
First line of each test case contains 3 space separated integers: M, x and y.
For each test case, the second line contains M space separated integers which represent the house numbers where the cops are residing.

Output

For each test case, output a single line containing the number of houses which are safe to hide from cops.

Constraints

  • 1 ≤ T ≤ 104
  • 1 ≤ x, y, M ≤ 10

Example

Input:
3
4 7 8
12 52 56 8
2 10 2
21 75
2 5 8
10 51

Output:
0
18
9

Explanation

Example 1 : Cops in house 12 can cover houses 1 to 68, and cops in house 52 can cover the rest of the houses. So, there is no safe house.
Example 2 : Cops in house 21 can cover houses 1 to 41, and cops in house 75 can cover houses 55 to 95, leaving houses numbered 42 to 54, and 96 to 100 safe. So, in total 18 houses are safe.

Problem Solving

  • First thing to notice is that it's a range problem. Given a range 1-100 we have to subtract ranges.
  • Simple math tells us that for every Mi range for that cop is i +- x * y. Current position + (speed * time) (distance) the cop can cover.
  • Now we have 1-100 range and have to subtract all Mi ranges and leftover will be our answer. 
  • We need to calculate the total sum of ranges, excluding the overlaps and finally subtract the the total from 100, to get safe houses. 
  • I mistakenly read the problem to output the indexes of houses, however now thinking about it that would have been a different problem.
  • We can create a list of ranges and while adding a range to list merge the range if required to make a bigger range. Finally we can compute the total sum of the ranges in the list and subtract that from 100. 
  • Here to make a list we can use std::vector, to represent a range we can use std::pair 
  • Also while merging we need to search through all merges possible therefore if we can maintain a sorted list then the while merging we only have to check the last element. 
  • Therefore we have to sort the houses list first and then give it to adding range. 
  •  The submission went successful here.

Learning 

  • I have a feeling that we can still improve this complexity of mlogm, if we would know how to store ranges properly. 
  • May be in future we can study such  data structures. 
  • We also used a built in sorting function which currently we have not implemented, so going forward we need to learn about sorting. 
  • Since in the certification course all sample problems are done, I would pick up problems from "Elements of Programming Interview" to cover more array and vector problems. 
 

Sunday, May 5, 2019

Chef and Rainbow Array

Chef and Rainbow Array

Link to problem here.
Chef likes all arrays equally. But he likes some arrays more equally than others. In particular, he loves Rainbow Arrays.
An array is Rainbow if it has the following structure:
  • First a1 elements equal 1.
  • Next a2 elements equal 2.
  • Next a3 elements equal 3.
  • Next a4 elements equal 4.
  • Next a5 elements equal 5.
  • Next a6 elements equal 6.
  • Next a7 elements equal 7.
  • Next a6 elements equal 6.
  • Next a5 elements equal 5.
  • Next a4 elements equal 4.
  • Next a3 elements equal 3.
  • Next a2 elements equal 2.
  • Next a1 elements equal 1.
  • ai can be any non-zero positive integer.
  • There are no other elements in array.

Help Chef in finding out if the given array is a Rainbow Array or not.

Input

  • The first line of the input contains an integer T denoting the number of test cases.
  • The first line of each test case contains an integer N, denoting the number of elements in the given array.
  • The second line contains N space-separated integers A1, A2, ..., AN denoting the elements of array.

Output

  • For each test case, output a line containing "yes" or "no" (without quotes) corresponding to the case if the array is rainbow array or not.

Constraints

  • 1 ≤ T ≤ 100
  • 7 ≤ N ≤ 100
  • 1 ≤ Ai ≤ 10

Subtasks

  • Subtask 1 (100 points) : Original constraints

Example

Input
3
19
1 2 3 4 4 5 6 6 6 7 6 6 6 5 4 4 3 2 1
14
1 2 3 4 5 6 7 6 5 4 3 2 1 1
13
1 2 3 4 5 6 8 6 5 4 3 2 1

Output
yes
no
no

Explanation

The first example satisfies all the conditions.
The second example has 1 element of value 1 at the beginning and 2 elements of value 1 at the end.
The third one has no elements with value 7 after elements with value 6.

Problem Solving 

  • This seems to be a palindrome problem. 
  • However this is incorrect, the input is mean to have increment by 1 at each step.
  • Following from that one can clearly see that the N should be odd to satisfy these properties. 
  • This gives us an early exit the range of values are small and we do not have to perform any operation other than comparison. So overflow is not possible.
  • For space we need to store at least half of the array before we can start comparing the other half.
  • A Stack looks to be more suitable for this problem. But we will implement an Stack later in syllabus under that section. 
  • We can also carefully implement this recursively and use the native stack space instead of allocating memory ourselves. 
  • One more issue here is that the size of the array should be decided at run time, which our array cannot do so we have to use a vector data structure, as discussed in previous post.
  • Okay, So the submission went unsuccessful here. 
  • It gives TLE, that means there is unseen problem that I have missed. 
  • Okay so I found the glitch and solved it here, The problem was we were contructing the vector with N/2 capacity but then pushing back instead of using the allocated memory which for bigger inputs caused bad::alloc(). However it now says Wrong Answer. 
  • Okay realized that we can ignore N < 3. checking for more ideas.
  • Okay so misinterpreted the problem itself, the numbers appears to have meant that the numbers should grow up to 7 and come back to 1. In our case we just checked whether the numbers are increasing first and then decreasing to form a palindrome. 
  • Okay so I submitted another solution which passed half of the task, one still remaining. I just capped my approach up to 7. Submission here. 
  • Also that N < 3 should be changed to N < 13. Submission here
  • After successive failures and beating up confidence to this "CAKEWALK" difficulty, I thought that I am just trying to fix my solution even after the original solution I wrote was thinking about misinterpreted problem. 
  • So I wrote from scratch again, this time I created state machines, basically two functions one which validates increasing values till mid array and the other which validates decreasing through rest of the array. Through the traversal we keep the count of 1-7 numbers and while decreasing we keep decrement the count so that while changing the number or in the end the count should be 0. 
  • Also learned, that std::array does not create zero initialized array - use array.fill to do that. here
  • After few off by 1 errors and edge cases, this submission went through here. 
  • Also learned that premature optimizations really bite in the ass if you are actively modifying the code. 
  • This problem was easy to think, difficult to code and hard to interpret correctly. 
  • In the end, this problem was easily solved by arrays only no vector required.



Saturday, May 4, 2019

Vectors

Vectors

Just like arrays, vectors use contiguous storage locations for their elements, which means that their elements can also be accessed using offsets on regular pointers to its elements, and just as efficiently as in arrays. But unlike arrays, their size can change dynamically, with their storage being handled automatically by the container.

Usage 

  • Store any type of data 
  • Insert in amortized O(1)
  • Remove in O(1) 
  • Access in O(1)
  • Size not known at compile time

Note

  • Since vectors are more suitable to situations instead of arrays they are extensively used in all applications. 
  • Vectors in java implements List interface and are synchronized.
  • Vectors in C++ are sequence container. 

Vector Implementation


  • The following implementation let's us create a vector with any int size.
  • Default constructor creates a vector of size 2. 
  • The container provides options to access and iterator to traverse the vector. 
  • The container also provides push_back to add elements at the end of current last element. 
  • The container also provide direct access to front and back elements 
  • On Push back of the last element the container resizes to twice the capacity. It allocates new memory then copies original content swap unique pointers and reset the raw pointers. The local unique pointer variable goes out of scope and hence deletes the previous allocated memory. 
  • The container also shrinks when the usage drops below half the current capacity.
  • Since the vector internally allocates C array the memory allocated is contiguous.

Learning 

  • C++ Vectors also have emplace_back function which leverages rvalue references to forward parameters to the container instead of creating temporaries like push_back. Read here
  • Vector<bool> is a specialized version of vector and is not recommended to be used in Google Style guide. Read here
  • std::swap is specialized for unique_ptr Read here. 
  • std::vector also have overloaded operators  like equality and comparison. Read here
  • One important question to answer is what's the complexity of inserting in a vector. 

Insert Complexity

  • Now vectors have 2 main insert operations an inexpensive one and an expensive one. 
  • If we always consider the worst case scenario as in terms of Big O, the expensive operation have order O(n) complexity and since we insert n5 elements the overall worst case analysis shows that complexity will be O (n^2). 
  • However this is not true as the number of expensive operations does cannot occur on every insert. 
  • Since the number of inexpensive operation increases and are often more than the number of expensive operation , we need to analyze this differently. 
  • Amortized analysis is complexity analysis over a range of operations rather a single operation. 
  • In this scenario, an amortized analysis means than while inserting n elements what is the overall cost of single insert operation. 
  • Now if we see, there are two operations one inexpensive i.e O(1) when we  do not expand the vector, the other is expensive one where we allocate new memory and the copy the original elements to new memory taking O(2 ^ k) operations, where k is an intermediate value < n. 
  • For reason that expand only happens on 2^k + 1 elements, 
  • Therefore total number of operations = num of inexpensive operations * cost of light operations + num of expensive operations * cost of expensive operations. 
  • Number of expensive operations = (2 + 4 + 8 + 16 ... + 2 ^ l) where l is the largest integer such that 2^l + 1 < n. 
  • if we look at it the other way say n is the final size of the vector, therefore this expensive operations will occur n/2 + n /4 + n/ 8 + n/16 + ... + 1 which is almost equal to twice 2n. here
  • Therefore the total operations will be somewhere n + 2n = 3n. 
  • Dividing this by total number of inserts gives us a constant 3 .
  • Therefore the amortized complexity  of inserting in a vector is O(1) .


Monday, April 29, 2019

The Minimum Number Of Moves

The Minimum Number Of Moves

Little chief has his own restaurant in the city. There are N workers there. Each worker has his own salary. The salary of the i-th worker equals to Wi (i = 1, 2, ..., N). Once, chief decided to equalize all workers, that is, he wants to make salaries of all workers to be equal. But for this goal he can use only one operation: choose some worker and increase by 1 salary of each worker, except the salary of the chosen worker. In other words, the chosen worker is the loser, who will be the only worker, whose salary will be not increased during this particular operation. But loser-worker can be different for different operations, of course. Chief can use this operation as many times as he wants. But he is a busy man. That's why he wants to minimize the total number of operations needed to equalize all workers. Your task is to find this number.

Input

The first line of the input contains an integer T denoting the number of test cases. The description of T test cases follows. The first line of each test case contains a single integer N denoting the number of workers. The second line contains N space-separated integers W1, W2, ..., WN denoting the salaries of the workers.

Output

For each test case, output a single line containing the minimum number of operations needed to equalize all workers.

Constraints

  • 1 ≤ T ≤ 100
  • 1 ≤ N ≤ 100
  • 0 ≤ Wi ≤ 10000 (104)

Example

Input:
2
3
1 2 3
2
42 42

Output:
3
0

Explanation

Example Case 1. Chief can equalize all salaries in 3 turns:
Turn ID IDs of involved workers Salaries after the move
1 1 2 2 3 3
2 1 2 3 4 3
3 1 3 4 4 4


Problem Solving

  1. This problem took me some time to grasp. Do not think otherwise but the issue here is that I did jump on solving the solution, however first I wanted to formally convince myself that a solution to this problem exists.
  2. Turns out that no one on the editorial or discussion have answered this issue. How do I know that in any configuration of W there will exist a solution where are salaries will be equal after performing the mentioned operation multiple times. 
  3. So to do that I thought of using induction, Clearly if f -> true when the solution to problem exists then f(1) is always true, because for 1 worker all salaries are already equal & number of operations are also = 0. 
  4. Thinking about f(2), if there are only 2 workers and since this operation always increases the value therefore the min moves would be to make the salary of the lesser worker equal to the worker whose salary is more i.e (Max(W[])-Min(W[])) number of moves. and also that the solution does exists. 
  5. So lets assume that f(k) -> true. with some X operations. 
  6. If we can argue that f(k + 1)  is also true then we would conclusively prove that a solution to this problem exists for every k >0.
  7. Now for f(k+1) out of k + 1 lets partition them in 2 groups of k say G1 and  1 say G2, such that the group G2 has only one element which is the max element of all k + 1 elements, 
  8. Now the group G1 is solvable by induction hypothesis - (5) by X operations. 
  9. That means that the after performing X operations in all k+1 elements where we always choose candidate for operation from group G1, the final value of G2 would be value of G2 elements + X. (since each operation will expand the G2 group by 1. 
  10. Now the final configuration after X operations would be that all salaries in G1 group would be equal say equal to E and G2 group salary would be increased by X. 
  11. Finally we can perform X - E operations by always selecting G2 candidate and so that G2 candidate never increases and the rest in  G1 which were equal already would all increase to be equal to G2. 
  12. Therefore all salaries can be made equal. QED 
  13. So I convinced myself that a problem can be solved. 
  14. Now for the number of operations, also took sometime to ponder, If the only operation is increase all but one, that means that the minimum number of the set should dictate the number of operations. 
  15. Doing sample examples would show that keeping max as the candidate and pulling up all the rest will yield the min number of operations. 
  16. Now this is tricky to imagine but if you pull up your min to the successor on the min value, then we have a case just like in the proof, where we try to make all other equal and then finally we can just move all except for the one that is max. So we can try pulling up min to the next min in every iteration. 
  17. This operation sequence will give us the min operations required. 
  18. However instead of modelling this behavior, one can calculate how many operations does that mean. 
  19. That means that in each iteration I make min equal to a next element therefore for every element this happens equal to the difference to the min value. 
  20. Therefore E (0,n) (Wi - min(w)) is the answer. 
  • For implementation 
  • we can see that most variables are in int range and the summation would max to 10^4 * 100 = 10 ^ 6 which is also integer range. so no overflow requirements. 
  • Next we see that we can find the summation and min elements in one scan of the input and the compute the answer so time can be O(1) and space also O(1).  
  • No extra edge cases here. 
  • The submission went successful here . 

Learning 

  • Proof by induction was the best thing about this problem solving. The ability to convince oneself that yes there is a solution is great, also it provides insights to solve the actual problem.
  • The problem can seem much easier if one thinks in a relative aspect. Since the only thing that matters is that all salaries become equal so the operation can also be thought of pushing one salary down each time instead of pulling all salaries except for one. In relative terms these are the same thing. 
  • The relative aspect is great but to get the final salary, it becomes is difficult. 
  • The final salary in the above approach is easy to think as min + number of total operations. (since in each operation the min have always increased, and the min was never a candidate to not increase the salary, the final = min + num of operations) 
  • This problem was of cake walk difficulty, however it took me some time to ponder on the details. A lot of time compared to time requirements  of competitive programming. 
  • This however should not sadden me, as my goal here is to learn and solve everything instead solve it fast. 
  • Let's see what other problems have to offer. :)


Thursday, April 25, 2019

Chef and Notebooks

Problem Statement 

The link to problem is here.  

Chef likes to write poetry. Today, he has decided to write a X pages long poetry, but unfortunately his notebook has only Y pages left in it. Thus he decided to buy a new CHEFMATE notebook and went to the stationary shop. Shopkeeper showed him some N notebooks, where the number of pages and price of the ith one are Pi pages and Ci rubles respectively. Chef has spent some money preparing for Ksen's birthday, and then he has only K rubles left for now.
Chef wants to buy a single notebook such that the price of the notebook should not exceed his budget and he is able to complete his poetry.
Help Chef accomplishing this task. You just need to tell him whether he can buy such a notebook or not. Note that Chef can use all of the Y pages in the current notebook, and Chef can buy only one notebook because Chef doesn't want to use many notebooks.

Input

The first line of input contains an integer T, denoting the number of test cases. Then T test cases are follow.
The first line of each test case contains four space-separated integers X, Y, K and N, described in the statement. The ith line of the next N lines contains two space-separated integers Pi and Ci, denoting the number of pages and price of the ith notebook respectively.

Output

For each test case, Print "LuckyChef" if Chef can select such a notebook, otherwise print "UnluckyChef" (quotes for clarity).

Constraints and Subtasks

  • 1 ≤ T ≤ 105
  • 1 ≤ Y < X ≤ 103
  • 1 ≤ K ≤ 103
  • 1 ≤ N ≤ 105
  • 1 ≤ Pi, Ci ≤ 103

Subtask 1: 40 points
  • Sum of N over all test cases in one test file does not exceed 104.

Subtask 2: 60 points
  • Sum of N over all test cases in one test file does not exceed 106.

Sample

Input
3
3 1 2 2
3 4
2 2    
3 1 2 2
2 3
2 3    
3 1 2 2
1 1
1 2

Output
LuckyChef
UnluckyChef
UnluckyChef

Explanation

Example case 1. In this case, Chef wants to write X = 3 pages long poetry, but his notebook has only Y = 1 page. And his budget is K = 2 rubles, and there are N = 2 notebooks in the shop. The first notebook has P1 = 3 pages, but Chef cannot buy it, because its price is C1 = 4 rubles. The second notebook has P2 = 2 pages, and its price is C2 = 2 rubles. Thus Chef can select the second notebook to accomplish the task. He will write 1 page of poetry in the old notebook, and 2 page of poetry in the new notebook.
Example case 2. Chef cannot buy any notebook, because the prices exceed the Chef's budget.
Example case 3. No notebook contains sufficient number of pages required to write poetry.

Problem Solving

  • The Chef's requirement Req= X - Y, no of pages required 
  • Since X > Y is given no need to check this condition
  •  The Solution is that out of all (P,C) if there exists a (P,C) such that P >= Req && C <=K then the chef can work else not, 
  • Note we should not worry about finding the optimal solution since the objective is only to find one solution but not the best one. 
  • Looking at limits of the inputs unsigned int is sufficient  
  • The submission is successful, here

Learning

  • This problem was not any different from the previous one. 
  • The only smart thing to do was to reduce the comparison operation by using a bool once the answer was found. 
  • Let's see if the next problem would be any different. 

Wednesday, April 24, 2019

Little Elephant and Candies

Little Elephant and Candies 

Intro 

The link to the problem is here. 

Problem Statement 

A Little Elephant and his friends from the Zoo of Lviv like candies very much.
There are N elephants in the Zoo. The elephant with number K (1 ≤ K ≤ N) will be happy if he receives at least AK candies. There are C candies in all in the Zoo.
The Zoo staff is interested in knowing whether it is possible to make all the N elephants happy by giving each elephant at least as many candies as he wants, that is, the Kth elephant should receive at least AK candies. Each candy can be given to only one elephant. Print Yes if it is possible and No otherwise.

Input

The first line of the input file contains an integer T, the number of test cases. T test cases follow. Each test case consists of exactly 2 lines. The first line of each test case contains two space separated integers N and C, the total number of elephants and the total number of candies in the Zoo respectively. The second line contains N space separated integers A1, A2, ..., AN.

Output

For each test case output exactly one line containing the string Yes if it possible to make all elephants happy and the string No otherwise. Output is case sensitive. So do not print YES or yes.

Constraints

1 ≤ T ≤ 1000
1 ≤ N ≤ 100
1 ≤ C ≤ 109
1 ≤ AK ≤ 10000, for K = 1, 2, ..., N

Example

Input:
2
2 3
1 1
3 7
4 2 2

Output:
Yes
No

Explanation

Case 1. We can give one candy to the first elephant and two candies to the second elephant and make them both happy. Hence the answer is Yes. Alternatively we can give one candy to each elephant and left one candy for ourselves but they again will be happy.
Case 2. Even if we give four candies to the first elephant and two candies to the second elephant we will have only one candy left and can not make last elephant happy since he needs two candies for his happiness. Hence the answer is No.


 Problem Solving

  • Since each elephant will be happy only when it receives Ak candies therefore the total candies required is a sum of all Ak for (1<k<N) and this sum should be less than C. 
  • From coding perspective all limits are trivial and if int is 4 bytes than all datatypes can be ints
  • But we need to think about integer overflow , since all A can be max 1000 and there can be max of 1000(N) of them  therefore the summation cannot be more than 10^6 which can also be accommodated in an unsigned int, so extra care required. 
  • Okay the submission went successful, here.

 Learning

  • There are few learning from this submission
  • First cin is slower than scanf which is slower than getchar which is slower than getchar_unlocked. Read about it here.  
  • One would be tempted to early exit when required candies are more than the C at input is yet to be processed. However this is futile as you anyways have to read all the inputs otherwise that input will be used by next test case. 
  • Also we avoided the use of array altogether by just summing up the numbers as they became available.