1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
//! # [Day 20: Infinite Elves and Infinite Houses](https://adventofcode.com/2015/day/20)
//!
//! To keep the Elves busy, Santa has them deliver some presents by hand, door-to-door.
//! He sends them down a street with infinite houses numbered sequentially:
//!
//! `1`, `2`, `3`, `4`, `5`, and so on.
//!
//! Each Elf is assigned a number, too, and delivers presents to houses based on that number:
//!
//! - The first Elf (number `1`) delivers presents to every house:
//! `1`, `2`, `3`, `4`, `5`, ....
//! - The second Elf (number `2`) delivers presents to every second house:
//! `2`, `4`, `6`, `8`, `10`, ....
//! - Elf number `3` delivers presents to every third house:
//! `3`, `6`, `9`, `12`, `15`, ....
//!
//! There are infinitely many Elves, numbered starting with `1`.
//! Each Elf delivers presents equal to ten times his or her number at each house.
//!
//! So, the first nine houses on the street end up like this:
//!
//! ```plain
//! House 1 got 10 presents.
//! House 2 got 30 presents.
//! House 3 got 40 presents.
//! House 4 got 70 presents.
//! House 5 got 60 presents.
//! House 6 got 120 presents.
//! House 7 got 80 presents.
//! House 8 got 150 presents.
//! House 9 got 130 presents.
//! ```
//!
//! The first house gets `10` presents: it is visited only by Elf `1`,
//! which delivers `1 * 10 = 10` presents. The fourth house gets `70` presents, because it is
//! visited by Elves `1`, `2`, and `4`, for a total of `10 + 20 + 40 = 70` presents.
//!
//! **What is the lowest house number of the house to get at least as many presents as the
//! number in your puzzle input?**
//!
//! # Part 2
//!
//! The Elves decide they don't want to visit an infinite number of houses. Instead,
//! each Elf will stop after delivering presents to `50` houses.
//! To make up for it, they decide to deliver presents equal to
//! eleven times their number at each house.
//!
//! 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?**
#[aoc_generator(day20)]
fn parse_input(input: &str) -> u64 {
input.parse().unwrap()
}
/// Part 1: What is the lowest house number of the house to get at least as many presents as the
/// number in your puzzle input?
#[aoc(day20, part1)]
fn part1(input: &u64) -> u64 {
for house_nr in 1..u64::MAX {
if presents_at1(house_nr) >= *input {
return house_nr;
}
}
0
}
fn presents_at1(house_nr: u64) -> u64 {
divisors(house_nr).into_iter().sum::<u64>() * 10
}
fn divisors(n: u64) -> Vec<u64> {
let mut small_divisors: Vec<u64> = Vec::from_iter(1..((n as f64).sqrt() as u64 + 1))
.into_iter()
.filter(|i| n % *i == 0)
.collect();
let mut large_divisors: Vec<u64> = small_divisors
.iter()
.filter(|d| n != **d * **d)
.map(|d| n / d)
.collect();
small_divisors.append(&mut large_divisors);
small_divisors
}
/// Part 2: what is the new lowest house number of the house to get at least as
/// many presents as the number in your puzzle input?
#[aoc(day20, part2)]
fn part2(input: &u64) -> u64 {
for house_nr in 1..u64::MAX {
if presents_at2(house_nr) >= *input {
return house_nr;
}
}
0
}
fn presents_at2(house_nr: u64) -> u64 {
divisors(house_nr)
.into_iter()
.filter(|d| house_nr / d <= 50)
.sum::<u64>()
* 11
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn part1_examples() {
// House 1 got 10 presents.
assert_eq!(10, presents_at1(1));
// House 2 got 30 presents.
assert_eq!(30, presents_at1(2));
// House 3 got 40 presents.
assert_eq!(40, presents_at1(3));
// House 4 got 70 presents.
assert_eq!(70, presents_at1(4));
// House 5 got 60 presents.
assert_eq!(60, presents_at1(5));
// House 6 got 120 presents.
assert_eq!(120, presents_at1(6));
// House 7 got 80 presents.
assert_eq!(80, presents_at1(7));
// House 8 got 150 presents.
assert_eq!(150, presents_at1(8));
// House 9 got 130 presents.
assert_eq!(130, presents_at1(9));
}
}