-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
main.rs
85 lines (78 loc) · 2.48 KB
/
main.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
use regex::Regex;
use std::collections::{HashMap, HashSet};
pub fn main() {
let re = Regex::new(r#"^(.*): (\d+)-(\d+) or (\d+)-(\d+)$"#).unwrap();
let input = include_str!("../input.txt");
let rules: Vec<(usize, usize, usize, usize, &str)> = input
.lines()
.take_while(|l| !l.is_empty())
.map(|rule| {
let cap = re.captures(rule).unwrap();
(
cap[2].parse::<usize>().unwrap(),
cap[3].parse::<usize>().unwrap(),
cap[4].parse::<usize>().unwrap(),
cap[5].parse::<usize>().unwrap(),
cap.get(1).unwrap().as_str(),
)
})
.collect();
let my_ticket = tickets("your ticket:", &input).next().unwrap();
let tickets: Vec<_> = tickets("nearby tickets:", &input)
.filter(|t| {
t.iter().all(|&f| {
rules
.iter()
.any(|r| (f >= r.0 && f <= r.1) || (f >= r.2 && f <= r.3))
})
})
.collect();
#[rustfmt::skip]
let mut rule_fields: HashMap<_, HashSet<_>> = rules
.iter()
.map(|f| (
f.4, (0..tickets[0].len())
.filter(|i| {
tickets
.iter()
.map(|t| t[*i])
.filter(|&v| (v >= f.0 && v <= f.1) || (v >= f.2 && v <= f.3))
.count()
== tickets.len()
})
.collect(),
))
.collect();
let mut map = vec![""; rules.len()];
for _ in 0..map.len() {
let (&name, p) = rule_fields
.iter()
.filter(|(_, p)| p.len() == 1)
.next()
.unwrap();
let pos = p.iter().next().unwrap().clone();
map[pos] = name;
rule_fields.values_mut().for_each(|p| {
p.remove(&pos);
});
rule_fields.remove(&name);
}
println!(
"{}",
my_ticket
.into_iter()
.enumerate()
.map(|(i, v)| (map[i], v))
.filter(|(f, _)| f.starts_with("dep"))
.map(|(_, v)| v)
.product::<usize>()
);
}
fn tickets(header: &'static str, input: &'static str) -> impl Iterator<Item = Vec<usize>> {
input
.lines()
.skip_while(move |&t| t != header)
.skip(1)
.take_while(|t| !t.is_empty())
.map(|t| t.split(',').map(|f| f.parse().unwrap()).collect())
}