--- /dev/null
+use std::error::Error;
+use std::path::Path;
+
+fn mix(value: u64, secret: u64) -> u64 {
+ value ^ secret
+}
+
+fn prune(value: u64) -> u64 {
+ value % 16777216
+}
+
+fn new_secret(secret: u64, steps: usize) -> u64 {
+ let mut s = secret;
+ for i in 0..steps {
+ s = prune(mix(s * 64, s));
+ s = prune(mix(s / 32, s));
+ s = prune(mix(s * 2048, s));
+ }
+ s
+}
+
+fn run_part1(input: &str) -> Result<u64, Box<dyn Error>> {
+ println!("Running {} - part 1", get_day());
+
+ let res: u64 = input.lines()
+ .map(|l| l.parse::<u64>().unwrap())
+ .map(|secret| new_secret(secret, 2000))
+ .sum();
+
+ Ok(res)
+}
+
+fn run_part2(input: &str) -> Result<u64, 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)?;
+ 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: &str = "\
+";
+
+ #[test]
+ fn test_part1() {
+ let secret_123_steps = vec![
+ 15887950, 16495136, 527345, 704524, 1553684,
+ 12683156, 11100544, 12249484, 7753432, 5908254,
+ ];
+ for step in 0..secret_123_steps.len() {
+ assert_eq!(new_secret(123, step + 1), secret_123_steps[step]);
+ }
+ assert_eq!(new_secret(1, 2000), 8685429);
+ assert_eq!(new_secret(10, 2000), 4700978);
+ assert_eq!(new_secret(100, 2000), 15273692);
+ assert_eq!(new_secret(2024, 2000), 8667524);
+ }
+
+ #[test]
+ fn test_part2() {
+ assert_eq!(0, run_part2(TEXT_INPUT).unwrap());
+ }
+}
pub mod day18;
pub mod day19;
pub mod day20;
+pub mod day22;
fn main() {
let args: Vec<String> = env::args().collect();
"day18" => day18::run(&input)?,
"day19" => day19::run(&input)?,
"day20" => day20::run(&input)?,
+ "day22" => day22::run(&input)?,
_ => return Err(format!("unknown or unimplemented day \"{day}\"").into()),
}
Ok(())