Find element position in given monotonic sequence in Python


Suppose we have a number l and a monotonic increasing sequence f(m), where f(m) = am + bm [log2(m)] + cm^3 and (a = 1, 2, 3, …), (b = 1, 2, 3, …), (c = 0, 1, 2, 3, …)

Here [log2(m)] is the log to the base 2 and round the value down. so,

if m = 1, the value is 0.

if m = 2-3, the value is 1.

if m = 4-7, the value is 2.

if m = 8-15, the value is 3. and so, on

we have to find the value m such that f(m) = l, if l is not present in the sequence then we have to print 0. We have to keep in mind that values are in such a way that they can be represented in 64 bits and the three integers a, b and c less than or equal to 100.

So, if the input is like a = 2, b = 1, c = 1, l = 12168587437017, then the output will be 23001 as f(23001) = 12168587437017

To solve this, we will follow these steps −

  • SMALLER_VAL := 1000000

  • LARGER_VAL := 1000000000000000

  • Define a function solve() . This will take a, b, c, n

  • ans := a * n

  • lg_val := the floor of log base 2 of n

  • ans := ans + b * n * lg_val

  • ans := ans + c * n^3

  • return ans

  • From the main method, do the following −

  • begin := 1

  • end := SMALLER_VAL

  • if c is same as 0, then

    • end := LARGER_VAL

  • ans := 0

  • while begin <= end, do

    • mid :=(begin + end) / 2 (take integer part only)

    • val := solve(a, b, c, mid)

    • if val is same as k, then

      • ans := mid

      • come out from the loop

    • otherwise when val > k, then

      • end := mid - 1

    • otherwise,

      • begin := mid + 1

  • return ans

Example

Let us see the following implementation to get better understanding −

 Live Demo

from math import log2, floor
SMALLER_VAL = 1000000
LARGER_VAL = 1000000000000000
def solve(a, b, c, n) :
   ans = a * n
   lg_val = floor(log2(n))
   ans += b * n * lg_val
   ans += c * n**3
   return ans
def get_pos(a, b, c, k) :
   begin = 1
   end = SMALLER_VAL
   if (c == 0) :
      end = LARGER_VAL
   ans = 0
   while (begin <= end) :
      mid = (begin + end) // 2
      val = solve(a, b, c, mid)
      if (val == k) :
         ans = mid
         break
      elif (val > k) :
         end = mid - 1
      else :
         begin = mid + 1
   return ans
a = 2
b = 1
c = 1
k = 12168587437017
print(get_pos(a, b, c, k))

Input

2,1,1,12168587437017

Output

23001

Updated on: 25-Aug-2020

143 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements