-2

I am working through the Max Multiple challenge on Code Signal:

Given a divisor and a bound, find the largest integer N such that:

N is divisible by divisor. N is less than or equal to bound. N is greater than 0. It is guaranteed that such a number exists.

Example

For divisor = 3 and bound = 10, the output should be maxMultiple(divisor, bound) = 9.

The largest integer divisible by 3 and not larger than 10 is 9.

This is my attempt:

def maxMultiple(divisor, bound):

    largest = 0

    for i in range(0,bound):
        if i % divisor == 0 and i <= bound:
            largest = i

    print(largest)

It passes on most tests but fails on these ones:

Input: divisor: 8
       bound: 88
Output: null
Expected Output:88
Console Output:80
Input:divisor: 10
      bound: 100
Output: null
Expected Output: 100
Console Output: 90

I am checking for the constraints in my if statement but it fails on these two cases. I do not understand why.

Onur-Andros Ozbek
  • 2,998
  • 2
  • 29
  • 78
  • `range(0, bound)` goes from `0` to `bound - 1` – yedpodtrzitko May 03 '21 at 08:13
  • `range(0, bound)` only iterates up to `bound-1`... also you might want to consider iterating downwards and returning the first match instead to be more efficient – Nick May 03 '21 at 08:13
  • 1
    Why looping, what about bound - (bound % divisor)? – Rocco May 03 '21 at 08:16
  • `range(0, bound)` not include `bound`, or you can use `range(0, bound+1)`. Another `range(bound, 0, -1)` may be better, it will be max one found and no more searching. – Jason Yang May 03 '21 at 08:16
  • Does this answer your question? [Why does range(start, end) not include end?](https://stackoverflow.com/questions/4504662/why-does-rangestart-end-not-include-end) – Tomerikoo May 03 '21 at 08:49

3 Answers3

3

The problem is your range. You're iterating from 0 through bound-1, when in fact you need to iterate from 1 through bound. You also don't need the in-loop bound test, since the range should cover it. The following should work:

def maxMultiple(divisor, bound):
    largest = None

    for i in range(1,bound+1):
        if i % divisor == 0:
            largest = i

    return largest

But a better way to do it is to iterate from high to low, as follows:

def maxMultiple(divisor, bound):
    for i in range(bound, 0, -1):
        if i % divisor == 0:
            return i

    return None

You could also dispense with the loop altogether:

def maxMultiple(divisor, bound):
    return (bound // divisor) * divisor

Or equivalently:

def maxMultiple(divisor, bound):
    return bound - (bound % divisor)
Tom Karzes
  • 22,815
  • 2
  • 22
  • 41
2

The second range boundary is exclusive. So to include bound, you need

range(foo, bound+1)

Even better is looping from the back, here seen using next:

def maxMultiple(divisor, bound):
    return next(i for i in range(bound, 0, -1) if not i % divisor)

But, you can actually directly calculate this without any loop, using floor division:

def maxMultiple(divisor, bound):
    return (bound // divisor) * divisor
user2390182
  • 72,016
  • 6
  • 67
  • 89
1

You should try running the loop from 1 to bound+1

def maxMultiple(divisor, bound):
    
        largest = 0
    
        for i in range(1,bound+1):
            if i % divisor == 0 and i <= bound:
                largest = i
    
        print(largest)