Day 10: Elves Look, Elves Say

I remember in the 6th grade our math teacher had a problem where they wrote the look-and-say sequence on the board and challenged all of us to figure out what came next. The whole class was stumped because we were focused on using addition, subtraction, multiplication, and other math concepts we were taught. It was not a math problem at all but instead a logic one.

The solution here was a bit tricky. Not because of the actual work but understanding Rust’s types. It was explained to me that both parse_input and look_and_say return different types but both implement Iterator. Therefore I have to wrap the outputs of each with dyn which requires a Box.

Loading code...

use itertools::Itertools;

fn parse_input<'a> (input: &'a str) -> Box<dyn Iterator<Item = usize> + 'a> {
	return Box::new(input.chars().map(|x| usize::from_str_radix(x.to_string().as_str(), 10).unwrap()));
}

fn look_and_say<'b> (input: impl Iterator<Item = usize> + 'b) -> Box<dyn Iterator<Item = usize> + 'b> {
	return Box::new(input.into_iter()
		.dedup_with_count()
		.map(|(count, value)| [count, value])
		.flatten());
}

fn solve (input: &str, count: usize) -> usize {
	let mut input = parse_input(input);
	for i in 0..count {
		input = look_and_say(input);
	}
	return input.count();
}

pub fn day_10_1 (input: &str) -> String {
	println!("{} = {}", input, solve("11", 1));
	return solve(input, 40).to_string();
}

pub fn day_10_2 (input: &str) -> String {
	return solve(input, 50).to_string();
}