Skip to content

Commit 7b2d36c

Browse files
committed
Add problem 3153: Sum of Digit Differences of All Pairs
1 parent f4fd49f commit 7b2d36c

File tree

4 files changed

+115
-0
lines changed

4 files changed

+115
-0
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2110,6 +2110,7 @@ pub mod problem_3147_taking_maximum_energy_from_the_mystic_dungeon;
21102110
pub mod problem_3148_maximum_difference_score_in_a_grid;
21112111
pub mod problem_3151_special_array_i;
21122112
pub mod problem_3152_special_array_ii;
2113+
pub mod problem_3153_sum_of_digit_differences_of_all_pairs;
21132114
pub mod problem_3350_adjacent_increasing_subarrays_detection_ii;
21142115

21152116
#[cfg(test)]
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
pub struct Solution;
2+
3+
// ------------------------------------------------------ snip ------------------------------------------------------ //
4+
5+
impl Solution {
6+
pub fn sum_digit_differences(nums: Vec<i32>) -> i64 {
7+
let nums = nums.into_iter().map(i32::cast_unsigned).collect::<Vec<_>>();
8+
let mut cache = [(0_u32, [0_u32; 10]); 10];
9+
10+
let cache = nums
11+
.first()
12+
.copied()
13+
.and_then(|first| cache.get_mut(..first.checked_ilog10()? as usize + 1))
14+
.unwrap_or(&mut []);
15+
16+
let mut result = 0;
17+
18+
for mut num in nums {
19+
for (total, details) in &mut *cache {
20+
let digit = num % 10;
21+
22+
num /= 10;
23+
24+
let digit = digit as usize;
25+
let digit_count = &mut details[digit];
26+
27+
result += u64::from(*total - *digit_count);
28+
*total += 1;
29+
*digit_count += 1;
30+
}
31+
}
32+
33+
result.cast_signed()
34+
}
35+
}
36+
37+
// ------------------------------------------------------ snip ------------------------------------------------------ //
38+
39+
impl super::Solution for Solution {
40+
fn sum_digit_differences(nums: Vec<i32>) -> i64 {
41+
Self::sum_digit_differences(nums)
42+
}
43+
}
44+
45+
#[cfg(test)]
46+
mod tests {
47+
#[test]
48+
fn test_solution() {
49+
super::super::tests::run::<super::Solution>();
50+
}
51+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
pub struct Solution;
2+
3+
// ------------------------------------------------------ snip ------------------------------------------------------ //
4+
5+
impl Solution {
6+
pub fn sum_digit_differences(nums: Vec<i32>) -> i64 {
7+
let mut nums = nums.into_iter().map(i32::cast_unsigned).collect::<Vec<_>>();
8+
let digits = nums.first().copied().and_then(u32::checked_ilog10).map_or(0, |x| x + 1);
9+
let mut result = 0;
10+
11+
for _ in 0..digits {
12+
let mut cache = [0_u32; 10];
13+
14+
(0..).zip(&mut nums).for_each(|(total, num)| {
15+
let digit = *num % 10;
16+
17+
*num /= 10;
18+
19+
let digit_count = &mut cache[digit as usize];
20+
21+
result += u64::from(total - *digit_count);
22+
*digit_count += 1;
23+
});
24+
}
25+
26+
result.cast_signed()
27+
}
28+
}
29+
30+
// ------------------------------------------------------ snip ------------------------------------------------------ //
31+
32+
impl super::Solution for Solution {
33+
fn sum_digit_differences(nums: Vec<i32>) -> i64 {
34+
Self::sum_digit_differences(nums)
35+
}
36+
}
37+
38+
#[cfg(test)]
39+
mod tests {
40+
#[test]
41+
fn test_solution() {
42+
super::super::tests::run::<super::Solution>();
43+
}
44+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
pub mod iterative;
2+
pub mod iterative_2;
3+
4+
pub trait Solution {
5+
fn sum_digit_differences(nums: Vec<i32>) -> i64;
6+
}
7+
8+
#[cfg(test)]
9+
mod tests {
10+
use super::Solution;
11+
12+
pub fn run<S: Solution>() {
13+
let test_cases = [(&[13, 23, 12] as &[_], 4), (&[10, 10, 10, 10], 0)];
14+
15+
for (nums, expected) in test_cases {
16+
assert_eq!(S::sum_digit_differences(nums.to_vec()), expected);
17+
}
18+
}
19+
}

0 commit comments

Comments
 (0)