Creating a new array that counts the distance between specific numbers - javascript

This is easy to mis-explain so I'll simplify it. Let's say I have an array that are the results of dice throws. Like:
1 2 4 6 1 2 6 6 2 4 etc
Every time you throw a 6, you win. I want to create a new array which contains after how many turns you would win based on the original array. So the above array would create an array that is:
4 3 1
(it takes 4 turns to win, then 3, then 1)
So I only want to count the distance between the 6's. (I could also convert the dice results to binary win/lose)
How do I do this in excel? (or javascript, but really prefer excel)

Create a Helper Column (Column A of Excel). Put 1 in the first cell (A2) of Helper column. Follow it up with the formula (in A3) =IF(B3=6,A2+1,A2).Drag it to the last row of to the given array.
Then Create a Result column (Column C of Excel). Type in formula (in C2)
=IF(ROW()-1=MAX(A:A),"",IF(IF(ROW()-1=1,COUNTIF(A:A,ROW()-1)+1,COUNTIF(A:A,ROW()-1))=0,"",IF(ROW()-1=1,COUNTIF(A:A,ROW()-1)+1,COUNTIF(A:A,ROW()-1))))
in the first cell of Result Column (Column C of Excel). Drag and get the required result.
Hide Helper Column.
Note: Array Data starts from cell B2

If the first array is B1:K1 the second might be created with:
=IF(B1=6,COLUMN()-SUM(A2:$B2)-1,"")
in B2 and copied across to suit.

This might work for you:
var rollsUntil6 = function(rolls) {
return rolls.reduce(function(indices, roll, idx) {
if (roll == 6) {indices.push(idx);} return indices;
}, [-1]).map(function(val, idx, arr) {
return val - arr[idx - 1];
}).slice(1);
};
rollsUntil6([1, 2, 4, 6, 1, 2, 6, 6, 2, 4]); //=> [4, 3, 1]

What you need to do is iterate over the array and count the spaces by accumulating into a collector variable. You can find the code below it just pops into and alert window.(Javascript)
var array = [1, 2, 4, 6, 1, 2, 6, 6, 2, 4]
var resultArray = []
var i = 0;
var distance = 0;
for (i = 0; i < array.length; i++) {
distance++;
if (array[i] == 6) {
resultArray.push(distance);
distance = 0;
}
}
alert(resultArray);
I took an attempt at doing in excel.
You can place a command button and define a sub function like below and you will get the results expected. For instructions on how to place a command button http://www.excel-easy.com/vba/create-a-macro.html#command-button
Sub DistanceOf6InString(x As String)
Size = Len(x)
distance = 0
result = ""
Dim i As Integer
For i = 1 To Size
distance = distance + 1
If (Mid(x, i, 1) = "6") Then
result = result & distance
distance = 0
End If
Next i
MsgBox result
End Sub
Private Sub CommandButton1_Click()
DistanceOf6InString ("1246126624")
End Sub

You can repeatedly find the array.indexOf(6,lastmatch)
var array= [1, 2, 4, 6, 1, 2, 6, 6, 2, 4];
var resultArray= [], i, incr= 0;
while((i= array.indexOf(6, incr))!= -1){
i+= 1;
resultArray.push(i-incr);
incr= i;
}
resultArray returned value: (Array) [4,3,1]

Related

Please Help me solve this problem i have trying to solve Range extraction

The problem i try to solve is this using js :
A format for expressing an ordered list of integers is to use a comma separated list of either:
-individual integers
-or a range of integers denoted by the starting integer separated from the end integer in the range by a dash, '-'. The range includes all integers in the interval including both endpoints. It is not considered a range unless it spans at least 3 numbers. For example "12,13,15-17"
Complete the solution so that it takes a list of integers in increasing order and returns a correctly formatted string in the range format.
Example:
solution([-10, -9, -8, -6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]);
// returns "-10--8,-6,-3-1,3-5,7-11,14,15,17-20"
so my idea was to use 3 functions :
1- newRangeStart: creates a new Array in results to store the range numbers and puts in it the first element of the range (RangeStarter).
2-olSupp : deletes elements from the list that were used by the 3rd function RangeArr so that we get a new Arr with a new RangeStarter using 1st function.
3-RangeArr : uses the 1st function than adds elements from the list to the array created by it which are consecutive starting from the Range starter, and then uses the 2nd function to delete the elements used from the ol so the next time we use the RangeArr function it creates another range.
By repeating the RangeArr function with a while loop that runs until ol becomes empty we will have a resuts array with arrays inside of it that contains ranges.
now the poblem is when i run RangeArr function it doesn't delete the used elements from the ol as i want i tried to fix the olSupp function several times but it just doesn't work i think there is a problem in my entire code pls someone help me to fix it here is my code:
function solution(list){
// TODO: complete solution
let ol = [...list];
let results = [];
/*This adds a new array for a range by adding the first number of the range to
an array (2D array) and stores it in the resuts array */
function newRangeStart(orderedlist,result){
result.push([orderedlist[0]]);
return result;
}
/*This functions takes the ol and deletes elements that are found in the results
so that the next time we run the newRangeStart function it creates an other array
for another range with a different start number*/
function olSupp(orderedlist,result){
let toRemove = result.flat();
let newList = [];
for (let i = 0; i < orderedlist.length; i++) {
if(!toRemove.includes(orderedlist[i])){
newList.push(orderedlist[i]);
}
}
orderedlist = [...newList];
return orderedlist;
}
/*Finally RangeArr function creates a range from the ol (ordered list)
starting by the first element of the results array and then uses olSupp to delete
the used numbers from the ol */
function RangeArr (orderedlist,result){
newRangeStart(orderedlist,result);
let i = 0;
while(orderedlist[i+1]- orderedlist[i] == 1 && orderedlist[i+2]- orderedlist[i+1]== 1) {
result[i].push(orderedlist[i+1],orderedlist[i+2]);
i = i+1;
}
olSupp(orderedlist,result);
return result;
}
/*we execute the RangeArr function until ol becomes emepty
and this will give us multiple arrays in the result array containing
the elements of each range found in the ol */
//PS: i didnt put the code beacuse it causes an infinte loop using while
RangeArr(ol,results);
console.log(ol,results);
}
solution([-10, -9, -8, -6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]);
const solution = arr => {
let s = null, d = 0;
const result = arr.sort((a, b) => a - b).reduce((p, c, i, arr) => {
d++;
if (!s) s = c;
if (arr[i + 1] - s > d) {
s === c ? p.push(s) : d < 3 ? p.push(s, c) : p.push(`${s}-${c}`);
s = null;
d = 0;
}
if (arr[i + 1] === undefined) s === c ? p.push(s) : d < 3 ? p.push(s, c) : p.push(`${s}-${c}`);
return p;
}, []);
return result;
}
console.log(solution([-10, -9, -8, -6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]));
Variables:
s (start) for saving the number that starts a range.
d (distance) for counting the distance between the start and end of a range.
for a and b read the doc for javascript sort method to learn more.
same with p (pervious), c (current), i (index) and arr (original array) read the doc for javascript reduce method
Logic:
we can determine a range (for example: [1, 2, 3, 4, 5] is equal to "1-5") by calculate the distance between the starting number 1 and the ending number 5. so the distance between 1 and 5 is 4 because 1 needs to increment by 1 four times to reach 5 and the distance inside the array between the starting number 1 (index 0) and the ending number 5 (index 4) is also 4. so if we take the end minus the start 5 - 1 = 4 if it matches to the correct distance inside the array which is 4 then it is a range "1-5". let's have another example [1, 2, 3, 6, 7, 8], this should be "1-3" and "6-8". when we calculate the distance with 1 and 6 (6 - 1 = 5) we get 5 which is incorrect, because it doesn't match the correct distance inside the array (1 is at index 0 and 6 is at index 3, 3 - 0 = 3. the distance between 1 and 6 is only 3 index apart and not 5, that isn't a range). but if we do the calculate with 1 and 3 it matches our criteria and it's a range "1-3".
Code:
we have to do the calculation inside a loop (i'm using reduce method because it's convenient). first thing i do in the loop is d++ to track the distance of index(s) that the loop had travel inside the array. if (!s) s = c; is for check we've saved a starting number or not. if (arr[i + 1] - s > d) { ... } this is where we do the calculation to see if the current element inside the array minus s is greater than the distance index we've travel or not. if it's true then it means s and the last element must be a range and we push that range in the result array. and then we reset s and d to let them work on the next range.
Update
const solution = arr => {
let s = null;
return arr.sort((a, b) => a - b).reduce((p, c, i, arr) => {
if (!s) s = c;
if (c + 1 !== arr[i + 1]) {
s === c ? p.push(s) : c - 1 === s ? p.push(s, c) : p.push(`${s}-${c}`);
s = null;
}
return p
}, [])
}
console.log(solution([-10, -9, -8, -6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]));

How would you make a function that adds random numbers from a list to reach a certain value?

the question title might be a little bit confusing so let me see if I can explain it a little better here. I want to create a function that will generate a sequence of numbers (in any order or combination) that are in a pre-defined list to add to a certain value.
IE.
var x = [6, 4, 3]; //pre-defined values
var n = 24; //the number I want to add too
function myFunc(values, goal) {
//code for algorithm
//return a sequence of numbers from the list that add to 24
}
myFunc(x, n)
Example Outputs from myFunc:
4, 4, 4, 6, 3, 3 --> 24
6, 4, 3, 3, 4, 4 --> 24
3, 4, 4, 6, 3, 4 --> 24
etc.
The algorithm would be able to return one of the many permutations that exist but I just came up with a couple for the sake of the question.
Responses don't have to be language-specific I just need a general idea/insight on how to create and structure this algorithm.
Thanks!
Here's a brute-force approach that keeps adding random values until the sum is 24 (return) or it's greater than 24 (restart). This may not be practical for large values.
var x = [6, 4, 3]; //pre-defined values
var n = 24; //the number I want to add too
function myFunc(values, goal) {
let result = [];
while (true) {
// Add random value
result.push(values[Math.floor(Math.random() * values.length)]);
// Calc sum
var sum = result.reduce((acc, val) => acc + val);
// If success, return
if (sum == goal) return result;
// If too large, start over
else if (sum > goal) result = [];
}
}
for (let i = 0; i < 10; i++) {
console.log(myFunc(x, n));
}

Sequence in an array

I have an algo exercise to do and I have no idea how to do it, as the requirement is to use only basic programming concepts. So - the point is to find the longest sequence of numbers in an array that are growing or not changing value.
So for the array [1,1,2,4,0,1,7,4], it would be [1,1,2,4].
It should have as small time and memory complexity as possible. Any solutions, tips? Much love and thanks in advance for any advice or feedback.
That's what I've managed to do in the last 10 minutes, but I feel like I'm doing it in the most complex way possible...
function idk(array) {
var current = 0;
var winner = 0;
var currentArray = [];
var winnerArray = [];
for (let i = 0; i <= array.length; i++) {
if (array[i + 1] >= array[i]) {
currentArray.push(array[i]);
current = currentArray.length;
} else {
currentArray.push(array[i]);
if (currentArray.length > best.length) {
// copy array and append it to the new array?
}
}
}
return winnerArray;
}
Try this javascript algorithm:
var array = [1, 8, 1, 1, 5, 7, 2, 2]
var output = []
array.forEach(function(value, index) {
if (array[index - 1] <= value && index != 0) {
output[output.length - 1].push(value)
} else {
output.push([value])
}
})
var longestArray = []
output.forEach(function(arrayCompare, index) {
if (arrayCompare.length > longestArray.length || index == 0) {
longestArray = arrayCompare
}
})
console.log(longestArray)
The first forEach loops through the elements of array. If the element is larger than or equal to the previous element, it adds it to the last array in output. If it is not, then it creates a new array, and pushes the array into output. This creates arrays with "growing" sequences.
After that, it loops through each sequence, and checks if the length of the sequence is greater than the current longest sequence, which is stored in longestArray. If it is, it changes longestArray to that. If it isn't, it does nothing.
Note that both of these loops have exceptions if the index is 0, since there is no element with index -1 (therefore such an exception had to be made).
Also, here's the same implementation in python:
array = [1, 8, 1, 1, 5, 7, 2, 2]
output = []
index = 0
while index < len(array):
value = array[index]
if (array[index-1] <= value and index !=0):
output[-1].append(value)
else:
output.append([value])
index += 1
longestArray = []
index = 0
while index < len(output):
arrayCompare = output[index]
if index==0 or len(arrayCompare) > len(longestArray):
longestArray = arrayCompare
index += 1
print(longestArray)
Just why loop over the end of the array?
Because you could take this advantage to gather the last longest sequence without having a check after the loop for having found a longest sequence.
But in parts:
Why not a temporary array? Because there is no need to use it, if you collect the values. the startignn index of a sequence is important and the actual indec to decide if the sequence is longer then the previously found one.
The loop feature two conditions, one for continuing the loop, if in sequence and another to check if the actual ended sequence is longer. And for storing the actual index.
The last loop with a check for an undefined value is false, it does not continue the loop and the nect check reveals either a new longest sequence or not.
Some other annotation:
winnerArray has to be an empty array, because of the check later for length
The sequence check take the previous element, because the loop starts with the first index and the previous element is given.
The Big O is O(n).
function idk(array) {
let winnerArray = [],
index = 0;
for (let i = 1; i < array.length + 1; i++) {
if (array[i - 1] <= array[i]) continue;
if (i - index > winnerArray.length) winnerArray = array.slice(index, i);
index = i;
}
return winnerArray;
}
console.log(...idk([1, 1, 2, 4, 0, 1, 7, 4])); // [1, 1, 2, 4]
console.log(...idk([1, 8, 1, 1, 5, 7, 2, 2])); // [1, 1, 5, 7]
console.log(...idk([1, 8, 1, 1, 5, 7, 2, 2, 2, 2, 2]));
Here is the dynamic programming algorithm in Python:
def longest_sequence(numbers):
length = len(numbers)
L = [0] * length #L stores max possible lengths at each index
L[-1] = 1 # base case
for i in range(length-2, -1, -1):
max_length = L[i]
for j in range(i, length):
if (L[j] > max_length) and (numbers[j] > numbers[i]):
max_length = L[j]
L[i] = max_length + 1
#trace back
max_length = max(L)
result = []
for k in range(max_length, 0, -1):
result.append(numbers[L.index(k)])
numbers = numbers[L.index(k):]
L = L[L.index(k):]
return result
my_numbers = [36,13,78,85,16,52,58,61,63,83,46,19,85,1,58,71,26,26,21,31]
print(longest_sequence(my_numbers))
#>>[13, 16, 52, 58, 61, 63, 83, 85]
To be optimal, you should not use intermediate lists during processing. You only need to hold indexes, sizes and the previous value:
def longSeq(A):
longStart,longSize = 0,0 # best range so far (index and size only)
start,size,prev = 0,0,None # current range (index and size)
for i,a in enumerate(A):
if i == 0 or prev <= a: # increase current range
size += 1
prev = a
if size > longSize: # track longest so far
longStart,longSize = start,size
else:
start,size,prev = i,1,a # sequence break, restart current
return A[longStart:longStart+longSize]
output:
print(longSeq([1,1,2,4,0,1,7,4])) # [1, 1, 2, 4]
print(longSeq( [1,8,1,1,5,7,2,2])) # [1, 1, 5, 7]
This will perform in O(n) time and use O(1) space.

Array returned not equal to the original array

I'm trying to solve this question on LeetCode:
Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.
Note: The number of elements initialized in nums1 and nums2 are m and n respectively.
You may assume that nums1 has enough space (size that is equal to m + n) to hold additional elements from nums2.
I ended up with coming up with this code:
var merge = function(nums1, m, nums2, n) {
var nums = [];
nums1.length = m;
nums2.length = n;
nums = nums.concat(nums1);
console.log(nums);
nums = nums.concat(nums2);
console.log(nums);
nums = nums.sort();
console.log(nums);
return nums;
}
This is what the 'run code' says:
Your input
[1,2,3,0,0,0]
3
[2,5,6]
3
stdout
[ 1, 2, 3 ]
[ 1, 2, 3, 2, 5, 6 ]
[ 1, 2, 2, 3, 5, 6 ]
Output:
[1,2,3]
Expected
[1,2,2,3,5,6]
(an image version if the quotes weren't clear)
When I'm console.logging the array, the answer is correct but for some reason returning the array gives a completely different output
Can anyone help in this?
I think the hint here is that nums1 is big enough to hold n+m values. So the way to solve this problem is to work backwards through both arrays, filling the empty space in nums1 as you go. So for example, for the first iteration of the loop, you would compare nums1[n-1] and nums2[m-1] and put whichever is larger into nums1[n+m-1]. You then continue this for as long as you have values in either array, copying exclusively from the other if one runs out:
const merge = function(nums1, m, nums2, n) {
n--; m--;
for (let i = m + n + 1; i >= 0; i--) {
nums1[i] = (m < 0 || n >= 0 && nums2[n] > nums1[m]) ? nums2[n--] : nums1[m--];
}
return nums1;
}
console.log(merge([1, 2, 3, 0, 0, 0], 3, [2, 5, 6], 3));
This code is O(n) (as compared to your sort which is O(nlogn)) and requires no additional space.

Giving an original array and a new array that each element's value indicates the count of elements on the left that are bigger

Giving an array, say [4,2,1,3,5], based on this array, we have a new array, which each number shows the count of elements on its left that are bigger than itself, which is [0,1,2,1,0]. Now write a function with given input of [0,1,2,1,0], return the original array. The range of array is 1 ~ n (n is the size of the array, you can assume all numbers in the original array are consecutive if sorted)
Now to recover the original array, I have tried a way to solve the problem by iterating through the range of array from the end to the front like this:
My approach:
say the range is 1 ~ 5, the original array would be [1, 2, 3, 4, 5] if sorted. Iterate from the end to the beg,
so first 5, there is no element can be bigger than 5, so its maximum count of bigger elements would be 0, then 4 would have 1 as its maximum count of bigger elements, 3 to 2, etc. Store the key-value pairs into an object.
Now iterating through the input from back to front,
0 -> 5
1 -> can be 4, 3, or 2
2 -> can be either 3, 2, or 1
1 -> any number bigger than the first one.
0 -> (can be anything, since 5 is taken, so it can be either 1, 2, 3, or 4)
Simply to map each element of the input as value to its key from the map is not enough. What would be an intuitive way to approach this with optimal performance? (avoiding O(n ^2) if possible.)
Initially make an AVL Tree from numbers 1 to n.
Start from rear i.e. at nth index (considering 1 based index).
Now the high level outline level of the algorithm should look like this:
1. At any ith index, say the number in array(not the originial array) is j
2. Search the number which is at (i-j)th position in your AVL tree(This can be done in O(logn) time. Comment if you need more explanation on this)
3. The element in the AVL tree is your required element. Delete that element from AVL tree.(O(logn))
So the total complexity would be O(nlogn).
Walkthrough
Initially the tree will contain all 5 elements.
You start at index 5(1-based indexing). Element is 0, i.e. i=5, j=0. So 5th largest element which is 5.
Now the tree contains four elements 1,2, 3, and 4. i=4, j=1. So 4-1 i..e 3rd largest element which is 3 in this case.
i=3, j=2. (3-2)rd largest element is 1 since the tree contains (1, 2, 4).
And so on.
Using Tree to find the ith largest number
We can do this by, storing the count of number of nodes in left subtree at the root node. So consider a tree, having elements 1, 2, 3,4 and 5 and tree structure as following:
4(3)
/ \
3(1) 5(0)
/ \
1(0) 2(0)
At root, number 4 is the value and the number in round bracket has the number of nodes in left subtree.
While constructing(insertion and deletion too) the tree, we can maintain the count.
Now, to find the ith node, say we want suppose 3rd nodes in the given tree. We start with the root, it says it has 3 elements smaller than it to the left so we move to left. Now the root i.e. 3 has 1 smaller left element which is less than 3(ith element) so we move to right of it. Subtract 1(the left count)+1(the root itself) out of 3. Now the root is 2 we want 1st element, the left count is 0. Hence the 1st element of the subtree rooted at 2 is 2.
Basic pseudocode is below:
while(true){
count = root->leftCount;
if((count+1)<i){
//move to right
i-=(count+1);
root = root->right;
}
else if(i==(count+1)){
//root is the ith node
break;
} else{
//move to the levft
root=root->left
}
}
You could use Array#reduceRight and use the value as negative index for generating the original array.
var array = [1, 2, 3, 4, 5],
countLeft = [0, 1, 2, 1, 0],
result = countLeft.reduceRight(function (r, a) {
return array.splice(array.length - 1 - a, 1).concat(r);
}, []);
console.log(result);
Shorter version with ES6 and reverse base array.
var array = [5, 4, 3, 2, 1],
countLeft = [0, 1, 2, 1, 0],
indices = array.map((_, i) => i),
result = [];
countLeft.forEach(a => {
result.unshift(array[indices[a]]);
indices = indices.filter((_, i) => i !== a);
});
console.log(result);
At last a proposal with complexity between O(n*(n-1)/2) and O(n).
This version uses a lazy array with progressive reduction of the length for every iteration. At the end, the offset array has zero elements.
var array = [5, 4, 3, 2, 1],
countLeft = [0, 1, 2, 1, 0],
result = [],
length = array.length;
countLeft.forEach((offset => (offset.length = countLeft.length, a => {
var i = offset[a] || 0;
result.unshift(array[i + a]);
offset.length--;
while (i < offset.length) {
offset[i] = (offset[i] || 0) + 1;
i++;
}
}))([]));
console.log(result);
A linear version, heavily inspired by the proposal of Oriol
var array = [1, 2, 3, 4, 5],
countLeft = [0, 1, 2, 1, 0],
swap = [],
i = 0,
l,
temp;
while (i < countLeft.length) {
l = countLeft[i];
while (l) {
swap.push(i + l - countLeft[i]);
l--;
}
i++;
}
i = swap.length;
while (i--) {
temp = array[swap[i]];
array[swap[i]] = array[swap[i] - 1];
array[swap[i] - 1] = temp;
}
console.log(array);
Here is a possible solution. See inline comments for a brief description of this method.
var a = [0,1,2,1,0],
n, b = [], res = [];
// build b = [5,4,3,2,1]
// we use this array to keep track of values to be pushed in res[],
// sorted in descending order
for(n = a.length; n > 0; n--) {
b.push(n);
}
// for each element of a, starting from the end:
// find correct value in b and remove it from b
while(a.length) {
res.push(b.splice(a.pop(), 1)[0]);
}
res = res.reverse();
console.log(res);
Output:
[4, 2, 1, 3, 5]
I propose an approach based on a custom sort, based on mergesort:
Split the array of inversions into two halves
Sort each part recursively, from greatest to lowest, maintaining stability
Merge the two parts
The difference with mergesort is the merge part. If we choose the j-th element of right part instead of the i-th of the left one, it will advance some elements, and therefore its number of inversions must be reduced by that amount.
Like mergesort, the complexity is O(n log n)
function undoInversions(inversions) {
function reorder(arr, from=0, to=arr.length) {
// Based on a stable decreasing mergesort
if(from >= to) return []; // Unusual base case
if(to === from + 1) return [arr[from]]; // Base case
var m = Math.floor((from + to)/2);
var l = reorder(arr, from, m), // Left recursive call
r = reorder(arr, m, to), // Right recursive call
ret = [], i=0, j=0;
while(i < l.length && j < r.length) { // Merge
if(r[j].value - l.length + i >= l[i].value) {
r[j].value -= l.length - i; // Reduce number of inversions
ret.push(r[j++]);
} else {
ret.push(l[i++]);
}
}
while(i < l.length) ret.push(l[i++]); // Merge remaining, if any
while(j < r.length) ret.push(r[j++]); // Merge remaining, if any
return ret;
}
var array = new Array(inversions.length);
reorder(inversions.map(function(inv, idx) {
return {value: inv, originalIndex: idx}; // Keep track of indices
})).forEach(function(obj, idx) {
if(obj.value !== 0) throw 'Invalid input';
array[obj.originalIndex] = idx + 1; // Invert the permutation
});
return array;
}
console.log(JSON.stringify(undoInversions([0,1,2,1,0])));
Here is an example to understand how it works:
[0,1,2,1,0] ~ [4,2,1,3,5]
⤩ ⤧
[0,0,2,1,0] ~ [2,4,1,3,5]
⤩ ⤧
[0,1,0,1,0] ~ [2,1,4,3,5]
⤩ ⤧
[0,0,0,1,0] ~ [1,2,4,3,5]
⤩ ⤧
[0,0,0,0,0] ——→ [1,2,3,4,5]
That is, each array of inversions corresponds to a permutation. We apply a permutation σ which transforms the input to the array of inversions [0,0,0,0,0], which corresponds to the permutation [1,2,3,4,5]. Since we kept track of the original indices, now we only need the to apply σ⁻¹ to [1,2,3,4,5] in order to get the permutation corresponding to the input.

Categories

Resources