aoc-2021/d01/src/main.rs

138 lines
4.3 KiB
Rust

use std::collections::VecDeque;
use std::fs::File;
use std::io::{self, BufRead};
use std::path::Path;
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
where
P: AsRef<Path>,
{
let file = File::open(filename)?;
Ok(io::BufReader::new(file).lines())
}
fn part1() {
// My naiive attempt
if let Ok(lines) = read_lines("input.txt") {
let mut last_val: Option<i32> = None;
let mut num_increase = 0;
for line in lines {
if let Ok(l) = line {
match l.parse::<i32>() {
Ok(val) => {
let increase;
match last_val {
Some(last_val) => increase = last_val < val,
None => increase = false,
}
// println!("{}: {}", val, increase);
if increase {
num_increase += 1;
}
last_val = Some(val);
}
Err(e) => println!("ERROR: Could not parse {}. {}", l, e),
}
}
}
println!("Part 1, All done! Num increased {}", num_increase);
}
}
fn part1mr() {
// Something more functional
let mut last_val: Option<i32> = None;
let num_increase = read_lines("input.txt")
.expect("Expected a file to read")
.map(|line| line.expect("Could not read line"))
.map(|line| {
line.parse::<i32>()
.expect(format!("Error parsing '{}' as in int", line).as_str())
})
.map(|value| {
let mut increase = 0;
if let Some(last_val) = last_val {
if value > last_val {
increase = 1;
}
}
last_val = Some(value);
increase
})
.reduce(|num_increase, increase| num_increase + increase);
println!(
"Part 1 new, All done! Num increased {}",
num_increase.unwrap()
);
}
fn part2() {
if let Ok(lines) = read_lines("input.txt") {
let mut num_increase = 0;
// If we have 3 values, pop from front and compare new number to the one read before
// pushing that to the back. If that is an increase, increment the increase value
let mut sliding_values: VecDeque<i32> = VecDeque::with_capacity(3);
for line in lines {
if let Ok(l) = line {
match l.parse::<i32>() {
Ok(val) => {
if sliding_values.len() < 3 {
sliding_values.push_back(val);
continue;
}
let outgoing = sliding_values.pop_front().unwrap();
let increase = val > outgoing;
if increase {
num_increase += 1;
}
sliding_values.push_back(val);
// println!("{}: {}", val, increase);
}
Err(e) => println!("ERROR: Could not parse {}. {}", l, e),
}
}
}
println!("All done! Num increased {}", num_increase);
}
}
fn part2mr() {
let mut sliding_values: VecDeque<i32> = VecDeque::with_capacity(3);
let num_increase = read_lines("input.txt")
.expect("Expected a file to read")
.map(|line| line.expect("Could not read line"))
.map(|line| {
line.parse::<i32>()
.expect(format!("Error parsing '{}' as in int", line).as_str())
})
.map(|value| {
let mut increase = 0;
if sliding_values.len() < 3 {
sliding_values.push_back(value);
} else {
let outgoing = sliding_values.pop_front().unwrap();
if value > outgoing {
increase = 1;
}
sliding_values.push_back(value);
}
increase
})
.reduce(|num_increase, increase| num_increase + increase);
println!(
"Part 2 new, All done! Num increased {}",
num_increase.unwrap()
);
}
fn main() {
part1();
part1mr();
part2();
part2mr();
}