with open('data-2015-20.txt', 'r') as f:
inp = f.read().splitlines()
presents = int(inp[0])Advent of Code 2015 Day 20
— Day 20: Infinite Elves and Infinite Houses —
What is the lowest house number of the house to get at least as many presents as the number in your puzzle input?
I think we just have to loop: try this as an estimation.
house = 600000
tot = 0
step = 1000
while tot < presents:
# increment house visited
house += step
# always start with elf 1
tot = 10
# if even, then go through everything
if house % 2 == 0:
for h in range(house, 1, -1):
if house % h == 0:
tot += 10 * h
else:
# odd number, we can just go through odds
for h in range(house, 1, -2):
if house % h == 0:
tot += 10 * h
# print(tot)
tot
house693000
Steps of 10000: 29295310, 810000
From 500,000, steps of 1,000: 29203200, 693000
From 600,000, steps of 100: 29203200, 693000
I think I want to try this somewhat differently, counting down.
# house = 700000
# tot = 0
#
#
# while house > 600000:
# # increment house visited
# house -= 10
# # always start with elf 1
# tot = 10
# # if even, then go through everything
# if house % 2 == 0:
# for h in range(house, 1, -1):
# if house % h == 0:
# tot += 10 * h
# else:
# # odd number, we can just go through odds
# for h in range(house, 1, -2):
# if house % h == 0:
# tot += 10 * h
# if tot > presents:
# print(tot)
# print(house)
#
#
# tot
# house29030400, 695520
29203200, 693000
29260800, 665280
Let’s look for factors instead
https://stackoverflow.com/questions/6800193/what-is-the-most-efficient-way-of-finding-all-the-factors-of-a-number-in-python
from functools import reduce
def factors(n):
return set(reduce(list.__add__,
([i, n//i] for i in range(1, int(n**0.5) + 1) if n % i == 0)))Use it in a loop
for i in range(600000, 700000):
x = sum(factors(i)) * 10
if x > presents:
print(x)
print(i)
break29260800
665280
— Part Two —
Elves are only going to deliver to 50 houses each.
With these changes, what is the new lowest house number of the house to get at least as many presents as the number in your puzzle input?
def factors2(n):
tmp = reduce(list.__add__, ([i, n//i]
for i in range(1, int(n**0.5) + 1) if n % i == 0))
return set([t for t in tmp if t >= (n/50)])Again loop it
mx = 0
for i in range(650000, 750000, 1):
x = sum(factors2(i)) * 11
if x > mx:
mx = x
print(x)
print(i)
# 70560017788375
650000
20278291
650016
21272559
650040
21687336
650100
26356330
650160
27800157
655200
28413770
665280
28899255
693000
29002446
705600
29370187
718200
31358250
720720