1use crate::util::hash::*;
22use crate::util::iter::*;
23use crate::util::parse::*;
24use crate::util::slice::*;
25
26type Result = (u32, u32);
27
28pub fn parse(input: &str) -> Result {
29 let tokens: Vec<_> = input.split_ascii_whitespace().chunk::<5>().collect();
30 let mut indices = FastMap::new();
31
32 for [start, _, end, ..] in &tokens {
33 let size = indices.len();
34 indices.entry(start).or_insert(size);
35
36 let size = indices.len();
37 indices.entry(end).or_insert(size);
38 }
39
40 let stride = indices.len();
41 let mut distances = vec![0; stride * stride];
42
43 for [start, _, end, _, distance] in &tokens {
44 let start = indices[start];
45 let end = indices[end];
46 let distance = distance.unsigned();
47
48 distances[stride * start + end] = distance;
49 distances[stride * end + start] = distance;
50 }
51
52 let mut global_min = u32::MAX;
53 let mut global_max = u32::MIN;
54 let mut indices: Vec<_> = (1..stride).collect();
55
56 indices.permutations(|slice| {
57 let mut sum = 0;
58 let mut local_min = u32::MAX;
59 let mut local_max = u32::MIN;
60
61 let mut trip = |from, to| {
62 let distance = distances[stride * from + to];
63 sum += distance;
64 local_min = local_min.min(distance);
65 local_max = local_max.max(distance);
66 };
67
68 trip(0, slice[0]);
69 trip(0, slice[slice.len() - 1]);
70
71 for i in 1..slice.len() {
72 trip(slice[i], slice[i - 1]);
73 }
74
75 global_min = global_min.min(sum - local_max);
76 global_max = global_max.max(sum - local_min);
77 });
78
79 (global_min, global_max)
80}
81
82pub fn part1(input: &Result) -> u32 {
83 input.0
84}
85
86pub fn part2(input: &Result) -> u32 {
87 input.1
88}