tangled
alpha
login
or
join now
jonas.tngl.sh
/
advent-of-code
0
fork
atom
Advent of Code solutions in Rust
0
fork
atom
overview
issues
pulls
pipelines
refactor: introduce `try_from_iter_exact` utility
jonas.tngl.sh
3 months ago
c0b97885
21cf9cc8
+39
-4
3 changed files
expand all
collapse all
unified
split
aoc_2020
src
day14.rs
aoc_2025
src
day12.rs
aoc_utils
src
array.rs
+1
-2
aoc_2020/src/day14.rs
···
63
63
type Err = anyhow::Error;
64
64
65
65
fn from_str(s: &str) -> Result<Self> {
66
66
-
// FIXME: This should use `try_from_iter_exact()`
67
67
-
aoc_utils::array::try_from_iter(s.chars().rev().map(|c| match c {
66
66
+
aoc_utils::array::try_from_iter_exact(s.chars().rev().map(|c| match c {
68
67
'X' => Ok(None),
69
68
'0' => Ok(Some(false)),
70
69
'1' => Ok(Some(true)),
+1
-2
aoc_2025/src/day12.rs
···
79
79
Ok::<_, ParseIntError>([x.parse()?, y.parse()?])
80
80
.with_context(|| anyhow!("failed to parse region dimenions {dimensions:?}"))
81
81
})?;
82
82
-
// TODO: add try_from_iter_exact
83
83
-
let presents = aoc_utils::array::try_from_iter(shapes.split_whitespace().map(|s| {
82
82
+
let presents = aoc_utils::array::try_from_iter_exact(shapes.split_whitespace().map(|s| {
84
83
s.parse()
85
84
.with_context(|| anyhow!("failed to parse present count {s:?}"))
86
85
}))?
+37
aoc_utils/src/array.rs
···
95
95
})
96
96
}
97
97
98
98
+
pub fn try_from_iter_exact<T, E, const N: usize>(
99
99
+
iter: impl IntoIterator<Item = Result<T, E>>,
100
100
+
) -> Result<Result<[T; N], Vec<T>>, E> {
101
101
+
let mut n = 0;
102
102
+
let mut fused = iter.into_iter().fuse();
103
103
+
let array: [_; N] = try_from_fn(|i| {
104
104
+
if let Some(elem) = fused.next() {
105
105
+
n = i + 1;
106
106
+
Ok(MaybeUninit::new(elem?))
107
107
+
} else {
108
108
+
Ok(MaybeUninit::uninit())
109
109
+
}
110
110
+
})?;
111
111
+
112
112
+
Ok(if n != N {
113
113
+
// received fewer elements from the iterator than N
114
114
+
Err(array
115
115
+
.into_iter()
116
116
+
.take(n)
117
117
+
.map(|x| unsafe { x.assume_init() })
118
118
+
.collect())
119
119
+
} else if let Some(extra) = fused.next() {
120
120
+
// received at least one more element than expected
121
121
+
let mut vec: Vec<T> = array
122
122
+
.into_iter()
123
123
+
.map(|x| unsafe { x.assume_init() })
124
124
+
.collect();
125
125
+
vec.push(extra?);
126
126
+
for extra in fused {
127
127
+
vec.push(extra?);
128
128
+
}
129
129
+
Err(vec)
130
130
+
} else {
131
131
+
Ok(array.map(|x| unsafe { x.assume_init() }))
132
132
+
})
133
133
+
}
134
134
+
98
135
pub fn try_map<T, U, E, const N: usize>(
99
136
array: [T; N],
100
137
f: impl FnMut(T) -> Result<U, E>,