day 22 was easy peasy
This commit is contained in:
parent
12bdd65215
commit
926fc4f6a8
@ -1,4 +1,3 @@
|
|||||||
use std::collections::HashSet;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@ -119,7 +118,8 @@ fn main() {
|
|||||||
&keypad_door,
|
&keypad_door,
|
||||||
&door_code,
|
&door_code,
|
||||||
'A');
|
'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);
|
print_code(&arrow_code_1);
|
||||||
|
|
||||||
let options_arrow_1 = build_options(
|
let options_arrow_1 = build_options(
|
||||||
@ -127,7 +127,7 @@ fn main() {
|
|||||||
&keypad_arrows,
|
&keypad_arrows,
|
||||||
&arrow_code_1,
|
&arrow_code_1,
|
||||||
Stay);
|
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);
|
print_code(&arrow_code_2);
|
||||||
|
|
||||||
let options_arrow_2 = build_options(
|
let options_arrow_2 = build_options(
|
||||||
@ -135,7 +135,7 @@ fn main() {
|
|||||||
&keypad_arrows,
|
&keypad_arrows,
|
||||||
&arrow_code_2,
|
&arrow_code_2,
|
||||||
Stay);
|
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);
|
complexity = complexity.min(arrow_code_3.len() as i64);
|
||||||
print_code(&arrow_code_3);
|
print_code(&arrow_code_3);
|
||||||
}
|
}
|
||||||
@ -146,147 +146,83 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
println!("the sum of the complexity scores is {}", sum);
|
println!("the sum of the complexity scores is {}", sum);
|
||||||
|
|
||||||
// println!("printing out the anomalous code");
|
|
||||||
|
|
||||||
// let code = "<<vAA>A>^AAvA<^A>AvA^A<<vA>>^AAvA^A<vA>^AA<A>A<<vA>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<T>(options: Vec<Vec<(Dir, i32)>>, map: &HashMap<Coord, T>, start: Coord) -> Vec<Dir> {
|
|
||||||
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<T>(options: Vec<Vec<(Dir, i32)>>, map: &HashMap<Coord, T>, start: Coord) -> Vec<Vec<Dir>> {
|
fn sequences<T>(options: Vec<Vec<(Dir, i32)>>, map: &HashMap<Coord, T>, start: Coord) -> Vec<Vec<Dir>> {
|
||||||
let mut out: Vec<(Vec<Dir>, Coord)> = vec![(vec![], start)];
|
let mut out: Vec<(Vec<Dir>, Coord, Dir)> = vec![(vec![], start, Stay)];
|
||||||
|
|
||||||
for choices in options {
|
for choices in options {
|
||||||
let mut new_out = vec![];
|
|
||||||
|
|
||||||
if choices.len() == 1 {
|
if choices.len() == 1 {
|
||||||
let (direction, times) = choices[0];
|
let (direction, times) = choices[0];
|
||||||
for (mut walk, mut here) in out {
|
for (walk, here, last) in out.iter_mut() {
|
||||||
for _ in 0..times {
|
for _ in 0..times {
|
||||||
walk.push(direction);
|
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 {
|
else if choices.len() == 2 {
|
||||||
|
let mut new_out = vec![];
|
||||||
|
|
||||||
let (d1, t1) = choices[0];
|
let (d1, t1) = choices[0];
|
||||||
let (d2, t2) = choices[1];
|
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 end = step(&step(&here, d1, t1), d2, t2);
|
||||||
|
|
||||||
let candidate_here = step(&here, d1, t1);
|
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) {
|
if map.contains_key(&candidate_here) {
|
||||||
let mut ab_walk = walk.clone();
|
let mut ab_walk = walk.clone();
|
||||||
|
|
||||||
for _ in 0..t1 { ab_walk.push(d1); }
|
for _ in 0..t1 { ab_walk.push(d1); }
|
||||||
for _ in 0..t2 { ab_walk.push(d2); }
|
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) {
|
if map.contains_key(&candidate_there) {
|
||||||
let mut ba_walk = walk.clone();
|
let mut ba_walk = walk.clone();
|
||||||
|
|
||||||
for _ in 0..t2 { ba_walk.push(d2); }
|
for _ in 0..t2 { ba_walk.push(d2); }
|
||||||
for _ in 0..t1 { ba_walk.push(d1); }
|
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 {
|
} else {
|
||||||
panic!("encountered a bad set of choices");
|
panic!("encountered a bad set of choices");
|
||||||
}
|
}
|
||||||
|
|
||||||
out = new_out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut final_out = vec![];
|
let mut final_out = vec![];
|
||||||
for (walk, _) in out {
|
for (walk, _, _) in out {
|
||||||
final_out.push(walk);
|
final_out.push(walk);
|
||||||
}
|
}
|
||||||
return final_out;
|
return final_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shortest_sequences<T>(
|
|
||||||
options: Vec<Vec<(Dir, i32)>>,
|
|
||||||
map: &HashMap<Coord, T>,
|
|
||||||
start: Coord
|
|
||||||
) -> Vec<Vec<Dir>> {
|
|
||||||
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<T: std::hash::Hash + std::cmp::Eq>(
|
fn build_options<T: std::hash::Hash + std::cmp::Eq>(
|
||||||
routes: &HashMap<(Coord, Coord), Vec<(Dir, i32)>>,
|
routes: &HashMap<(Coord, Coord), Vec<(Dir, i32)>>,
|
||||||
|
6
day22/Cargo.toml
Normal file
6
day22/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "day22"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
95
day22/src/main.rs
Normal file
95
day22/src/main.rs
Normal file
@ -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<String> = 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<HashMap<[i64; 4], i64>> = 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 }
|
Loading…
Reference in New Issue
Block a user