Add day03

This commit is contained in:
Pedro de Oliveira 2023-05-05 20:42:09 +01:00
parent 4cda9b2765
commit 9399c2cc36
6 changed files with 143 additions and 0 deletions

7
Cargo.lock generated
View File

@ -190,6 +190,13 @@ dependencies = [
"criterion", "criterion",
] ]
[[package]]
name = "day03"
version = "0.1.0"
dependencies = [
"criterion",
]
[[package]] [[package]]
name = "either" name = "either"
version = "1.8.0" version = "1.8.0"

View File

@ -2,4 +2,5 @@
members = [ members = [
"day01", "day01",
"day02", "day02",
"day03",
] ]

11
day03/Cargo.toml Normal file
View File

@ -0,0 +1,11 @@
[package]
name = "day03"
version = "0.1.0"
edition = "2021"
[dev-dependencies]
criterion = "0.4.0"
[[bench]]
name = "day03"
harness = false

27
day03/benches/day03.rs Normal file
View File

@ -0,0 +1,27 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use ::day03::{parse_input_part1, parse_input_part2, count_valid};
pub fn criterion_benchmark(c: &mut Criterion) {
let input = include_str!("../../input/day03.txt");
c.bench_function("day03 parse_input_part1", |b| {
b.iter(|| parse_input_part1(black_box(input)))
});
c.bench_function("day03 parse_input_part2", |b| {
b.iter(|| parse_input_part2(black_box(input)))
});
let input_part1 = parse_input_part1(input);
c.bench_function("day03 solve_part1", |b| {
b.iter(|| count_valid(black_box(&input_part1)))
});
let input_part2 = parse_input_part2(input);
c.bench_function("day03 solve_part2", |b| {
b.iter(|| count_valid(black_box(&input_part2)))
});
}
criterion_group!{
name = benches;
config = Criterion::default().sample_size(1000);
targets = criterion_benchmark
}
criterion_main!(benches);

63
day03/src/lib.rs Normal file
View File

@ -0,0 +1,63 @@
pub struct Triangle {
a: u16,
b: u16,
c: u16,
}
impl Triangle {
fn new(a: u16, b: u16, c: u16) -> Self {
Triangle { a, b, c }
}
fn is_valid(&self) -> bool {
(self.a + self.b > self.c) && (self.a + self.c > self.b) && (self.b + self.c > self.a)
}
}
pub fn parse_input_part1(input: &str) -> Vec<Triangle> {
input
.lines()
.map(|line| {
let sides = std::str::from_utf8(line.as_bytes())
.unwrap()
.split_whitespace()
.filter_map(|s| s.parse().ok())
.collect::<Vec<u16>>();
match sides.as_slice() {
[a, b, c] => Triangle::new(*a, *b, *c),
_ => panic!("Parse error"),
}
})
.collect()
}
pub fn parse_input_part2(input: &str) -> Vec<Triangle> {
let mut sides = [[0u16; 3]; 3];
input
.lines()
.enumerate()
.flat_map(|(i, line)| {
let numbers: Vec<u16> = line
.split_whitespace()
.map(|n| n.parse().unwrap())
.collect();
numbers.iter().enumerate().for_each(|(j, number)| {
sides[i % 3][j] = *number;
});
if i % 3 == 2 {
let triangles: Vec<Triangle> = (0..3)
.map(|j| Triangle::new(sides[0][j], sides[1][j], sides[2][j]))
.collect();
return triangles.into_iter();
}
Vec::new().into_iter()
})
.collect()
}
pub fn count_valid(triangles: &[Triangle]) -> u16 {
triangles.iter().filter(|t| t.is_valid()).count() as u16
}

34
day03/src/main.rs Normal file
View File

@ -0,0 +1,34 @@
use ::day03::{parse_input_part1, parse_input_part2, count_valid};
fn main() {
let input = include_str!("../../input/day03.txt");
let part1_input = parse_input_part1(input);
let part1 = count_valid(&part1_input);
println!("Part1: {}", part1);
let part2_input = parse_input_part2(input);
let part2 = count_valid(&part2_input);
println!("Part2: {}", part2);
}
#[cfg(test)]
mod day03 {
use ::day03::{parse_input_part1, parse_input_part2, count_valid};
const INPUT1: &str = "5 10 25";
const INPUT2: &str = r#"101 301 501
102 302 502
103 303 503
201 401 601
202 402 602
203 403 603"#;
#[test]
fn part1_test() {
assert_eq!(count_valid(&parse_input_part1(INPUT1)), 0);
}
#[test]
fn part2_test() {
assert_eq!(count_valid(&parse_input_part2(INPUT2)), 6);
}
}