0

The problem: There is a list of positive integers where the elements are unique and monotonically increasing. The list is s. For example s=[1,2,3,4,5,6,7,8,9,10]. The length of the list is n. The goal is to find the total number of ordered pairs (L, W) where L and W are in s that satisfies L*W <= a

The solution of the problem seems straight forward, yet I cannot figure out how did I do it wrong. This was an online assessment problem and I have failed already. If someone can tell me how did I fail, I will be very happy.

The approach is straight forward: for each possible L, find an upper bound of W in s using binary search. My code using Python:

def configurationCount(n, s, a):
    # n is the length of s.
    num_ways = 0
    # Consider every L.
    for i in range(n):
        L = s[i]
        goal = a//L
        
        # Binary search for this upper bound in s.
        i = 0
        j = len(s) - 1
        mid = (i+j)//2
        exact_match = False
        valid = False
        cursor = -1
        while(i<=j):
            if goal > s[mid]:
                i = mid+1
                cursor = mid
                mid = (i+j)//2
            elif goal < s[mid]:
                j = mid - 1
                cursor = mid
                mid = (i+j)//2
            else:
                exact_match = True
                cursor = mid
                break
            
        if cursor in range(n) and L*s[cursor]<=a:
            valid = True    
        if cursor in range(n) and valid:
            num_ways += (cursor + 1)

            
    return num_ways

This code only gave one correct output for one test case, but failed for the other 10 test cases. In one case where I could see that my out put was wrong, the correct output was more than 2000, where mine was about 1200. So I probably did not count some cases. Yet this approach seems so standard but how did I do it wrong?

  • Since this is an ordered list, you can take advantage of it using two pointers from either end and increment and decrement as required. i.e. if `W > a/L`, then decrement the `W` index. Else keep incrementing the `L` index till `L <= W`. – m_vemuri Apr 08 '22 at 05:19
  • Thanks! This is a good method. I wish I could come up with it. But it does not explain how did I do it wrong...I noticed that I probably should not use the variable i in the binary search because i is used as the outer loop's index, but this should not cause the bug because range (as far as I know) will always assign a corrected version of i at the beginning of each iteration. – aCertainNewUser Apr 08 '22 at 05:28
  • @aCertainNewUser, You are right about the range part, Do you have the test cases for the assessment, I have got correct results for the small use case (n<8). – Devesh Apr 08 '22 at 05:31
  • @DeveshShukla, the assessment used a procedurally generated list, which I am not sure if I am allowed to share the details. I guess all I can say is that s[0]=9507446, n=100, s[i] = ((279028249*s[i-1]+366009408)%10000000)+1+s[i-1] for other i values and a=37537747383873671. The length of the list is 100 I just tried the brute force method on this test case, the output is 2227 while the code above gives 1242. – aCertainNewUser Apr 08 '22 at 05:49
  • Found the problem. The cursor variable could end up at two possible positions, one of which is not desirable. If the cursor is at the undesirable position, just cursor-=1. Just added three lines of code and got the correct results. Such a shame. I bet such a pitfall is already known to more experienced ones. – aCertainNewUser Apr 08 '22 at 06:39
  • Correct, I just found out the same, Problem is if the cursor is set to the higher index the check condition **cursor in range(n) and L*s[cursor]<=a** is false and the count for this iteration never goes into the total. It took me some time to find out and to that here are my suggestions: 1) You should leverage the suggestion by @m_vemuri, 2) if you want to continue with your code, make another function for binary search which returns count and add it to total. This way you split code into smaller chunks and is easier to debug. – Devesh Apr 08 '22 at 06:45
  • @Devesh, thanks friend. I do agree m_vemuri 's solution is better. I am just not so confident that I can come up with something perfect like that in a stressful time-limited environment. Especially when the approach that I can easily come up with can end up with having this kind of bugs. I mean, if I had ever used a binary search approach to look for a specific location to insert an element, this should not happen. This is such a good experience. Too bad it happens after the assessment. – aCertainNewUser Apr 08 '22 at 06:58

0 Answers0