Created
February 28, 2019 22:26
-
-
Save frol/a5d644c74a41f395cc33bfa81843fccb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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