1
0
Fork 0
advent-of-code/2023/src/day06.rs

93 lines
2.1 KiB
Rust

use aoc_runner_derive::{aoc, aoc_generator};
struct Race {
time: u64,
distance: u64,
}
impl Race {
fn winning_times(&self) -> Vec<u64> {
let mut result: Vec<u64> = vec![];
for t in 0..=self.time {
if t * (self.time - t) > self.distance {
result.push(t);
}
}
result
}
}
#[aoc_generator(day6)]
fn parse(input: &str) -> Vec<Race> {
let mut lines = input.lines();
let times: Vec<u64> = lines.next().unwrap().split(": ").collect::<Vec<&str>>()[1]
.trim_start()
.split(" ")
.filter_map(|t| t.parse::<u64>().ok())
.collect();
let distances: Vec<u64> = lines.next().unwrap().split(": ").collect::<Vec<&str>>()[1]
.trim_start()
.split(" ")
.filter_map(|t| t.parse::<u64>().ok())
.collect();
assert_eq!(times.len(), distances.len());
(0..times.len())
.map(|i| Race {
time: times[i],
distance: distances[i],
})
.collect()
}
#[aoc(day6, part1)]
fn part1(input: &[Race]) -> u64 {
input
.iter()
.map(|race| race.winning_times().len() as u64)
.collect::<Vec<u64>>()
.iter()
.product()
}
#[aoc(day6, part2)]
fn part2(input: &[Race]) -> u64 {
let time = input
.iter()
.map(|race| race.time)
.collect::<Vec<u64>>()
.iter()
.map(|t| t.to_string())
.collect::<Vec<String>>()
.join("")
.parse::<u64>()
.unwrap();
let distance = input
.iter()
.map(|race| race.distance)
.collect::<Vec<u64>>()
.iter()
.map(|t| t.to_string())
.collect::<Vec<String>>()
.join("")
.parse::<u64>()
.unwrap();
let race = Race { time, distance };
race.winning_times().len() as u64
}
#[cfg(test)]
mod tests {
use super::*;
const SAMPLE_DATA: &'static str = r#"Time: 7 15 30
Distance: 9 40 200
"#;
#[test]
fn sample_data() {
let races = parse(&SAMPLE_DATA);
assert_eq!(part1(&races), 288);
assert_eq!(part2(&races), 71503);
}
}