-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.rs
71 lines (62 loc) · 1.83 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
use std::{collections::HashMap, str::FromStr};
type ValveId = u8;
#[derive(Debug)]
struct Valve {
id: ValveId,
opened: bool,
flow_rate: u8,
leads_to: Vec<ValveId>,
}
#[derive(Debug)]
struct Tunnel {
valves: HashMap<ValveId, Valve>,
current_valve: ValveId,
remaining_time: u8,
current_rate: u8,
}
impl FromStr for Valve {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let err = || -> Self::Err { format!("`{s}` is invalid") };
let s = s.strip_prefix("Valve ").ok_or_else(err)?;
let id = s[..=2].bytes().sum();
let s = s[2..].strip_prefix(" has flow rate=").ok_or_else(err)?;
let (flow_rate, valves) = s.split_once(';').ok_or_else(err)?;
let flow_rate = flow_rate
.parse()
.map_err(|_| format!("`{flow_rate}` is not a valid number"))?;
let valves = valves
.replace("tunnel ", "tunnels ")
.replace("leads ", "lead ")
.replace("valve ", "valves ");
let valves = valves
.strip_prefix(" tunnels lead to valves ")
.ok_or_else(err)?;
let leads_to = valves.split(", ").map(|str| str.bytes().sum()).collect();
Ok(Self {
id,
opened: false,
flow_rate,
leads_to,
})
}
}
impl FromStr for Tunnel {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let valves = s
.lines()
.map(|l| Valve::from_str(l).map(|v| (v.id, v)))
.collect::<Result<_, _>>()?;
Ok(Self {
valves,
current_valve: b'a' * 2,
current_rate: 0,
remaining_time: 30,
})
}
}
fn main() {
let tunnel = Tunnel::from_str(include_str!("../test_input.txt")).unwrap();
println!("{tunnel:#?}");
}