1

I tried to solve a question on HackerRank (Problem Link: https://www.hackerrank.com/challenges/mehta-and-his-laziness/problem) which involves calculating the number of even perfect square proper divisors of a given number N. The problem requires the program to calculate the probability of a divisor of a given number N being even perfect square among all of N's proper divisors.

For example, given N = 36, the set of proper divisors is {1,2,3,4,6,9,12,18}, and only 4 is an even perfect square. The probability will be 1/8.

Another example will be N = 900, there will be a total of 26 proper divisors and 3 of them {4,36,100} are even perfect square. The probability will be 3/26.

These 2 examples are taken from the problem description on HackerRank. I solved this problem and passed all tests but my solution is not optimal. So I read the "Smarter Strategy" mentioned in the editorial provided by HackerRank. I understood the theoretical explanation but I got really confused by the line

divisors[j] += divisors[j] / e

I don't know whether it is appropriate to copy and paste the explanation and full code here from the editorial on HackerRank (https://www.hackerrank.com/challenges/mehta-and-his-laziness/editorial) since it requires the user to log in first (can use Gmail, Facebook, GitHub and LinkedIn accounts) and unlock (no need to pay, it is free), so I just pasted the line that I got really confused. I hope someone can also access the editorial and answer my following questions.

I understand the explanations and codes of other solutions, but I just don't get why the update of the divisors list should be done in this way for this optimal method. divisors[j] is the value from the last cycle of the loop, how can this be used to calculate the divisors produced by the current prime number and specific exponent? I think that it /e instead of /(e+1) is because of the initialization of all 1s in the list (already counted the 1 being divisors of every number). Also, I think this method of update is related to avoid double-counting, but I really don't understand how this formula was derived?

For example, 36 = 2^2 * 3^2.

After loop 2^1, divisors[36] should be 2. Then after loop 2^2, divisors[36] should be 3 (2/2+2). After loop 3^1, divisors[36] should be 6 (3/1+3). And then after 3^2, divisors[36] should be 9 (6/2+6).

My guess is that after each loop the divisors is adding the possibilities of divisors caused by the current value, for example, in the 36 case:

val : divisors list
2^1 : {1,2}
2^2 : {1,2,4}
3^1 : {1,2,4,3,6,12}
3^2 : {1,2,4,3,6,12,9,18,36}

But I don't know how the formula was mathematically derived... Can anyone explain it to me? Thank you so much...

user299560
  • 15
  • 5
  • 1
    We can't reasonably answer questions about code that we can't see. Can you paste the relevant code into the question? – Mark Dickinson May 24 '20 at 14:02
  • I really want but it is in the editorial of the HackerRank, it requires the user to log in their website (can use Gmail, Facebook, GitHub. LinkedIn accounts) and unlock (no need to pay money, it is free). I don't know whether I can post it here directly, but can you try to click the link I provided and sign in to access the editorial? – user299560 May 24 '20 at 14:52
  • Also, how do you know your solution is not optimal? Your solution may be different *and* optimal. – President James K. Polk May 24 '20 at 14:52
  • @PresidentJameK.Polk Because the editorial provides different solutions, mine is the same as the one with time complexity O(N log N), while the optimal one's time complexity is better than this. – user299560 May 24 '20 at 14:56

1 Answers1

0

It is not clear about which formula you are talking about but if you are talking about how the list

  val : divisors list
  2^1 : {1,2}
  2^2 : {1,2,4}
  3^1 : {1,2,4,3,6,12}
  3^2 : {1,2,4,3,6,12,9,18,36}

was created then here is the answer your number is 36 = 22 * 3 2 and think you have a list A = {} which is empty initially and we will find all the divisors. At that point I think you know how the prime factorization was done. Now, from simple combinatorics you have three possible choice for 2 to include it in every divisors. Suppose you don't want to calculate the divisors that contains any number of 2 means you want 20=1 in

So, if you choose 20 and any number of 3 then you have the possible choice 20 * 30, 20 * 31, 20 * 32 So, for 20 and any number of 3: list contains: 20 * 30 = 1, 20 * 31 = 3, 20 * 32 = 9

So, A = {1, 3, 9}

Then you choose exactly 2 once and any number of 3 then you have the possible choice 21 * 30, 21 * 31, 21 * 32

for 21 and any number of 3:list contains: 21 * 30 = 2, 21 * 31 = 6,21 * 32 = 18

So, A = {1, 3, 9} U {2, 6, 18} = {1, 2, 3, 6, 9, 18} and continue for when 2 occurs twice. then you have all the divisors in the list.

This can be easily implemented using sieve.

rng70
  • 25
  • 9
  • Thank you for your answer, but this is not the question I am talking about... I understand this method and implemented it in the sieve, but the editorial (https://www.hackerrank.com/challenges/mehta-and-his-laziness/editorial) here further reduced this method and mentioned a better one in the "smarter strategy", it is the one with 2^e * p_2^e2...I also understand the text explanation of that part, but I don't understand how the line of code "divisors[j] += divisors[j] / e" is related to the theoretical explanation. – user299560 May 25 '20 at 18:12
  • you should paste the code segment here .. at least the function that contains the code segment.. I can't help you without seeing the codes you are talking about .. may be it is the part of precomputation that reduce the complexity...add code-segment in you qs. – rng70 May 25 '20 at 18:17
  • Because the code is inside the link that I provided...and it requires the user to log in to unlock. I don't know whether it is appropriate to share their code on another forum, but can you try the link I put in the last comment? The code is inside that link... Thank you.. – user299560 May 26 '20 at 04:26
  • I will try to give you answer after seeing the code when I will get time. But I appreciate your thinking, but most of the time you will find it inappropriate providing some link to other users and asking them to log in that site and then answering your question. – rng70 May 27 '20 at 11:33
  • Yes...I am sorry about that... I also asked the website whether it is okay for me to post the code here but they haven't replied to me yet...Once I got the permission I will post the full code here... Thank you all the time. – user299560 May 27 '20 at 14:34