.sum()
}
-fn nb_of_digits(mut v: i64) -> u32 {
- let mut n = 1;
- while v >= 10 {
- v /= 10;
- n += 1;
- }
- n
-}
-
pub fn sum_valid_equations_with_concat(equations: &[Equation]) -> i64 {
fn is_valid(result: i64, operands: &[i64]) -> bool {
let l = operands.len();
return true;
}
- let p = 10i64.pow(nb_of_digits(last));
+ let p = 10i64.pow(utils::nb_of_digits(last));
if sub % p == 0 {
if is_valid(sub / p, &operands[0..l - 1]) {
return true;
--- /dev/null
+use std::io::BufRead;
+
+use rustc_hash::FxHashMap;
+
+use crate::utils;
+
+type Stones = FxHashMap<u64, u64>;
+
+pub fn read(reader: &mut dyn BufRead) -> Stones {
+ Stones::from_iter(
+ utils::split_to_vec(&std::io::read_to_string(reader).unwrap(), " ")
+ .into_iter()
+ .map(|s| (s, 1)),
+ )
+}
+
+fn add_or_set(map: &mut FxHashMap<u64, u64>, k: u64, n: u64) {
+ map.entry(k).and_modify(|v| *v += n).or_insert(n);
+}
+
+pub fn blink(stones: FxHashMap<u64, u64>, i: u32) -> FxHashMap<u64, u64> {
+ if i == 0 {
+ stones
+ } else {
+ let mut next_stones = FxHashMap::<u64, u64>::default();
+ for (stone, n) in stones {
+ if stone == 0 {
+ add_or_set(&mut next_stones, 1, n);
+ } else {
+ let nb_digits = utils::nb_of_digits(stone);
+ if nb_digits % 2 == 0 {
+ let base = 10u64.pow(nb_digits / 2);
+ let left = stone / base;
+ let right = stone - left * base;
+ add_or_set(&mut next_stones, left, n);
+ add_or_set(&mut next_stones, right, n);
+ } else {
+ add_or_set(&mut next_stones, stone * 2024, n);
+ }
+ }
+ }
+
+ blink(next_stones, i - 1)
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ static STONES: &str = "125 17";
+
+ #[test]
+ fn test_part1_and_part2() {
+ let stones = read(&mut STONES.as_bytes());
+ let stones_after_6 = blink(stones.clone(), 6);
+ let stones_after_25 = blink(stones, 25);
+ assert_eq!(stones_after_6.values().sum::<u64>(), 22);
+ assert_eq!(stones_after_25.values().sum::<u64>(), 55312);
+ }
+}
day10::score(&map, &start_positions, true),
)
}
+
+pub fn day11(reader: &mut dyn BufRead) -> String {
+ let stones = day11::read(reader);
+ let stones_25 = day11::blink(stones, 25);
+ let nb_stones_25 = stones_25.values().sum::<u64>();
+ let stones_75 = day11::blink(stones_25, 50);
+ format!(
+ "part1: {}, part2: {}",
+ nb_stones_25,
+ stones_75.values().sum::<u64>()
+ )
+}
-use std::{fmt::Debug, str::FromStr};
+use std::{cmp, fmt::Debug, str::FromStr};
+
+use num;
pub fn split_to_vec<T>(str: &str, pat: &str) -> Vec<T>
where
{
str.split(pat).map(|v| v.parse::<T>().unwrap()).collect()
}
+
+pub fn nb_of_digits<T>(mut v: T) -> u32
+where
+ T: cmp::PartialOrd<T> + std::ops::DivAssign<T> + num::FromPrimitive + Copy,
+{
+ let ten = T::from_u32(10).unwrap();
+ let mut n = 1;
+ while v >= ten {
+ v /= ten;
+ n += 1;
+ }
+ n
+}