-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
154 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Day 20: Infinite Elves and Infinite Houses | ||
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: | ||
|
||
``` | ||
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 Two | ||
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? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { describe, expect, it } from 'vitest'; | ||
|
||
import { findFactors } from './find-factors.js'; | ||
|
||
/* ========================================================================== */ | ||
|
||
describe('Calculate factors', () => { | ||
it('should return the factors for any given number', () => { | ||
expect(findFactors(25)).toEqual([1, 5, 25]); | ||
expect(findFactors(45)).toEqual([1, 3, 5, 9, 15, 45]); | ||
expect(findFactors(53)).toEqual([1, 53]); | ||
expect(findFactors(64)).toEqual([1, 2, 4, 8, 16, 32, 64]); | ||
expect(findFactors(100)).toEqual([1, 2, 4, 5, 10, 20, 25, 50, 100]); | ||
expect(findFactors(102)).toEqual([1, 2, 3, 6, 17, 34, 51, 102]); | ||
expect(findFactors(120)).toEqual([1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 24, 30, 40, 60, 120]); | ||
expect(findFactors(12345)).toEqual([1, 3, 5, 15, 823, 2469, 4115, 12345]); | ||
expect(findFactors(32766)).toEqual([ | ||
1, 2, 3, 6, 43, 86, 127, 129, 254, 258, 381, 762, 5461, 10922, 16383, 32766 | ||
]); | ||
expect(findFactors(32767)).toEqual([1, 7, 31, 151, 217, 1057, 4681, 32767]); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/** | ||
* Finds the factors for a given number. | ||
* | ||
* @param value The number for which to find the the factors. | ||
* | ||
* @returns An array with all the factors, sorted from low to high. | ||
* | ||
* @see {@link https://courses.lumenlearning.com/mathforliberalartscorequisite/chapter/finding-all-the-factors-of-a-number/} | ||
*/ | ||
export function findFactors(value: number): number[] { | ||
const factors: number[] = []; | ||
// We need to stop when the divisor becomes smaller than the quotient. We | ||
// could do that be checking the result in the for loop or we calculate when | ||
// it is. By taking the square root we know the tipping point and since we | ||
// only deal with integers we need to round it down. | ||
// E.g.: When factoring 72 the tipping point is 8. This because the square | ||
// root of 72, rounded down, is 8. | ||
// - 72 / 8 = 9, the divisor (8) is more than the quotient (9) | ||
// - 72 / 9 = 8, the divisor (9) has become more than the quotient (8) | ||
const limit = Math.floor(Math.sqrt(value)); | ||
|
||
// Starting by 1 keep processing all the integers until the limit has been | ||
// processed too. | ||
for (let divisor = 1; divisor <= limit; divisor++) { | ||
// When the quotient is not a whole number, the divisor and quotient | ||
// are not factors. | ||
if (value % divisor !== 0) continue; | ||
|
||
factors.push(divisor); | ||
|
||
// When the divisor and quotient are the same, there is no need to add | ||
// the quotient the list of factors it has already been added when the | ||
// divisor was added to the list. | ||
if (value / divisor !== divisor) { | ||
factors.push(value / divisor); | ||
} | ||
} | ||
|
||
return factors.sort((a, b) => a - b); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { findFactors } from './helpers/find-factors.js'; | ||
|
||
/* ========================================================================== */ | ||
|
||
async function solver(input: string): Promise<number> { | ||
// Each elf gives 10 times the number of presents as his/her number. If we | ||
// divide the input by 10 each elf gives 1 time the number of presents as | ||
// his/her number and we a lower target to find a solution to. | ||
const presentsGoal = Number(input) / 10; | ||
|
||
// Iterate over the houses, start with 1 house and keep increasing till the | ||
// first house with the specified number of presents has been found. | ||
for (let houseNumber = 1; houseNumber < Infinity; houseNumber++) { | ||
const visitingElves = findFactors(houseNumber); | ||
const numberOfPresents = visitingElves.reduce((sum, count) => sum + count, 0); | ||
|
||
if (numberOfPresents >= presentsGoal) return houseNumber; | ||
} | ||
|
||
return -1; | ||
} | ||
|
||
/* ========================================================================== */ | ||
|
||
export default { | ||
prompt: 'lowest house number to receive specified number of presents', | ||
solver | ||
} satisfies Solution; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { findFactors } from './helpers/find-factors.js'; | ||
|
||
/* ========================================================================== */ | ||
|
||
async function solver(input: string): Promise<number> { | ||
const presentsGoal = Number(input); | ||
|
||
// Iterate over the houses, start with 1 house and keep increasing till the | ||
// first house with the specified number of presents has been found. | ||
for (let houseNumber = 1; houseNumber < Infinity; houseNumber++) { | ||
// Get the number of the elves that will make a stop at the | ||
// current house. Only elves for whom it is at most their fifth visit | ||
// will visit this house. Elves which have already visited 50 houses | ||
// will sit this one out. | ||
const visitingElves = findFactors(houseNumber).filter(elf => houseNumber / elf <= 50); | ||
|
||
// Count the number of presents which will be presented to the house. | ||
const numberOfPresents = visitingElves.reduce((sum, elf) => sum + (elf * 11), 0); | ||
|
||
if (numberOfPresents >= presentsGoal) return houseNumber; | ||
} | ||
|
||
return -1; | ||
} | ||
|
||
/* ========================================================================== */ | ||
|
||
export default { | ||
prompt: 'lowest house number to receive specified number of presents', | ||
solver | ||
} satisfies Solution; |