Skip to content

Commit 6f7dd2c

Browse files
committed
Extract "fold_decimal" method to slice utils
1 parent bd6a22a commit 6f7dd2c

File tree

4 files changed

+26
-12
lines changed

4 files changed

+26
-12
lines changed

src/util/slice.rs

+18
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@
99
//! Uses [Heap's algorithm](https://en.wikipedia.org/wiki/Heap%27s_algorithm) for efficiency,
1010
//! modifying the slice in place.
1111
//!
12+
//! [`fold_decimal`]
13+
//!
14+
//! Accumulates a slice of digits from 0 to 9 inclusive into a single integer.
15+
//!
1216
//! [`permutations`]: SliceOps::permutations
17+
//! [`fold_decimal`]: SliceOps2::fold_decimal
18+
use super::integer::*;
1319

1420
pub trait SliceOps<T> {
1521
fn permutations(self, callback: impl FnMut(&[T]));
@@ -40,3 +46,15 @@ impl<T> SliceOps<T> for &mut [T] {
4046
}
4147
}
4248
}
49+
50+
pub trait SliceOps2<T: Integer<T>> {
51+
/// Folds a slice of digits into an integer.
52+
fn fold_decimal(self) -> T;
53+
}
54+
55+
impl<T: Integer<T>> SliceOps2<T> for &[T] {
56+
#[inline]
57+
fn fold_decimal(self) -> T {
58+
self.iter().fold(T::ZERO, |acc, &b| T::TEN * acc + b)
59+
}
60+
}

src/year2019/day04.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! These numbers become rapidly less dense as the password value increases and there
55
//! are only 3003 total of these numbers with 6 digits.
66
use crate::util::parse::*;
7+
use crate::util::slice::*;
78

89
pub fn parse(input: &str) -> Vec<u32> {
910
input.iter_unsigned().collect()
@@ -83,7 +84,7 @@ fn passwords(input: &[u32], predicate: impl Fn(bool, bool, bool, bool, bool) ->
8384
}
8485

8586
// Convert number to `u32`.
86-
n = digits.iter().fold(0, |acc, d| 10 * acc + d);
87+
n = digits.fold_decimal();
8788
}
8889

8990
count

src/year2019/day16.rs

+4-10
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@
7575
//! [grows rather large]: https://oeis.org/A017763/b017763.txt
7676
//! [Lucas's theorem]: https://en.wikipedia.org/wiki/Lucas%27s_theorem
7777
//! [Chinese remainder theorem]: https://en.wikipedia.org/wiki/Chinese_remainder_theorem
78-
use crate::util::integer::*;
7978
use crate::util::parse::*;
79+
use crate::util::slice::*;
8080

8181
/// Lookup table for first five rows of
8282
/// [Pascal's triangle](https://en.wikipedia.org/wiki/Pascal%27s_triangle).
@@ -135,12 +135,12 @@ pub fn part1(input: &[u8]) -> i32 {
135135
(current, next) = (next, current);
136136
}
137137

138-
fold_number(&current[..8])
138+
current[..8].fold_decimal()
139139
}
140140

141141
pub fn part2(input: &[u8]) -> usize {
142142
let digits: Vec<_> = input.iter().copied().map(usize::from).collect();
143-
let start = fold_number(&digits[..7]);
143+
let start = digits[..7].fold_decimal();
144144

145145
// This approach will only work if the index is in the second half of the input.
146146
let size = digits.len();
@@ -160,7 +160,7 @@ pub fn part2(input: &[u8]) -> usize {
160160
}
161161

162162
result.iter_mut().for_each(|r| *r %= 10);
163-
fold_number(&result)
163+
result.fold_decimal()
164164
}
165165

166166
/// Computes C(n, k) % 2
@@ -215,9 +215,3 @@ fn bimonial_mod_5(mut n: usize, mut k: usize) -> usize {
215215
fn binomial_mod_10(n: usize, k: usize) -> usize {
216216
5 * binomial_mod_2(n, k) + 6 * bimonial_mod_5(n, k)
217217
}
218-
219-
/// Folds a slice of digits into an integer.
220-
#[inline]
221-
fn fold_number<T: Integer<T>>(slice: &[T]) -> T {
222-
slice.iter().fold(T::ZERO, |acc, &b| T::TEN * acc + b)
223-
}

src/year2021/day08.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
//! * Add the occurences of each scrambled segment for each digit after the `|` symbol, then
2828
//! lookup the total and map directly to the unscrambled digit.
2929
use crate::util::iter::*;
30+
use crate::util::slice::*;
3031

3132
type Input = Vec<[u32; 4]>;
3233

@@ -39,7 +40,7 @@ pub fn part1(input: &Input) -> usize {
3940
}
4041

4142
pub fn part2(input: &Input) -> u32 {
42-
input.iter().map(|digits| digits.iter().fold(0, |acc, d| 10 * acc + d)).sum()
43+
input.iter().map(|digits| digits.fold_decimal()).sum()
4344
}
4445

4546
fn descramble(line: &str) -> [u32; 4] {

0 commit comments

Comments
 (0)