Dag 2 voltooid, niet prachtig, maar het voldoet
This commit is contained in:
6
advent_of_code/2024/2/Cargo.toml
Normal file
6
advent_of_code/2024/2/Cargo.toml
Normal file
@@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "main"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
1000
advent_of_code/2024/2/input.txt
Normal file
1000
advent_of_code/2024/2/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
157
advent_of_code/2024/2/src/main.rs
Normal file
157
advent_of_code/2024/2/src/main.rs
Normal file
@@ -0,0 +1,157 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
fn distance<T>(a: T, b: T) -> T
|
||||
where
|
||||
T: Ord + std::ops::Sub<Output = T>,
|
||||
{
|
||||
if a < b {
|
||||
return b - a;
|
||||
} else {
|
||||
return a - b;
|
||||
}
|
||||
}
|
||||
|
||||
fn check_line_safety_1(line: &Vec<u32>) -> bool {
|
||||
let len = line.len();
|
||||
let mut prev = line[0];
|
||||
let up_or_down = line[0] < line[1];
|
||||
|
||||
for i in 1..len {
|
||||
if prev == line[i] {
|
||||
return false;
|
||||
}
|
||||
|
||||
let dist = distance(prev, line[i]);
|
||||
if dist < 1 || dist > 3 {
|
||||
return false;
|
||||
}
|
||||
|
||||
if up_or_down && prev > line[i] {
|
||||
return false;
|
||||
} else if !up_or_down && prev < line[i] {
|
||||
return false;
|
||||
}
|
||||
|
||||
prev = line[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
fn solve_1(input: &str) -> u32 {
|
||||
let data: Vec<Vec<u32>> = input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
line.split_whitespace()
|
||||
.map(|number| number.parse::<u32>().unwrap())
|
||||
.collect()
|
||||
})
|
||||
.collect();
|
||||
|
||||
return data.into_iter().filter(check_line_safety_1).count() as u32;
|
||||
}
|
||||
|
||||
fn check_line_safety_2(line: &Vec<u32>) -> bool {
|
||||
let len = line.len();
|
||||
let mut prev = line[0];
|
||||
let mut ups: HashSet<usize> = HashSet::new();
|
||||
let mut downs: HashSet<usize> = HashSet::new();
|
||||
let mut distance_violations: HashSet<usize> = HashSet::new();
|
||||
|
||||
for i in 1..len {
|
||||
let dist = distance(prev, line[i]);
|
||||
|
||||
if dist < 1 || dist > 3 {
|
||||
distance_violations.insert(i);
|
||||
}
|
||||
|
||||
if prev < line[i] {
|
||||
ups.insert(i);
|
||||
} else if prev > line[i] {
|
||||
downs.insert(i);
|
||||
}
|
||||
|
||||
prev = line[i];
|
||||
}
|
||||
|
||||
if ups.len() > 2 && downs.len() > 2 {
|
||||
return false;
|
||||
}
|
||||
if distance_violations.len() > 2 {
|
||||
return false;
|
||||
} else if distance_violations.len() == 0 && (ups.len() == 0 || downs.len() == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let minor = if ups.len() > downs.len() {
|
||||
downs.clone()
|
||||
} else {
|
||||
ups.clone()
|
||||
};
|
||||
|
||||
let union: HashSet<_> = minor.union(&distance_violations).to_owned().collect();
|
||||
if union.len() == 1 {
|
||||
let mut line_copy_1 = line.clone();
|
||||
let mut line_copy_2 = line.clone();
|
||||
let delete_spot = *union.into_iter().next().unwrap();
|
||||
|
||||
line_copy_1.remove(delete_spot);
|
||||
line_copy_2.remove(delete_spot - 1);
|
||||
|
||||
return check_line_safety_1(&line_copy_1) || check_line_safety_1(&line_copy_2);
|
||||
} else {
|
||||
let mut line_copy_1 = line.clone();
|
||||
let mut line_copy_2 = line.clone();
|
||||
let mut line_iter = union.into_iter();
|
||||
|
||||
line_copy_1.remove(*line_iter.next().unwrap());
|
||||
line_copy_2.remove(*line_iter.next().unwrap());
|
||||
|
||||
return check_line_safety_1(&line_copy_1) || check_line_safety_1(&line_copy_2);
|
||||
}
|
||||
}
|
||||
|
||||
fn solve_2(input: &str) -> u32 {
|
||||
let data: Vec<Vec<u32>> = input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
line.split_whitespace()
|
||||
.map(|number| number.parse::<u32>().unwrap())
|
||||
.collect()
|
||||
})
|
||||
.collect();
|
||||
|
||||
return data.into_iter().filter(check_line_safety_2).count() as u32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Hello, this is Patrick!");
|
||||
|
||||
let input = include_str!("../input.txt");
|
||||
|
||||
let result_1 = solve_1(input);
|
||||
println!("The number of safe reports is {}", result_1);
|
||||
|
||||
let result_2 = solve_2(input);
|
||||
println!("The number of safe reports (version 2) is {}", result_2);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_1() {
|
||||
let test_input = include_str!("../test.txt");
|
||||
|
||||
assert_eq!(solve_1(test_input), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_2() {
|
||||
let test_input = include_str!("../test.txt");
|
||||
|
||||
assert_eq!(solve_2(test_input), 4);
|
||||
}
|
||||
}
|
||||
6
advent_of_code/2024/2/test.txt
Normal file
6
advent_of_code/2024/2/test.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
7 6 4 2 1
|
||||
1 2 7 8 9
|
||||
9 7 6 2 1
|
||||
1 3 2 4 5
|
||||
8 6 4 4 1
|
||||
1 3 6 7 9
|
||||
Reference in New Issue
Block a user