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
|
use crate::prelude::*;
pub fn data(year: u16, day: u16) -> Result<File> {
File::open(format!("data/{}/{}.txt", year, day)).map_err(|e| anyhow!(e))
}
pub fn lines(fh: File) -> impl Iterator<Item = String> {
let fh = std::io::BufReader::new(fh);
fh.lines().map(|res| res.unwrap())
}
pub fn split(fh: File, sep: u8) -> impl Iterator<Item = String> {
let fh = std::io::BufReader::new(fh);
fh.split(sep)
.map(|res| String::from_utf8(res.unwrap()).unwrap())
}
pub fn ints(iter: impl Iterator<Item = String>) -> impl Iterator<Item = i64> {
iter.map(|s| s.trim().parse().unwrap())
}
pub fn bytes(fh: File) -> impl Iterator<Item = u8> {
fh.bytes().map(|res| res.unwrap())
}
pub fn string(fh: File) -> String {
let bytes: Vec<_> = bytes(fh).collect();
String::from_utf8(bytes).unwrap()
}
pub fn bool_grid(
lines: impl Iterator<Item = String>,
t: u8,
f: u8,
) -> Grid<bool> {
lines
.map(|s| {
s.as_bytes()
.iter()
.copied()
.map(|b| {
if b == f {
false
} else if b == t {
true
} else {
panic!("unrecognized character {}", char::from(b))
}
})
.collect::<Vec<_>>()
})
.collect()
}
pub fn digit_grid(lines: impl Iterator<Item = String>) -> Grid<u8> {
lines
.map(|s| {
s.as_bytes()
.iter()
.copied()
.map(|b| b - b'0')
.collect::<Vec<_>>()
})
.collect()
}
// false positive, doing its suggestion gives borrow checker errors
#[allow(clippy::redundant_closure)]
pub fn grid<F, T>(lines: impl Iterator<Item = String>, f: F) -> Grid<T>
where
F: Fn(u8) -> T,
T: Clone + Default + Eq + PartialEq,
{
lines
.map(|s| {
s.as_bytes()
.iter()
.copied()
.map(|b| f(b))
.collect::<Vec<_>>()
})
.collect()
}
|