Rust Day 4
Now with tests, very neat
This commit is contained in:
parent
d4643c00d2
commit
80e9066b1d
6 changed files with 1144 additions and 3 deletions
2
rust/Cargo.lock
generated
2
rust/Cargo.lock
generated
|
@ -4,4 +4,4 @@ version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "advent-of-code"
|
name = "advent-of-code"
|
||||||
version = "22.3.2"
|
version = "22.4.2"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "advent-of-code"
|
name = "advent-of-code"
|
||||||
version = "22.3.2"
|
version = "22.4.2"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
|
@ -37,4 +37,8 @@ path = "src/day02/main.rs"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "day03"
|
name = "day03"
|
||||||
path = "src/day03/main.rs"
|
path = "src/day03/main.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "day04"
|
||||||
|
path = "src/day04/main.rs"
|
||||||
|
|
1000
rust/src/day04/input.txt
Normal file
1000
rust/src/day04/input.txt
Normal file
File diff suppressed because it is too large
Load diff
34
rust/src/day04/main.rs
Normal file
34
rust/src/day04/main.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
const INPUT: &str = include_str!("input.txt");
|
||||||
|
|
||||||
|
mod part_1;
|
||||||
|
use part_1::part_1;
|
||||||
|
mod part_2;
|
||||||
|
use part_2::part_2;
|
||||||
|
|
||||||
|
fn parse_input() -> Vec<[[u32; 2]; 2]> {
|
||||||
|
INPUT
|
||||||
|
.lines()
|
||||||
|
.map(|line| {
|
||||||
|
let pairs = line
|
||||||
|
.split(',')
|
||||||
|
.take(2)
|
||||||
|
.map(|v| {
|
||||||
|
let boundary = v
|
||||||
|
.split('-')
|
||||||
|
.map(|v| v.parse::<u32>().expect("Non-numerical value in input"))
|
||||||
|
.take(2)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
assert_eq!(boundary.len(), 2);
|
||||||
|
[boundary[0], boundary[1]]
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
assert_eq!(pairs.len(), 2);
|
||||||
|
[pairs[0], pairs[1]]
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
part_1(&parse_input());
|
||||||
|
part_2(&parse_input());
|
||||||
|
}
|
54
rust/src/day04/part_1.rs
Normal file
54
rust/src/day04/part_1.rs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#[inline(always)]
|
||||||
|
fn sections_contain_each_other(sections: [[u32; 2]; 2]) -> bool {
|
||||||
|
let start_1 = sections[0][0];
|
||||||
|
let end_1 = sections[0][1];
|
||||||
|
let start_2 = sections[1][0];
|
||||||
|
let end_2 = sections[1][1];
|
||||||
|
|
||||||
|
(start_1 <= start_2 && end_1 >= end_2) || (start_1 >= start_2 && end_1 <= end_2)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn part_1(input: &[[[u32; 2]; 2]]) -> usize {
|
||||||
|
let times_contained = input
|
||||||
|
.iter()
|
||||||
|
.filter(|sections| sections_contain_each_other(**sections))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.len();
|
||||||
|
println!("Part 1: {times_contained}");
|
||||||
|
times_contained
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_containment() {
|
||||||
|
for num in 0..=1024u32 {
|
||||||
|
assert!(sections_contain_each_other([[num, num], [num, num]]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for num_a in 0..=1024u32 {
|
||||||
|
for num_b in num_a..=1024u32 {
|
||||||
|
assert!(sections_contain_each_other([
|
||||||
|
[num_a, num_b],
|
||||||
|
[num_b, num_b]
|
||||||
|
]));
|
||||||
|
assert!(sections_contain_each_other([
|
||||||
|
[num_a, num_b],
|
||||||
|
[num_a, num_b]
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for num_a in 0..=1024u32 {
|
||||||
|
for num_b in num_a + 1u32..=num_a + 1024u32 {
|
||||||
|
assert!(!sections_contain_each_other([
|
||||||
|
[num_a, num_a],
|
||||||
|
[num_b, num_b]
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert!(!sections_contain_each_other([[1, 3], [3, 83]]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_with_solution() {
|
||||||
|
assert_eq!(part_1(&crate::parse_input()), 584);
|
||||||
|
}
|
49
rust/src/day04/part_2.rs
Normal file
49
rust/src/day04/part_2.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#[inline(always)]
|
||||||
|
fn sections_overlap(sections: [[u32; 2]; 2]) -> bool {
|
||||||
|
let start_1 = sections[0][0];
|
||||||
|
let end_1 = sections[0][1];
|
||||||
|
let start_2 = sections[1][0];
|
||||||
|
let end_2 = sections[1][1];
|
||||||
|
|
||||||
|
(start_1 <= end_2 && end_1 >= start_2) || (start_1 >= end_2 && end_1 <= start_2)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn part_2(input: &[[[u32; 2]; 2]]) -> usize {
|
||||||
|
let times_overlapped = input
|
||||||
|
.iter()
|
||||||
|
.filter(|sections| sections_overlap(**sections))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.len();
|
||||||
|
println!("Part 2: {times_overlapped}");
|
||||||
|
times_overlapped
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_overlap() {
|
||||||
|
for num in 0..=1024u32 {
|
||||||
|
assert!(sections_overlap([[num, num], [num, num]]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for num_a in 0..=1024u32 {
|
||||||
|
for num_b in num_a..=1024u32 {
|
||||||
|
assert!(
|
||||||
|
sections_overlap([[num_a, num_b], [num_b, num_b]]),
|
||||||
|
"{:?}",
|
||||||
|
[[num_a, num_b], [num_b, num_b]]
|
||||||
|
);
|
||||||
|
assert!(sections_overlap([[num_a, num_b], [num_a, num_b]]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for num_a in 0..=1024u32 {
|
||||||
|
for num_b in num_a + 1u32..=num_a + 1024u32 {
|
||||||
|
assert!(!sections_overlap([[num_a, num_a], [num_b, num_b]]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert!(sections_overlap([[1, 3], [3, 83]]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_with_solution() {
|
||||||
|
assert_eq!(part_2(&crate::parse_input()), 933);
|
||||||
|
}
|
Loading…
Reference in a new issue