-
Notifications
You must be signed in to change notification settings - Fork 0
/
2015-12-09.rs
131 lines (101 loc) · 3.6 KB
/
2015-12-09.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//! Day 9: All in a Single Night
use std::{collections::HashSet, str::FromStr};
use aoc_ornaments::{linear::Distances, Part, Solution};
#[derive(Debug, derive_more::Deref)]
struct Day(Distances<u32>);
impl FromStr for Day {
type Err = miette::Error;
fn from_str(input: &str) -> miette::Result<Self> {
Ok(Self(input.lines()
.fold(Distances::new(), |mut map, line| {
let parts: Vec<&str> = line.split(' ').collect();
match parts.as_slice() {
[a, "to", b, "=", d] => {
let distance = d.parse().unwrap();
map.insert_ordered(a.to_string(), b.to_string(), distance);
},
_ => panic!("Invalid input"),
}
map
})))
}
}
impl Day {
}
impl Solution for Day {
type Output = u32;
fn part1(&mut self) -> miette::Result<Self::Output> {
let cities = self.get_unique_cities();
let mut overall_shortest = None;
// Try each city as a starting point
for start in cities.iter() {
let mut remaining: HashSet<_> = cities
.iter()
.filter(|&city| city != start)
.copied()
.collect();
let mut path_shortest = None;
self.find_shortest_path(start, &mut remaining, 0, &mut path_shortest);
// Update overall shortest if this path is shorter
if let Some(path_len) = path_shortest {
overall_shortest = match overall_shortest {
None => Some(path_len),
Some(current_shortest) => Some(current_shortest.min(path_len))
};
}
}
Ok(overall_shortest.unwrap())
}
fn part2(&mut self) -> miette::Result<Self::Output> {
let cities = self.get_unique_cities();
let mut overall_longest = None;
// Try each city as a starting point
for start in cities.iter() {
let mut remaining: HashSet<_> = cities
.iter()
.filter(|&city| city != start)
.copied()
.collect();
let mut path_longest = None;
self.find_longest_path(start, &mut remaining, 0, &mut path_longest);
// Update overall shortest if this path is longer
if let Some(path_len) = path_longest {
overall_longest = match overall_longest {
None => Some(path_len),
Some(current_shortest) => Some(current_shortest.max(path_len))
};
}
}
Ok(overall_longest.unwrap())
}
}
fn main() -> miette::Result<()> {
let mut day = Day::from_str(include_str!("./inputs/2015-12-09.txt"))?;
let part1 = day.solve(Part::One)?;
let part2 = day.solve(Part::Two)?;
println!("Part 1: {}", part1);
println!("Part 2: {}", part2);
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() {
let input = "London to Dublin = 464
London to Belfast = 518
Dublin to Belfast = 141";
let mut day = Day::from_str(input).unwrap();
let result = day.solve(Part::One).unwrap();
assert_eq!(result, "605");
}
#[test]
fn test_part2() {
let input = "London to Dublin = 464
London to Belfast = 518
Dublin to Belfast = 141";
let mut day = Day::from_str(input).unwrap();
let result = day.solve(Part::Two).unwrap();
assert_eq!(result, "982");
}
}