From 926fc4f6a8ad212242c7bfd03d43f53546baee79 Mon Sep 17 00:00:00 2001 From: shoofle Date: Mon, 23 Dec 2024 10:44:12 -0500 Subject: [PATCH] day 22 was easy peasy --- day21/src/main.rs | 134 ++++++++++++---------------------------------- day22/Cargo.toml | 6 +++ day22/src/main.rs | 95 ++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+), 99 deletions(-) create mode 100644 day22/Cargo.toml create mode 100644 day22/src/main.rs diff --git a/day21/src/main.rs b/day21/src/main.rs index bdd9fb5..63d3252 100644 --- a/day21/src/main.rs +++ b/day21/src/main.rs @@ -1,4 +1,3 @@ -use std::collections::HashSet; use std::collections::HashMap; use std::env; use std::fs; @@ -119,7 +118,8 @@ fn main() { &keypad_door, &door_code, 'A'); - for arrow_code_1 in shortest_sequences(options_door, &door_map, keypad_door[&'A']) { + println!("{options_door:?}"); + for arrow_code_1 in sequences(options_door, &door_map, keypad_door[&'A']) { print_code(&arrow_code_1); let options_arrow_1 = build_options( @@ -127,7 +127,7 @@ fn main() { &keypad_arrows, &arrow_code_1, Stay); - for arrow_code_2 in shortest_sequences(options_arrow_1, &keypad_map, keypad_arrows[&Stay]) { + for arrow_code_2 in sequences(options_arrow_1, &keypad_map, keypad_arrows[&Stay]) { print_code(&arrow_code_2); let options_arrow_2 = build_options( @@ -135,7 +135,7 @@ fn main() { &keypad_arrows, &arrow_code_2, Stay); - for arrow_code_3 in shortest_sequences(options_arrow_2, &keypad_map, keypad_arrows[&Stay]) { + for arrow_code_3 in sequences(options_arrow_2, &keypad_map, keypad_arrows[&Stay]) { complexity = complexity.min(arrow_code_3.len() as i64); print_code(&arrow_code_3); } @@ -146,147 +146,83 @@ fn main() { } println!("the sum of the complexity scores is {}", sum); - - // println!("printing out the anomalous code"); - - // let code = "<A>^AAvA<^A>AvA^A<>^AAvA^A^AAA<A>^AAAvA<^A>A"; - // let code_dirs = code.chars().map(|x| match x { - // '<' => West, '>' => East, '^' => North, 'v' => South, 'A' => Stay, _ => panic!() - // }).collect(); - // print_code(&code_dirs); - // println!("resulting keypresses:"); - // let code_2 = execute_code(&code_dirs, &keypad_map, keypad_arrows[&Stay]); - // print_code(&code_2); - // println!("resulting keypresses:"); - // let code_3 = execute_code(&code_2, &keypad_map, keypad_arrows[&Stay]); - // print_code(&code_3); - // println!("resulting in:"); - // let code_4 = execute_code(&code_3, &door_map, keypad_door[&'A']); - // print_code_door(&code_4); - - } -fn first_sequence(options: Vec>, map: &HashMap, start: Coord) -> Vec { - let mut out = vec![]; - let mut here = start; - - for choices in options { - if choices.len() == 1 { - let (direction, times) = choices[0]; - for _ in 0..times { - out.push(direction); - } - here = step(&here, direction, times) - } else if choices.len() == 2 { - let (d1, t1) = choices[0]; - let (d2, t2) = choices[1]; - if map.contains_key(&step(&here, d1, t1)) { - for _ in 0..t1 { - out.push(d1); - } - - for _ in 0..t2 { - out.push(d2); - } - } else { - for _ in 0..t2 { - out.push(d2); - } - - for _ in 0..t1 { - out.push(d1); - } - } - - - } - } - return out; -} fn sequences(options: Vec>, map: &HashMap, start: Coord) -> Vec> { - let mut out: Vec<(Vec, Coord)> = vec![(vec![], start)]; + let mut out: Vec<(Vec, Coord, Dir)> = vec![(vec![], start, Stay)]; for choices in options { - let mut new_out = vec![]; - if choices.len() == 1 { let (direction, times) = choices[0]; - for (mut walk, mut here) in out { + for (walk, here, last) in out.iter_mut() { for _ in 0..times { walk.push(direction); - here = step(&here, direction, 1); + *here = step(&here, direction, 1); + } + + if direction != Stay { + *last = direction; } - new_out.push((walk, here)); } } - + else if choices.len() == 2 { + let mut new_out = vec![]; + let (d1, t1) = choices[0]; let (d2, t2) = choices[1]; - for (ref walk, here) in &mut out { + for (walk, here, last) in &mut out { let end = step(&step(&here, d1, t1), d2, t2); + let candidate_here = step(&here, d1, t1); + let candidate_there = step(&here, d2, t2); + + if d1 == *last && map.contains_key(&candidate_here) { + for _ in 0..t1 { walk.push(d1); } + for _ in 0..t2 { walk.push(d2); } + new_out.push((walk.clone(), end, d2)); + continue; + } + if d2 == *last && map.contains_key(&candidate_there) { + for _ in 0..t2 { walk.push(d2); } + for _ in 0..t1 { walk.push(d1); } + new_out.push((walk.clone(), end, d1)); + continue; + } + if map.contains_key(&candidate_here) { let mut ab_walk = walk.clone(); for _ in 0..t1 { ab_walk.push(d1); } for _ in 0..t2 { ab_walk.push(d2); } - new_out.push((ab_walk, end)); + new_out.push((ab_walk, end, d2)); } - let candidate_there = step(&here, d2, t2); if map.contains_key(&candidate_there) { let mut ba_walk = walk.clone(); for _ in 0..t2 { ba_walk.push(d2); } for _ in 0..t1 { ba_walk.push(d1); } - new_out.push((ba_walk, end)); + new_out.push((ba_walk, end, d1)); } - } + out = new_out; } else { panic!("encountered a bad set of choices"); } - out = new_out; } let mut final_out = vec![]; - for (walk, _) in out { + for (walk, _, _) in out { final_out.push(walk); } return final_out; } -fn shortest_sequences( - options: Vec>, - map: &HashMap, - start: Coord -) -> Vec> { - let mut short_length = None; - let mut shorts = vec![]; - - for seq in sequences(options.to_vec(), map, start) { - let my_len = seq.len(); - if let Some(len) = short_length { - if my_len == len { - shorts.push(seq); - } else if my_len < len { - shorts = vec![seq]; - short_length = Some(my_len); - } - } else { - short_length = Some(my_len); - shorts.push(seq); - } - } - - return shorts; -} fn build_options( routes: &HashMap<(Coord, Coord), Vec<(Dir, i32)>>, diff --git a/day22/Cargo.toml b/day22/Cargo.toml new file mode 100644 index 0000000..07fb531 --- /dev/null +++ b/day22/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day22" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/day22/src/main.rs b/day22/src/main.rs new file mode 100644 index 0000000..b2f0837 --- /dev/null +++ b/day22/src/main.rs @@ -0,0 +1,95 @@ +use std::collections::HashSet; +use std::collections::HashMap; + +use std::env; +use std::fs; + +fn main() { + println!("Hello, AoC day 21!"); + + let args: Vec = env::args().collect(); + if args.len() != 2 { + println!("wrong number of arguments!"); + std::process::exit(1); + } + + let file_path = &args[1]; + + let file = fs::read_to_string(file_path) + .expect("should be able to read the file"); + + + // part a + let mut sum = 0; + for line in file.lines() { + let mut secret: i64 = line.parse().expect("gotta have good starting secrets"); + + for _ in 0..2000 { + secret = evolve(secret); + } + + sum += secret; + } + + println!("the sum of final secrets is {sum}"); + + // part b + let mut possible_changes: HashSet<[i64; 4]> = HashSet::new(); + let mut monkeys_changes: Vec> = Vec::new(); + + for line in file.lines() { + let mut secret: i64 = line.parse().expect("gotta have good starting secrets"); + + let mut primed = 4; + + let mut changes: [i64; 4] = [0,0,0,0]; + let mut last_price; + let mut price = secret % 10; + let mut my_guide: HashMap<[i64; 4], i64> = HashMap::new(); + println!("monkey starting with {secret}"); + + for _ in 0..2000 { + secret = evolve(secret); + last_price = price; + price = secret % 10; + + changes = [changes[1], changes[2], changes[3], price - last_price]; + + if primed > 0 { + primed = primed - 1; + } else { + possible_changes.insert(changes); + + if !my_guide.contains_key(&changes) { + my_guide.insert(changes, price); + } + } + // println!(": {price} ({}) {primed} {changes:?}", price-last_price); + } + + monkeys_changes.push(my_guide); + } + + println!("observed {} change sequences", possible_changes.len()); + let mut best = 0; + for sequence in possible_changes { + let mut candidate = 0; + for change_guide in &monkeys_changes { + candidate += change_guide.get(&sequence).unwrap_or(&0); + } + best = best.max(candidate); + } + + println!("best price is {best}"); +} + +fn evolve(initial: i64) -> i64 { + let mut secret = initial; + secret = prune(mix(secret, secret*64)); + secret = prune(mix(secret, secret/32)); + secret = prune(mix(secret, secret*2048)); + return secret; +} + +fn prune(x: i64) -> i64 { x % 16777216 } +fn mix(x:i64, y:i64) -> i64 { x ^ y } \ No newline at end of file