How to visualize a 3-way mergesort? - algorithm

[6, 4, 3, 7, 2, 9, 1, 5]
[6, 4], [3, 7, 2], [9, 1, 5]
[6, 4], [3], [7], [2], [9], [1], [5]
swap
[6, 4], [3], [7], [2], [9], [1], [5]
[4, 6], [2, 3, 7], [1, 5, 9]
[2, 3, 4, 6, 7], [1, 5, 9]
[1, 2, 3, 4, 5, 6, 7, 9]
Is this correct? And why is this n log base 3 n?

The merge operations should be 3 way:
[6] [4] [3] [7] [2] [9] [1] [5]
[3 4 6] [2 7 9] [1 5]
[1 2 3 4 5 6 7 9]
|N|J|H|Q|6|L|K|5|P|E|3|A|G|8|D|4|O|I|B|0|9|M|F|2|1|C|7|
|H J N|6 L Q|5 K P|3 A E|8 D G|4 I O|0 9 B|2 F M|1 7 C|
|5 6 H J K L N P Q|3 4 8 A D E G I O|0 1 2 7 9 B C F M|
|0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q|

Related

Minimum reversals of maximal decreasing subarrays needed to sort array

The input is a length n array, containing distinct integers from 1 to n.
We will perform the following algorithm. There are no choices to be made in the algorithm: the only goal is counting the number of reversals this algorithm will perform.
Algorithm is like below:
While(array not sorted in ascending order) do:
Find all the maximal contiguous subarrays which are in decreasing order,
and reverse each of them (simultaneously).
We want to find the total number of times reverse will be called in the above algorithm, in an optimal way (i.e. as efficiently as possible, so direct simulation is probably too slow).
Example 1:
4,3,1,2 // 1 reversal: [4, 3, 1]
1,3,4,2 // 1 reversal: [4, 2]
1,3,2,4 // 1 reversal: [3, 2]
1,2,3,4
// Reverse is called 3 times in above example
Example 2:
5 3 4 2 1 ---> 2 reversals: [5, 3], [4, 2, 1]
3 5 1 2 4 ---> 1 reversal: [5, 1]
3 1 5 2 4 ---> 2 reversals: [3, 1], [5, 2]
1 3 2 5 4 ---> 2 reversals: [3, 2], [5, 4]
1 2 3 4 5 ---> sorted
Total of 7 reversals
Note that O(n^2) reversals may be necessary to sort a sequence in this way, so a direct simulation can take that many steps to run, but there may be a way to count them faster than O(n^2).
If n = 2k, then the sequence k+1, k+2, ... , 2k, 1, 2, 3, ..., k will require k^2 reversals:
Reversals to be performed are surrounded by brackets
5, 6, 7, [8, 1], 2, 3, 4 // 1 reversal
5, 6, [7, 1], [8, 2], 3, 4 // 2 reversals
5, [6, 1], [7, 2], [8, 3], 4 // 3 reversals
[5, 1], [6, 2], [7, 3], [8, 4] // 4 reversals
1, [5, 2], [6, 3], [7, 4], 8 // 3 reversals
1, 2, [5, 3], [6, 4], 7, 8 // 2 reversals
1, 2, 3, [5, 4], 6, 7, 8 // 1 reversal
1, 2, 3, 4, 5, 6, 7, 8
Total of 16 = (8/2)^2 reversals.
Things which I tried:
Trying to convert it to recursion.
Using stack to solve it.
Read about inversion but not able to solve this.
Read on codeforces about the thread but was not relevant to this post.

how to collect elements in a list every 3 places until none remained

here is what i have to do :
[1,2,3,4,5,6,7] - initial sequence
[1,2,4,5,6,7] => 3 is counted out and goes into the result [3]
[1,2,4,5,7] => 6 is counted out and goes into the result [3,6]
[1,4,5,7] => 2 is counted out and goes into the result [3,6,2]
[1,4,5] => 7 is counted out and goes into the result [3,6,2,7]
[1,4] => 5 is counted out and goes into the result [3,6,2,7,5]
[4] => 1 is counted out and goes into the result [3,6,2,7,5,1]
[] => 4 is counted out and goes into the result [3,6,2,7,5,1,4]
Let consider the following python code:
s=[1,2,3,4,5,6,7]
result=[]
cur_idx=0
while 1:
print s,result
if(len(s))==0:
break
if cur_idx<len(s)-2:
cur_idx=cur_idx+2
else:
cur_idx= (len(s)-2+cur_idx) % len(s) -1
result.append(s[cur_idx])
del s[cur_idx]
It does almost what you want:
[1, 2, 3, 4, 5, 6, 7] []
[1, 2, 4, 5, 6, 7] [3]
[1, 2, 4, 5, 7] [3, 6]
[1, 4, 5, 7] [3, 6, 2]
[1, 4, 5] [3, 6, 2, 7]
[4, 5] [3, 6, 2, 7, 1]
[4] [3, 6, 2, 7, 1, 5]
[] [3, 6, 2, 7, 1, 5, 4]
Actually, the difference is when the 7 is removed, because you consider a "virtual index". I found a tedious solution to manage this:
s=[1,2,3,4,5,6,7]
result=[]
cur_idx=0
while 1:
print s,result,cur_idx,len(s)
if(len(s))==1:
result.append(s[0])
s=[]
print "final result:", result
break
if cur_idx<len(s)-2:
cur_idx=cur_idx+2
else:
cur_idx= len(s)-cur_idx
if cur_idx==len(s):
cur_idx=0
result.append(s[cur_idx])
del s[cur_idx]
if cur_idx==len(s):
cur_idx=0
That results into:
[1, 2, 3, 4, 5, 6, 7] [] 0 7
[1, 2, 4, 5, 6, 7] [3] 2 6
[1, 2, 4, 5, 7] [3, 6] 4 5
[1, 4, 5, 7] [3, 6, 2] 1 4
[1, 4, 5] [3, 6, 2, 7] 0 3
[1, 4] [3, 6, 2, 7, 5] 0 2
[4] [3, 6, 2, 7, 5, 1] 0 1
final result: [3, 6, 2, 7, 5, 1, 4]

Trying to create a pair generator

I'm trying to build a pair generator. It takes a list of six names, and generates pairs for the week (5 days), with as few replications as possible.
The minimum I've gotten my replicated pairs down to is 2 (so I have found 5 days of pairs, i.e. 15 total pair combinations, with only 2 identical sets).
My method:
# Start with individuals in an array
[1, 2, 3, 4, 5, 6]
# Bisect the array
[1, 2, 3]
[4, 5, 6] => yields pair combinations [1, 4], [2, 5], [3, 6]
# Move the lower of the bisected arrays along
[1, 2, 3]
[6, 4, 5] => yields pair combinations [1, 6], [2, 4], [3, 5]
# Move along once more
[1, 2, 3]
[5, 6, 4] => yields pair combinations [1, 5], [2, 6], [3, 4]
# Since there are no more unique pair combinations, bisect each array again
(Array 1) [1, 2]
(Array 1) [3] => yields pair combination [1, 3] with 2 'spare'
(Array 2) [4, 5]
(Array 2) [6] => yields pair combination [4, 6] with 6 'spare'
=> 'spare' pair combination [2, 6] is a replication
# Move the lower of the bisected arrays along
(Array 1) [1, 2]
(Array 1) [3] => yields pair combination [2, 3] with 1 'spare'
(Array 2) [4, 5]
(Array 2) [6] => yields pair combination [5, 6] with 4 'spare'
=> 'spare' pair combination [1, 4] is a replication
This process above gives us 13 unique pairs, and then 2 that are non-unique. Every day of the week is covered, but we replicate.
Is there any way to do this more efficiently/to avoid the replication?
This is a round robin tournament where every player plays every other player. Line up the players like below to form the pairs 1 4, 2 5 and 3 6:
123
456
fix player 1, rotate the remaining players:
142
563
to produce pairs 1 5, 4 6 and 2 3. Keep rotating:
154
632
165
324
136
245
I think you're simply after the built-in combination method which returns an enumerator. You can use .to_a to turn it into an array of unique combinations.
[1, 2, 3, 4, 5, 6].combination(2).to_a
# => [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 3], [2, 4], [2, 5], [2, 6], [3, 4], [3, 5], [3, 6], [4, 5], [4, 6], [5, 6]]
This is called a 1-factorization. One 1-factorization of the complete graph on 6 vertices {0,1,2,3,4,oo} is to let the schedule on day i be {{oo,i},{i+1,i+4},{i+2,i+3}} where all of the numbers i+j are reduced mod 5.

Average of several Ruby arrays

I have three Ruby arrays:
[1, 2, 3, 4]
[2, 3, 4, 5]
[3, 4, 5, 6]
How can I take the average of all three numbers in position 0, then position 1, etc. and store them in a new array called 'Average'?
a = [1, 2, 3, 4]
b = [2, 3, 4, 5]
c = [3, 4, 5, 6]
a.zip(b,c)
# [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]]
.map {|array| array.reduce(:+) / array.size }
# => [ 2,3,4,5]
Try this:
arr = ([1, 2, 3, 4] + [3, 4, 5, 6] + [2, 3, 4, 5])
arr.inject(0.0) { |sum, el| sum + el } / arr.size
The concatenation could be done in several ways, depends on how you store your arrays.
As a syntactic sugar, you could do it like this too:
arr.inject(:+).to_f / arr.size

Numpy sorting help

In Numpy, how do I create an array of indices which can be used return the values of the source array in sorted order? eg:
Source:
[[4 2 6 7]
[1 4 8 9]
[3 1 0 3]]
Indices:
[10 4 9 1 8 11 0 5 2 3 6 7]
Take a look at numpy.argsort - it will return the indices that would sort your array. You can also specifiy the axis along which to sort. Try:
a = numpy.asarray([[4, 2, 6, 7], [1, 4, 8, 9], [3, 1, 0, 3]])
numpy.argsort(a.flat)
>> array([10, 4, 9, 1, 8, 11, 0, 5, 2, 3, 6, 7])
The answer's in the manual:
src = [[ ... ]]
ravel_src = np.ravel(src)
indices = np.argsort(ra)

Resources