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 :)

  • Ephera@lemmy.ml
    link
    fedilink
    English
    arrow-up
    2
    ·
    11 days ago

    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.
    • whoareuOP
      link
      fedilink
      arrow-up
      2
      ·
      11 days ago

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

      • Ephera@lemmy.ml
        link
        fedilink
        English
        arrow-up
        2
        ·
        11 days ago

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