Skip to content

Instantly share code, notes, and snippets.

@frol
Created February 28, 2019 22:26
Show Gist options
  • Select an option

  • Save frol/a5d644c74a41f395cc33bfa81843fccb to your computer and use it in GitHub Desktop.

Select an option

Save frol/a5d644c74a41f395cc33bfa81843fccb to your computer and use it in GitHub Desktop.
// Simple
fn array_manipulation_simple(n: usize, queries: &[(usize, usize, isize)]) -> isize {
let mut checkpoints = vec![0; n];
for &(start, end, value) in queries {
checkpoints[start - 1] += value;
if end < n {
checkpoints[end] -= value;
}
}
let mut max = 0;
let mut accumulated_sum = 0;
for checkpoint in checkpoints {
accumulated_sum += checkpoint;
if accumulated_sum > max {
max = accumulated_sum;
}
}
max
}
// Functional (scan + fold) - 2 lines shorter than the simple solution and produces EXACTLY the same Assembly
// NOTE: the generated Assembly is EXACTLY the same for all the implementations!
fn array_manipulation_scan_fold(n: usize, queries: &[(usize, usize, isize)]) -> isize {
let mut checkpoints = vec![0; n];
for &(start, end, value) in queries {
checkpoints[start - 1] += value;
if end < n {
checkpoints[end] -= value;
}
}
checkpoints
.into_iter()
.scan(0, |accumulated_sum, checkpoint| {
*accumulated_sum += checkpoint;
Some(*accumulated_sum)
})
.fold(0, isize::max)
}
// Functional (single monster fold) - this is only for comparison with Kotlin
// NOTE: the generated Assembly is EXACTLY the same for all the implementations!
fn array_manipulation_fold(n: usize, queries: &[(usize, usize, isize)]) -> isize {
let mut checkpoints = vec![0; n];
for &(start, end, value) in queries {
checkpoints[start - 1] += value;
if end < n {
checkpoints[end] -= value;
}
}
checkpoints
.into_iter()
.fold((0, 0), |mut checkpoint_fold, checkpoint| {
checkpoint_fold.0 += checkpoint;
if checkpoint_fold.0 > checkpoint_fold.1 {
checkpoint_fold.1 = checkpoint_fold.0
}
checkpoint_fold
})
.1
}
// Functional (with a special struct for fold) - this is complete overkill for the task, so it is only for comparison with Kotlin
// NOTE: the generated Assembly is EXACTLY the same for all the implementations!
struct CheckpointFold {
max_value: isize,
accumulated_value: isize,
}
impl std::ops::AddAssign<isize> for CheckpointFold {
fn add_assign(&mut self, value: isize) {
self.accumulated_value += value;
if self.accumulated_value > self.max_value {
self.max_value = self.accumulated_value;
}
}
}
fn array_manipulation_fold_struct(n: usize, queries: &[(usize, usize, isize)]) -> isize {
let mut checkpoints = vec![0; n];
for &(start, end, value) in queries {
checkpoints[start - 1] += value;
if end < n {
checkpoints[end] -= value;
}
}
checkpoints
.into_iter()
.fold(
CheckpointFold {
max_value: 0,
accumulated_value: 0,
},
|mut checkpoint_fold, checkpoint| {
checkpoint_fold += checkpoint;
checkpoint_fold
},
)
.max_value
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment