operating on numeric ids instead of strings

This commit is contained in:
Acvaxoort 2023-12-08 19:34:42 +01:00
parent 9091376a90
commit 8b7587890d

View File

@ -1,14 +1,13 @@
use std::fs::read_to_string;
use std::collections::HashMap;
use num::integer::lcm;
fn get_steps_to(directions: &str, nodes: &HashMap<&str, (&str, &str)>,
start: &str, stop: fn(&str) -> bool) -> u64 {
fn get_steps_to<F: Fn(u16) -> bool>(directions: &str, nodes: &Vec<(u16, u16)>,
start: u16, stop: F) -> u64 {
let mut current_node = start;
let mut counter: u64 = 0;
'outer: loop {
for c in directions.bytes() {
let (left, right) = nodes[current_node];
let (left, right) = nodes[current_node as usize];
match c {
b'L' => current_node = left,
b'R' => current_node = right,
@ -23,22 +22,36 @@ fn get_steps_to(directions: &str, nodes: &HashMap<&str, (&str, &str)>,
counter
}
fn str_to_id(str: &str) -> u16 {
let mut value: u16 = 0;
for c in str.bytes() {
value = value * 26 + (c - b'A') as u16;
}
value
}
fn main() {
let lines_str = read_to_string("input.txt").unwrap();
let mut lines_iter = lines_str.lines();
let directions = lines_iter.next().unwrap();
lines_iter.next();
let nodes = lines_iter.map(|line| {
let mut nodes: Vec<(u16, u16)> = vec![(0, 0); 17576];
let mut ids_ending_with_a: Vec<u16> = Vec::new();
for line in lines_iter {
let mut ids = line.split([' ', '(', ')', '=', ',']).filter(|&str| !str.is_empty());
(ids.next().unwrap(), (ids.next().unwrap(), ids.next().unwrap()))
}).collect::<HashMap<_, _>>();
let counter1 = get_steps_to(directions, &nodes, "AAA", |str| str == "ZZZ");
let counter2 = nodes.iter()
.filter_map(|(&id, _)|
Some(id).filter(|&id| id.as_bytes()[2 as usize] == b'A'))
.map(|node| get_steps_to(
directions, &nodes, node, |str| str.as_bytes()[2 as usize] == b'Z'))
let node_id = str_to_id(ids.next().unwrap());
nodes[node_id as usize] = (str_to_id(ids.next().unwrap()), str_to_id(ids.next().unwrap()));
if node_id % 26 == 0 {
ids_ending_with_a.push(node_id);
}
}
let id_aaa = str_to_id("AAA");
let id_zzz = str_to_id("ZZZ");
let counter1 = get_steps_to(directions, &nodes, id_aaa, |id| id == id_zzz);
let counter2 = ids_ending_with_a.iter()
.map(|&node| get_steps_to(
directions, &nodes, node, |id| id % 26 == 25))
.fold(1 as u64, |acc, counter| lcm(acc, counter));
println!("{}", counter1);
println!("{}", counter2);
println!("Counter1: {}", counter1);
println!("Counter2: {}", counter2);
}