I've started to learn Numpy and I'm looking for some ways to write this. I've written a generalization of Euler 1. It takes a list of divisors and a number, for example [3, 5] and 1000 in Euler 1.
Naively in pure python:
def subn1(divisors, n):
return sum(i for i in range(1,n) if not all(i % d for d in divisors))
This runs in about 2.5 seconds for range(2,20), 1000000.
My first and best so far numpy attempt looks like this:
def subn2(divisors, n):
a = np.arange(1,n)
b = np.zeros(a.shape[0], dtype=bool)
for d in divisors:
b += a % d == 0
return np.sum(a[b])
And runs in around 0.45 seconds for range(2,20), 1000000.
My third attempt was to remove the foor loop and use pure numpy, however it lost in the speed department by a small margin and uses more memory.
def subn3(divisors, n):
nums = np.arange(1,n)
divs = np.array([divisors]).T
return np.sum(nums[np.logical_or.reduce(np.mod(nums, divs) == 0, axis=0)])
This runs in around .5 seconds for range(2,20), 100000.
Is there a faster way to write it in 'pure' numpy or are foor loops not to shy away from?
Note: I'm aware that you can optimize it by reducing the divisor list, so there's no need to comment on that :)