Advent of Code 2015 - Day 10 - Elves Look, Elves Say
On the tenth day of Advent of Code 2015 the Elves are playing a game of look-and-say, of which we are asked to find several terms in the sequence.
Part 1
For part one we are asked to determine the length of the result of the 40th term in the sequence (starting with the provided input). Based on a famous integer sequence, we begin by implementing how the next term can be produced from a supplied value.
const lookAndSay = (input: string): string =>
input
.match(/(\d)\1*/g)
.reduce((next, digit) => next + digit.length + digit[0], '');
For this implementation I have decided to take advantage of Regular Expression back-reference’s again to capture all the grouped adjacent digits - treating integers as strings in the process. From here we can reduce over these groups forming the next value in the sequence.
Now we have the ability to produce the next term in the sequence, we need a means to iterate over this process for a given amount of times.
For this I decided to create a small generic utility function, which is influenced by the iterate
function provided in Clojure (expect this one is not lazy).
const repeat = <T>(
times: number,
fn: (x: T) => T,
initialValue?: T
): T => {
let accumulator = initialValue;
while (times--) accumulator = fn(accumulator);
return accumulator;
};
Providing an optional initial value, this function abstracts away the mutational looping required to apply this process in a performant manor. With these two functions now present we can compose them together and find the 40th term which is requird to answer this parts question 🌟.
const part1 = (input: string): number =>
repeat(40, lookAndSay, input).length;
Part 2
For part two we are required to instead find the 50th terms length in the sequence. Again we can compose the two above functions together to find the desired answer 🌟.
const part2 = (input: string): number =>
repeat(50, lookAndSay, input).length;