Last active
November 25, 2018 12:45
-
-
Save u840903/bf20e1e60dff23112600a15e785497e9 to your computer and use it in GitHub Desktop.
This file contains 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
// Setup. | |
const ARRAY_LENGTH = 8; | |
const STEPS = [ | |
[1, 1, 8], | |
[0, 2, 8], | |
[2, 4, 6], | |
[0, 5, 6] | |
]; | |
// Initial array state. | |
const initialArray = Array.from({ length: ARRAY_LENGTH }).fill(0); | |
// Helper function to check if an index is in range. | |
const inRange = (i, x, y) => i >= x && i <= y; | |
// Helper function to zero-index instruction ranges. | |
const zeroIndexRange = ([t, x, y]) => [t, x - 1, y - 1]; | |
// Find the sum of all elements from index x to index y modulo 10^9+7 | |
const sum = (x, y, arr) => | |
// Iterate over the whole array. | |
arr.reduce( | |
(sum, value, i) => | |
// Check if index is or is between x and y. | |
inRange(i, x, y) | |
// Add the current value modulo 10^9+7 to the accumulator | |
// (sum) if the index is in range. | |
? sum + (value % (Math.pow(10, 9) + 7)) | |
// Do nothing if we are out of bounds. | |
: sum, | |
0); | |
// Report sum and return untouched array. | |
const reportSum = (x, y, arr) => !console.log(sum(x, y, arr)) && arr; | |
// Add or subtract (controlled by modifier) (i+1)×(i+2)×(i+3) from Ax+i and so on until Ay | |
// This approach will suck if x-y is a lot smaler than arr.length ¯\_(ツ)_/¯ | |
const change = (x, y, arr, modifier) => | |
// Iterate over the whole array. | |
arr.map((value, i) => | |
// Check if index is or is between x and y. | |
inRange(i, x, y) | |
// Add (i+1)×(i+2)×(i+3)*1 or (i+1)×(i+2)×(i+3)*-1, i.e substract, to the value. | |
? value + (i - x + 1) * (i - x + 2) * (i - x + 3) * modifier | |
// Leave the value untouched if we are out of bounds. | |
: value | |
); | |
// Action router. | |
const action = (t, x, y, arr) => { | |
switch (t) { | |
case 0: | |
return reportSum(x, y, arr); | |
case 1: | |
return change(x, y, arr, 1); | |
case 2: | |
return change(x, y, arr, -1); | |
} | |
}; | |
// Recurse over steps. | |
const follow = (steps, arr) => | |
// Check if we still have steps to exercise. | |
steps.length | |
// Act on the first step in the steps array and remove it from the array. | |
? follow(steps, action(...steps.shift(), arr)) | |
// Return the array if there are no more steps to execute. | |
: arr; | |
// Manipulate initial array using the steps. | |
const result = follow( | |
// The data has ranges with one base indexs. | |
// Javascript uses zero based indexs. | |
// Lets change... | |
STEPS.map(zeroIndexRange), | |
initialArray | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment