this post was submitted on 30 Dec 2024
2 points (75.0% liked)

Advent of Code

295 readers
1 users here now

Advent of Code is an annual Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.

https://adventofcode.com

founded 2 years ago
MODERATORS
 
use std::fs;
use std::collections::HashMap;

fn count_correct(rules_hash_map: HashMap<&str, Vec<&str>>, page_numbers: &str) -> bool{
        let tmp = page_numbers.split(",").collect::<Vec<&str>>();
        for i in 0..tmp.len()-1 {
            for j in i+1..tmp.len() {
                match rules_hash_map.get(&tmp[i]) {
                    Some(vec) => {
                        if !vec.contains(&tmp[j]) {
                            return false;
                        }
                    }
                    None => {
                        return false;
                    }
                }
            }
        }
    

    return true;
}

fn main() {
    let contents = fs::read_to_string("input.txt")
        .expect("Should have been able to read the file");
    let parts = contents.split("\n\n").collect::<Vec<&str>>();
    let rules = parts[0];
    let page_numbers = parts[1];
    let mut rules_hash_map: HashMap<&str, Vec<&str>> = HashMap::new();

    for rule in rules.split("\n") {
        let tmp = rule.split("|").collect::<Vec<&str>>();
        rules_hash_map.entry(tmp[0]).and_modify(|vec| vec.push(tmp[1])).or_insert(vec![tmp[1]]);
    }

    let mut count = 0;
    let mut answer = 0;
    for page_numbers_line in page_numbers.split("\n").collect::<Vec<&str>>() {
        if page_numbers_line.len() == 0 {
            break;
        }
        let ok = count_correct(rules_hash_map.clone(), page_numbers_line);
        if ok {
            let tmp = page_numbers_line.split(",").collect::<Vec<&str>>();
            answer += tmp[tmp.len()/2].parse::<i32>().expect("parsing error");
            count += 1;
        }
    }

    println!("true_count: {count}");
    println!("answer: {answer}");
}

any suggestions would be appreciated :)

top 3 comments
sorted by: hot top controversial new old
[–] [email protected] 2 points 3 weeks ago (1 children)

The Playground doesn't run without the input.txt file, so I haven't tested these points beyond compiling them. And I also don't know what the exercise was. But in terms of superficial code style:

  • Instead of .split("\n"), you can also do .lines(). I'm guessing, in this case, it makes no difference, but .lines() handles line endings correctly for Windows, too.
  • In your main-function where you're iterating over page_numbers, you don't want to .collect() right afterwards. The .split() has turned it into an iterator, then the collect turns it back into a Vec and then the for-loop implicitly adds a .iter() afterwards, because it needs to turn it back into an iterator to loop through it. If you just don't collect into a Vec, it can directly use the Iterator that came out of the .split().
  • Your count_correct() function takes the HashMap as an owned value. Generally, you want your functions to take parameters as a reference, unless you actually need the ownership. So, if you change that to &HashMap and then change where you call it to count_correct(&rules_hash_map, page_numbers_line), then it works the same. In particular, cloning a whole HashMap in every cycle of the loop can use rather many resources. But cloning when you don't need to, can also lead to logical mistakes, as you might end up updating one clone of the HashMap, not realizing why it's not being updated everywhere.
[–] [email protected] 2 points 3 weeks ago (1 children)

I am not much familiar with Rust that's why I am making these naive mistakes. Thank you for the suggestions though.

[–] [email protected] 2 points 3 weeks ago

Yeah, no worries. I made these mistakes for quite a while, when I first learned it.