Context
I'm doing Advent of Code as a way of learning Rust, and have a working solution to Day 8, Part 1. This involves moving between nodes, starting at AAA
and looking for ZZZ
, where the next node is determined by the L/R instruction chain in the first line. We loop over the L/R instruction set until ZZZ
is found. Some of the example input is given below.
RL
AAA = (BBB, CCC)
BBB = (DDD, EEE)
CCC = (ZZZ, GGG)
DDD = (DDD, DDD)
I think the logic I used here is ok, but I expect my code to the solution does not take advantage of Rust's strengths. I know, for example, that I am being lazy by using .unwrap()
instead of handling an Option.
My Code
use regex::Regex;
use std::collections::HashMap;
use std::fs;
const FILE: &str = "../inputs/day8_1.txt";
fn parse_inputs(filename: &str) -> (Vec<char>, HashMap<String, Vec<String>>) {
let mut node_map: HashMap<String, Vec<String>> = HashMap::new();
let file = fs::read_to_string(filename).expect("File read failure");
let (directions, nodes) = file.split_once("\n\n").unwrap();
let rgx = Regex::new(r"(\w{3})").unwrap();
for line in nodes.lines() {
let matches: Vec<String> = rgx
.find_iter(line)
.map(|x| x.as_str().to_string())
.collect();
node_map.insert(
matches[0].clone(),
vec![matches[1].clone(), matches[2].clone()],
);
}
(directions.chars().collect::<Vec<char>>(), node_map)
}
fn main () {
let mut step_count: u32 = 0;
let mut point = "AAA".to_string();
let (directions, data) = parse_inputs(FILE);
let direction_map = HashMap::from([('L', 0), ('R', 1)]);
let mut indexer: usize = 0;
let max_index = directions.len() - 1;
while point != "ZZZ".to_string() {
let d: usize = direction_map[&directions[indexer]];
point = data[&point][d].clone();
if indexer < max_index {
indexer += 1;
} else {
indexer = 0;
}
step_count += 1
}
println!("Part One: {:?}", step_count)
}
Review Request
I'm looking for advice on how this code might follow a more idiomatic Rust style. I think I am probably brute forcing my way through the compiler here, as I'm having to clone values to get past the borrowing rules. I suspect that I could write the code in a more intelligent way to avoid cloning. I also know that I could (and should) actually handle errors and options, but I'm not sure how best to do that here.