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 :)
You must log in or register to comment.
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 aVec
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 aVec
, it can directly use the Iterator that came out of the.split()
. - Your
count_correct()
function takes theHashMap
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 toand 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.
I am not much familiar with Rust that’s why I am making these naive mistakes. Thank you for the suggestions though.
Yeah, no worries. I made these mistakes for quite a while, when I first learned it.
- Instead of