Home > other >  how to count the number divisible by N in given range (A to B) for multiple cases (C) in python
how to count the number divisible by N in given range (A to B) for multiple cases (C) in python

Time:12-11

So basically, there are multiple cases that need to be solve by counting the number that divisible by N in given range A to B.

for example, there are 2 cases.

case 1 has A=1, B=10, N=3

case 2 has A=8, B=20, N=4

but on one condition that the input must be like this:

2        #<-- number of cases
1        #<-- A 
10       #<-- B 
3        #<-- N
8        #<-- A
20       #<-- B
4        #<-- N

the output will be like:

Case 1: 3 #because between 1 until 10, only 3,6,9 that divisible by 3
Case 2: 4 #because between 8 until 20, only 8,12,16,20 that divisible by 4

I have this function for reference:

def CountDiv(A,B,N):
    count = 0
    
    for i in range(A, B 1):
        if i % N == 0:
            count = count   1
    
    return count

My explanation is bad but I just don't know how to make it more clearer. I hope someone will understand and enlightened me about this problem. Thank you

CodePudding user response:

You don't need to loop over all values. You can only generate the multiple from the smallest starting point ((A N-1)//N*N):

def ndiv(A, B, N):
    return len(list((A N-1)//N*N, B 1, N)))

Even better, calculate directly the number of values using:

def ndiv(A, B, N):
    if B<A:
        return 0
    return (B N-(A N-1)//N*N)//N

example:

>>> ndiv(8,20,4)
4

>>> ndiv(1,10,3)
3

>>> ndiv(1,1,3)
0

CodePudding user response:

I'm assuming that you are asking how to properly slice your input list. Assuming you have your input sequence in a list, this should work

seq = [ 2,        #<-- number of cases
        1,        #<-- A 
        10,       #<-- B 
        3,        #<-- N
        8,        #<-- A
        20,       #<-- B
        4,        #<-- N
]


def slices(lst, n):

    number_of_cases = lst.pop(0)
    
    for i in range(0, n * number_of_cases, n):
        yield lst[i:i   n]

def CountDiv(A,B,N):
    
    count = 0
    for i in range(A, B 1):
        if i % N == 0:
            count = count   1
    
    return count

print([CountDiv(*sub) for sub in [*slices(seq, n=3)]])
# [3, 4]

If you want the exact output you described, you can do this

for idx, sub in enumerate([*slices(seq, n=3)]):
    print(f"Case {idx}: {CountDiv(*sub)}")

# Case 0: 3
# Case 1: 4

You should also combine @mozway's and my answer, like so.

def slices(lst, n):
   
    number_of_cases = lst.pop(0)
     
    for i in range(0, n * number_of_cases, n):
        yield lst[i:i   n]

def ndiv(A, B, N):
    return (B N-(A N-1)//N*N)//N if B>=A else 0

for idx, sub in enumerate([*slices(seq, n=3)]):
    print(f"Case {idx}: {ndiv(*sub)}")
  • Related