1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
use nom::{
bytes::complete::tag,
character::complete::{line_ending, space1, u64 as nom_u64},
combinator::map,
multi::separated_list1,
sequence::tuple,
IResult,
};
use std::fs;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let input = fs::read_to_string("inputs/day_6.txt")?;
let parsed = RacePlan::multi_parser(&input).unwrap().1;
for plan in parsed {
dbg!(&plan.win_count_product());
}
Ok(())
}
#[derive(Debug)]
struct RacePlan(Vec<RaceRecord>);
#[derive(Debug)]
struct RaceRecord {
time: u64,
distance: u64,
}
impl RacePlan {
fn multi_parser(input: &str) -> IResult<&str, Vec<Self>> {
separated_list1(line_ending, RacePlan::parser)(input)
}
fn parser(input: &str) -> IResult<&str, Self> {
map(
tuple((
tag("Time:"),
space1,
separated_list1(space1, nom_u64),
line_ending,
tag("Distance:"),
space1,
separated_list1(space1, nom_u64),
)),
|(_, _, times, _, _, _, distances)| {
RacePlan(
times
.into_iter()
.zip(distances.into_iter())
.map(|(time, distance)| RaceRecord { time, distance })
.collect(),
)
},
)(input)
}
fn win_count_product(&self) -> usize {
self.0.iter().map(|r| r.count_wins()).product()
}
}
impl RaceRecord {
fn count_wins(&self) -> usize {
(1..self.time)
.map(|charge_time| charge_time * (self.time - charge_time))
.filter(|distance| *distance > self.distance)
.count()
}
}
|