Source

Part 1: P(n) is defined such that for each number i, add 10i to any number divisible by i. Find the first value n such that P(n) is at least a given target number.

Let’s throw some memory (and numpy) at it:

target = int(sys.argv[1])

presents = numpy.zeros(target)

for i in range(1, target):
presents[i::i] += 10 * i

for i in range(len(presents)):
if presents[i] >= target:
print(i)
sys.exit(0)

It barely makes it in under a minute, but it does. You can speed it up even more if you guess on where the answer will be an initialize to only the first numpy.zeros(target / 10). In only shaves off about 16 of the time on my run though, so I’m not sure it’s worth it.

Part 2: Do the same thing, only use 11i instead of 10i but only to the first 50 multiples.

Nothing much changes:

target = int(sys.argv[1])

presents = numpy.zeros(target / 10)

for i in range(1, target):
presents[i:i*50:i] += 11 * i

for i in range(len(presents)):
if presents[i] >= target:
print(i)
sys.exit(0)