--- /dev/null
+use std::error::Error;
+use std::path::Path;
+
+fn split_in_two(value: u64) -> Option<(u64, u64)> {
+ let n_digits = value.ilog10() + 1;
+ if n_digits % 2 == 0 {
+ let p = 10_u64.pow(n_digits / 2);
+ return Some((value / p, value % p));
+ }
+ else {
+ return None;
+ }
+}
+
+fn count_stones(value: u64, blinks: u32) -> u32 {
+ if blinks == 0 {
+ return 1;
+ }
+ else if value == 0 {
+ return count_stones(1, blinks - 1);
+ }
+ else {
+ if let Some((r, l)) = split_in_two(value) {
+ return count_stones(r, blinks - 1) + count_stones(l, blinks - 1);
+ }
+ else {
+ return count_stones(value * 2024, blinks - 1);
+ }
+ }
+}
+
+fn run_part1(input: &str, blinks: u32) -> Result<u32, Box<dyn Error>> {
+ println!("Running {} - part 1", get_day());
+
+ let res = input.split_whitespace()
+ .map(|v| v.parse::<u64>().unwrap())
+ .map(|v| count_stones(v, blinks))
+ .sum::<u32>();
+
+ Ok(res)
+}
+
+fn run_part2(input: &str) -> Result<u32, Box<dyn Error>> {
+ println!("Running {} - part 2", get_day());
+
+ Ok(0)
+}
+
+pub fn run(input: &str) -> Result<(), Box<dyn Error>> {
+ let res = run_part1(input, 25)?;
+ println!("{res}");
+
+ let res = run_part2(input)?;
+ println!("{res}");
+
+ Ok(())
+}
+
+fn get_day() -> String {
+ let filename = file!();
+ Path::new(filename).file_stem().unwrap().to_str().unwrap().to_string()
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ static TEXT_INPUT_0: &str = "\
+0 1 10 99 999";
+ static TEXT_INPUT: &str = "\
+125 17";
+
+ #[test]
+ fn test_part1() {
+ assert_eq!(7, run_part1(TEXT_INPUT_0, 1).unwrap());
+ assert_eq!(3, run_part1(TEXT_INPUT, 1).unwrap());
+ assert_eq!(4, run_part1(TEXT_INPUT, 2).unwrap());
+ assert_eq!(5, run_part1(TEXT_INPUT, 3).unwrap());
+ assert_eq!(9, run_part1(TEXT_INPUT, 4).unwrap());
+ assert_eq!(13, run_part1(TEXT_INPUT, 5).unwrap());
+ assert_eq!(22, run_part1(TEXT_INPUT, 6).unwrap());
+ assert_eq!(55312, run_part1(TEXT_INPUT, 25).unwrap());
+ }
+
+ #[test]
+ fn test_part2() {
+ assert_eq!(0, run_part2(TEXT_INPUT).unwrap());
+ }
+}