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
//! # [Day 10: Elves Look, Elves Say](https://adventofcode.com/2015/day/10)
//!
//! Today, the Elves are playing a game called [look-and-say](https://en.wikipedia.org/wiki/Look-and-say_sequence).
//! They take turns making sequences by reading aloud the previous sequence and using that reading
//! as the next sequence. For example, `211` is read as "one two, two ones", which
//! becomes `1221` (`1` `2`, `2` `1`s).
//!
//! Look-and-say sequences are generated iteratively, using the previous value as input for the
//! next step. For each step, take the previous value, and replace each run of digits (like `111`)
//! with the number of digits (`3`) followed by the digit itself (`1`).
//!
//! For example:
//!
//! - `1` becomes `11` (`1` copy of digit `1`).
//! - `11` becomes `21` (`2` copies of digit `1`).
//! - `21` becomes `1211` (one `2` followed by one `1`).
//! - `1211` becomes `111221` (one `1`, one `2`, and two `1`s).
//! - `111221` becomes `312211` (three `1`s, two `2`s, and one `1`).
//!
//! Starting with the digits in your puzzle input, apply this process 40 times.
//! **What is the length of the result?**
//!
//! # Part Two
//!
//! Neat, right? You might also enjoy hearing [John Conway talking about this sequence](https://www.youtube.com/watch?v=ea7lJkEhytA)
//! (that's Conway of Conway's Game of Life fame).
//!
//! Now, starting again with the digits in your puzzle input, apply this process 50 times.
//! **What is the length of the new result?**
use itertools::Itertools;
/// Part 1: Starting with the digits in your puzzle input, apply this process 40 times.
/// What is the length of the result?
#[aoc(day10, part1)]
fn part1(input: &str) -> usize {
let mut s = input.to_string();
for _ in 0..40 {
s = lookandsay(&s);
}
s.len()
}
/// Part 2: Now, starting again with the digits in your puzzle input, apply this process 50 times.
/// What is the length of the new result?
#[aoc(day10, part2)]
fn part2(input: &str) -> usize {
let mut s = input.to_string();
for _ in 0..50 {
s = lookandsay(&s);
}
s.len()
}
fn group_chars(input: &str) -> Vec<String> {
input
.chars()
.group_by(|&x| x)
.into_iter()
.map(|(_, r)| r.collect())
.collect()
}
fn lookandsay(input: &str) -> String {
let mut s = String::new();
for group in group_chars(input) {
let count = group.len().to_string();
let char = group.chars().next().unwrap().to_string();
s += count.as_str();
s += char.as_str();
}
s
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn examples() {
// `1` becomes `11` (`1` copy of digit `1`).
assert_eq!(lookandsay("1"), "11");
// `11` becomes `21` (`2` copies of digit `1`).
assert_eq!(lookandsay("11"), "21");
// `21` becomes `1211` (one `2` followed by one `1`).
assert_eq!(lookandsay("21"), "1211");
// `1211` becomes `111221` (one `1`, one `2`, and two `1`s).
assert_eq!(lookandsay("1211"), "111221");
// `111221` becomes `312211` (three `1`s, two `2`s, and one `1`).
assert_eq!(lookandsay("111221"), "312211");
}
}