generated from fspoettel/advent-of-code-rust
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path06.rs
107 lines (88 loc) · 2.44 KB
/
06.rs
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use itertools::Itertools;
use joinery::JoinableIterator;
advent_of_code::solution!(6);
#[derive(Debug)]
struct Race {
time: u64,
distance: u64,
}
impl From<(u64, u64)> for Race {
fn from(value: (u64, u64)) -> Self {
Race {
time: value.0,
distance: value.1,
}
}
}
fn races_from_str(s: &str) -> Vec<Race> {
let mut parts = s.lines();
let times = parts
.next()
.expect("awlays a time line")
.split_ascii_whitespace()
.skip(1);
let distances: std::iter::Skip<std::str::SplitAsciiWhitespace<'_>> = parts
.next()
.expect("awlays a dist line")
.split_ascii_whitespace()
.skip(1);
times
.zip(distances)
.map(|(time, dist)| {
(
time.parse().expect("Time always a number"),
dist.parse().expect("Dist always a number"),
)
})
.map(Into::<Race>::into)
.collect_vec()
}
fn race_from_str_no_gaps(s: &str) -> Race {
let mut parts = s.lines();
let time = parts
.next()
.expect("awlays a time line")
.split_ascii_whitespace()
.skip(1)
.join_concat()
.to_string();
let distance = parts
.next()
.expect("awlays a dist line")
.split_ascii_whitespace()
.skip(1)
.join_concat()
.to_string();
Race {
time: time.parse().expect("Time always a number"),
distance: distance.parse().expect("Dist always a number"),
}
}
fn num_ways_to_beat_race(race: &Race) -> u64 {
(0..=race.time)
.map(|button_hold_time| button_hold_time * (race.time - button_hold_time))
.filter(|traveled_distance| *traveled_distance > race.distance)
.count() as u64
}
pub fn part_one(input: &str) -> Option<u64> {
let races = races_from_str(input);
Some(races.iter().map(num_ways_to_beat_race).product())
}
pub fn part_two(input: &str) -> Option<u64> {
let race = race_from_str_no_gaps(input);
Some(num_ways_to_beat_race(&race))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part_one() {
let result = part_one(&advent_of_code::template::read_file("examples/part1", DAY));
assert_eq!(result, Some(288));
}
#[test]
fn test_part_two() {
let result = part_two(&advent_of_code::template::read_file("examples/part2", DAY));
assert_eq!(result, Some(71503));
}
}