I need an algorithm that can map the runs in a permutation to a single number, but also reduce the subsequent numbers.
So a run is a sequential set of numbers in a permutation that is sorted and in-order. In the list, 1;2;3;5;6;4 there are two runs, 1;2;3 and 5;6. I want to replace these with a single number, a minimum, so if, after removing runs, we have a permutation of 4 elements, the permutation uses the numbers 1 ... 4. In the above, we have to reduce the two runs. the first run would be 1, 4 transforms to 2, and [5;6] transforms to 3, to hold the second criteria. If I sort the reduced permutation then expand the elements inside from the mapping, and sort the original permutation I will get the same result. The resultant permutation shouldn't have any runs in it.
For example (i've highlighted the runs):
(1;2;3;4;5;6) => 1 //Mappings: 1->1;2;3;4;5;6
(2;3;4);1;(5;6) => 2 1 3 // Mappings: 2->2;3;4, and 3->5;6
(3;4);(1;2);(5;6) => 2 1 3 // Mappings: 2->3;4, and 1->1;2 and 3->5;6
for now, I am passing over the list and making a list of lists, grouping the runs. Really the second part is the hard part to make a clean solution. I have thought of the naive approach, curious if anyone has some clever trick that can do it better then mine, I'm at like O( 2n + n log n),
- replacing the runs with the head element of the run and inserting that data into a hashtable (for recoverability)
- sorting to create a map to the missing digits with it's sorted index. [1;6;5;4] would output [(1,1);(4,2);(5,3);(6,4)]
- replacing the list in step1 with the map created in step2 and updating the hashtable for translation.
running through an example, again:
step 1: replace runs with the head element of the run and inserting data into a hash table [1;3;4;2;5;6;] -> [1;3;2;5] step 2: sort array to create map [1235], so we know that, in the previous array, 1 maps to 1, 2 to 2, 3 to 3, 4 to 5. step 3: do above translation on array from step one. [1;3;2;4]
If I sort this permutation and reconstruct: [1;2;3;4], 3->3;4 and 4->5;6 I get, 1;2;3;4;5;6. Also sorted.
I'm using lists, so a functional approach would be preferred. No code necessary. All ideas, of course, welcome.
EDIT:
mweerden:
It's not clear to me what the precise conditions on the mapping are. Why exactly isn't it allowed to just produce the permutation [1,2,...,N] for a permutation with N runs? You seem to prefer to map a run to a number from that run, but (as this isn't always possible) you seem to allow some freedom. –
I don't prefer to map a run to a number within that run (look above!), but I need to preserve an ordering. The permutation [1;2;3...N] is a run, and thus can be reduced further. That is why it is invalid. The order will matter in further operations in another algorithm, but the individual elements can be expanded at the end to rescue the original permutation.