2

I can do it in only O(k) time can someone be that kind to help me. I can not use build in functions.

def potnr(a, b):
    rez = 1
    while b>0:
        if b%2:
            rez = rez * a

        b = b // 2
        a = a * a
        
    return rez

def liczba(n, m):
    k = 1
    while potnr(n, k) < m:
        k += 1

    return k

print(liczba(2, 16))

I can do it in only O(k) time can someone be that kind to help me

logyka
  • 21
  • 3
  • 1
    First idea that comes to my mind would be to use some dichotomy algorithm: calculate n^2, n^4, n^8 until you pass over m, then track k between the last 2 powers by dichotomy. I didn't do the actual maths, but I think it should work. Edit: just did some quick mental calculations; if I'm not mistaken, it should be about 2*log2(k). – Swifty Nov 17 '22 at 22:53

3 Answers3

3

n^k >= m if and only if k >= log m base n

Since log m base n = log m / log n, this is as simple as:

from math import log, ceil
def smallest_k(n, m):
    return ceil(log(m)/log(n))

This runs in O(1) time.

QWERTYL
  • 1,355
  • 1
  • 7
  • 11
1

This one should work (I just fixed the value of k returned, for there was no guarantee it was the smallest value with the previous return):

import math
def min_power(n,m):
    b=1
    while n**b < m:
        b *= 2
    a = b/2
    while b-a > 1:
        c = (a+b)/2
        if n**c < m:
            a = c
        else:
            b = c
    k = math.ceil(a)
    return k if (n**k >= m) else k+1

min_power(35,10**250)
# Out[23]: 162
Swifty
  • 2,630
  • 2
  • 3
  • 21
  • The question mentions natural numbers, so using non-integers is against the spirit of the challenge. I also suspect you need to check `b±1` before returning `b` just to protect from round-off errors. – anatolyg Nov 17 '22 at 23:46
  • Well about non-integer exponents, it's not a big deal; rounding c would take care of that without impacting the efficiency of the code (I didn't bother to do it for that very reason). As for the return, I totally agree; I rushed the "ending" because I was tired, but I'll fix it right now. – Swifty Nov 18 '22 at 15:55
0

First determine any natural number k for which n ^ k >= m. Then refine your estimate to find the smallest such k.

It's easiest to find the initial estimate for k as a power of 2. Have a temporary value which holds n ^ k. Start from k = 1, repeatedly multiply k by 2, and square your temporary variable, until your k is sufficiently big.

Your real k will be greater than half the estimate you found. Numbers in that range have log2(k) bits. Check each bit, starting from the most significant one. For each such bit, calculate n ^ k for two values of k: with that bit equal to 0 and 1. Compare with m - this will tell you the value of that bit. Proceed to lower-significant bits, until you get to bit 0 (least significant bit).

I am not sure you are allowed to assume that calculating n ^ k has O(1) complexity. If not, you have to store intermediate results for all n ^ k calculations at first stage, or alternatively, use sqrt to calculate lesser powers of n.

anatolyg
  • 26,506
  • 9
  • 60
  • 134