Thursday, 30 April 2020

[issue with the question] Flatland Space Stations

Here is something rare. A question where the question setter does an oopsie in the testcases.

The solution to the intended question:
First of all to make our lives easier, let's sort the array containing the indices of cities containing space stations.
Let us think of this example (0 is a city without space station, 1 is with)

00001001000001000

We should find the number of zeroes between two 1's (let that be n) and then, by induction one can prove that the longest distance to a space station in that set of zeroes is ceil( (n - 1)/2 ). We will have to find the maximum among all such groups of zeroes between two 1's.

But what about the ends? The ends have to be dealt differently. For the ends, the number of zeroes from that end to the nearest one is equal to the largest distance. So we do that by comparing the maximum value we obtained before with the number of zeroes between the left end and the first 1, and the number of zeroes after the last 1 and the right end. The maximum out of these three will be the answer.

Type, type, type... hit submit! What happens? 4 testcases did not pass. Wrong Answer, it says. But then you spend some Hackos to look at the testcase after racking your brains for an hour, and you see this:
6 6
0 1 2 4 3 5

Wait, what? The question mentions that the cities are indexed 1 based! So the question is not perfect. The setter apparently forgot to make the testcases 1 based. After taking that into account, it works.

Monday, 27 April 2020

[Bitwise OR shenanigans] ACM ICPC Team

This question is really easy, but a little hitch stopped me on this one:

Bitwise OR in common programming languages:
| operator accepts two integers, converts them to binary, ORs them, and returns the result in decimal again.
If in a | b, a and b are given in binary, we need to add a "0b" before them. This is what I did not know.

I use Python3 for competitive coding, so for reference I shall add code to compare two integers which consist only of zeroes and ones

orint(a, 2) | int(a, 2)
orbin(or)[2:]

the first line converts a and b to integer and the second parameter "2" tells python that a is a string of zeroes and ones which is a binary number.
Hence a = "1001" yields 9.

or is set to a | b in DECIMAL system. The second line converts it to binary.
The [2:] tells python to skip the "0b". <== this is what isn't intuitive, and frankly, kind of sucks. But OK. One more thing to keep in mind!

Super Reduced String

Here, we go for a recursive solution.

Our function basically takes an every element (except the last one) of the string, and compares it to the one next to it.

If they are equal, delete both of them from the string

We are not done yet. We have only made one pass. This may generate a new string which may be further reducible. So we introduce a boolean variable "done" initialized as True right at the beginning of the function, before any other statement.

Whenever we find two adjacent elements being equal, we set the value of done = False. At the end of the function, we check if done is False. If it is false, we set

string = superReducedString(string) 

(recursion)

When the super reduced string is obtained, "done" will remain true. When done is true, return the string.

Strange Counter

After some observation by writing down a few cases, it becomes clear that
1 + 3(2n - 1) <= t
if we find n such that

n = floor(log2( (t - 1)/3 + 1 ))

1 + 3(2n - 1) is the cumulative time till latest counter.

then c = 3(2n - 1) gives us the value from which the latest counter will start counting (check this for a few cases to make it clear)

find the difference between the current time and 1 + 3(2n - 1). (to know how many steps to count down)
Subtract that difference from c and that is the answer

Sherlock and The Beast

The total number of digits (n) must be a linear multiple of 3 and 5, of form 3a + 5b = n where a is total number of 5's and b is total number of 3's. For the number to be largest possible, 'a' must be largest possible, so we can arrange 'a' 5's then remaining 'b' 3's and be done. Now, an upper bound on the number of 5's must be r= floor(n/3). the remaining digits are (b = n - r). If b % 5 == 0, then we are good! but if b % 5 != 0, then we must increment 'b' and decrement 'a' until either a == 0 without obtaining any "decent number" (as explained in question) where we return -1. If a "Decent number" exists, we shall obtain the correct distribution when both 'a' and 'b' become valid multiples of 3 and 5 respectively again. Return this number.

Halloween Sale

Algorithm:
1. Find n = floor((p - m)/d)
2. check if s - np + (n)(n - 1)(d/2) > 0
    this formula comes from observation of how much money we have with us after each purchase
    s, s - p, s - p + d, s - 2p + 3d, ...... , s - np + (n)(n - 1)(d/2)
    if this is > 0, that means even after the minimum price is reached, more items can be bought.
    now edge cases here are for the base cases (n = 1 and n = 0)
    the n = 0 edge case is when s < p (no items can be bought)
    the n = 1 edge case is when s - p < p - d (one item can be bought)
    these edge cases have to be separately dealt with, using if statements prior to step 2
3. if the answer to step 2 is yes, then
    s = s - np + (n)(n - 1)(d/2)
    n += floor(s/m)
 4. if the answer to step 2 is no, then we solve the quadratic equation:
     s - np + (n)(n - 1)(d/2) = 0
     to find the number of items we can buy, and then floor the result.
     I don't know why, but taking the smaller root worked, but not always the bigger root.
5. return n