Numpy sorting help - sorting

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)

Related

How Do I Ensure a Candidate Latin Square Is a Valid Damm Operation Table

I am attempting to write a function in Scala that takes a valid Latin Square as input and then returns a Boolean value indicating whether the input Latin Square is a valid instance of an operation-table for the Damm Algorithm, or not. The Damm Algorithm appears to be of the "Check digit" class of error detection mechanisms.
The desired function is an implementation of the implication described in the Design section of the Wikipedia article for the Damm Algorithm. The implication is captured by the assertion of:
a weak totally anti-symmetric quasigroup with the property x ∗ x = 0
I'm insufficient in both the math skills to properly read and interpret Damm's paper, and then having enough German (the language within which the paper was written) reading skills to be able to confidently interpret how I would encode a correct validation function.
Given the following function definition:
def validate(latinSquare: List[List[Int]]): Boolean =
???
With what would I replace the ????
Within the paper, a single instance of a valid 10x10 Latin Square is provided. It is reproduced within the Wikipedia article and looks like this:
|0 1 2 3 4 5 6 7 8 9
-+-------------------
0|0 3 1 7 5 9 8 6 4 2
1|7 0 9 2 1 5 4 8 6 3
2|4 2 0 6 8 7 1 3 5 9
3|1 7 5 0 9 8 3 4 2 6
4|6 1 2 3 0 4 5 9 7 8
5|3 6 7 4 2 0 9 5 8 1
6|5 8 6 9 7 2 0 1 3 4
7|8 9 4 5 3 6 2 0 1 7
8|9 4 3 8 6 1 7 2 0 5
9|2 5 8 1 4 3 6 7 9 0
I can see there are others who have sought an answer to this. However, no one has yet provided a requested code-based valid Latin Square solution.
I have coded up a generic Latin Square generator, but need the above validation function which will serve as the filter to eliminate each candidate Latin Square that does not meet the necessary condition(s) of the above implication.
In functional programming terms, the checksum algorithm is foldLeft with a carefully chosen binary operation. The requirements for this binary operation, in English:
In every two-digit input, if we change one of the digits, then the checksum changes (Latin square…);
In every three-digit input, if the latter two digits are distinct and we swap them, then the checksum changes (…with weak total antisymmetry);
The Latin square has zeros on the diagonal.
In Python 3:
def validate(latinSquare):
Q = range(len(latinSquare))
return all(
x == y
for c in Q
for x in Q
for y in Q
if latinSquare[latinSquare[c][x]][y] == latinSquare[latinSquare[c][y]][x]
) and all(latinSquare[x][x] == 0 for x in Q)
print(
validate(
[
[0, 3, 1, 7, 5, 9, 8, 6, 4, 2],
[7, 0, 9, 2, 1, 5, 4, 8, 6, 3],
[4, 2, 0, 6, 8, 7, 1, 3, 5, 9],
[1, 7, 5, 0, 9, 8, 3, 4, 2, 6],
[6, 1, 2, 3, 0, 4, 5, 9, 7, 8],
[3, 6, 7, 4, 2, 0, 9, 5, 8, 1],
[5, 8, 6, 9, 7, 2, 0, 1, 3, 4],
[8, 9, 4, 5, 3, 6, 2, 0, 1, 7],
[9, 4, 3, 8, 6, 1, 7, 2, 0, 5],
[2, 5, 8, 1, 4, 3, 6, 7, 9, 0],
]
)
)
This is a conversion into Scala of the Python 3 Answer that was provided by David Eisenstat's answer.
View in Scastie:
def isValidDammOperationTable(validLatinSquare: List[List[Int]]): Boolean = {
val indices = validLatinSquare.indices.toList
(
indices.forall(index => validLatinSquare(index)(index) == 0)
&& indices.forall(
c =>
indices.forall(
x =>
indices.forall(
y =>
(validLatinSquare(validLatinSquare(c)(x))(y) != validLatinSquare(validLatinSquare(c)(y))(x))
|| (x == y)
)
)
)
)
}
val exampleLatinSquareX10: List[List[Int]] =
List(
List(0, 3, 1, 7, 5, 9, 8, 6, 4, 2)
, List(7, 0, 9, 2, 1, 5, 4, 8, 6, 3)
, List(4, 2, 0, 6, 8, 7, 1, 3, 5, 9)
, List(1, 7, 5, 0, 9, 8, 3, 4, 2, 6)
, List(6, 1, 2, 3, 0, 4, 5, 9, 7, 8)
, List(3, 6, 7, 4, 2, 0, 9, 5, 8, 1)
, List(5, 8, 6, 9, 7, 2, 0, 1, 3, 4)
, List(8, 9, 4, 5, 3, 6, 2, 0, 1, 7)
, List(9, 4, 3, 8, 6, 1, 7, 2, 0, 5)
, List(2, 5, 8, 1, 4, 3, 6, 7, 9, 0)
)
println(isValidDammOperationTable(exampleLatinSquareX10)) //prints "true"

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]

Transform one list into another [duplicate]

This question already has answers here:
Algorithm: optimal way to rearrange a list from one order to another?
(4 answers)
Closed 4 years ago.
Given two lists, for example:
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [2, 4, 6, 7, 0, 1, 3, 5, 8, 9]
I wish to find a series of moves which will transform list a into list b, where each move is an operation:
move(from_index, to_index)
which moves the element at location from_index and places it at location to_index. So if:
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
then the operation move(3,1) on the list a will transform a into:
a = [0, 3, 1, 2, 4, 5, 6, 7, 8, 9]
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [2, 4, 6, 7, 0, 1, 3, 5, 8, 9]
move(0, 8)
a = [1, 2, 3, 4, 5, 6, 7, 0, 8, 9]
move(0, 8)
a = [2, 3, 4, 5, 6, 7, 0, 1, 8, 9]
move(1, 8)
a = [2, 4, 5, 6, 7, 0, 1, 3, 8, 9]
move(2, 8)
a = [2, 4, 6, 7, 0, 1, 3, 5, 8, 9]
a==b
Hopefully that's what you're looking for.
Basically, start with the left- most element and move it to where it should be. For example, I took 0 and placed it right after the value that it is supposed to eventually end up behind, which is 7. I continued moving from left to right until all of the elements were in the desired order.
I'd iterate over the second sequence (the sorted list) and swap items in the first. I wrote this pseudo-code in python:
>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> b = [2, 4, 6, 7, 0, 1, 3, 5, 8, 9]
>>> def swap(seq, i, j):
... a = seq[i]
... seq[i] = seq[j]
... seq[j] = a
...
>>> for index_in_b, value in enumerate(b):
... index_in_a = a.index(value)
... if index_in_b != index_in_a:
... swap(a, index_in_a, index_in_b)
... print('move {} to {}'.format(index_in_a, index_in_b))
move 0 to 2
move 1 to 4
move 2 to 6
move 3 to 7
move 4 to 6
move 5 to 6
move 6 to 7
In this case I'm moving the items in the first sequence by swapping them.
Update
We can slightly improve the performance in python by removing the move inside swap function and also removing the function call. Here is a performance comparison:
import timeit
s1 = """
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [2, 4, 6, 7, 0, 1, 3, 5, 8, 9]
def swap(seq, i, j):
a = seq[i]
seq[i] = seq[j]
seq[j] = a
for index_in_b, value in enumerate(b):
index_in_a = a.index(value)
if index_in_b != index_in_a:
swap(a, index_in_a, index_in_b)"""
s2 = """
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [2, 4, 6, 7, 0, 1, 3, 5, 8, 9]
for index_in_b, value in enumerate(b):
index_in_a = a.index(value)
if index_in_b != index_in_a:
a[index_in_a], a[index_in_b] = a[index_in_b], a[index_in_a]"""
# on an i7 macbook pro
timeit.timeit(s1)
4.087386846542358
timeit.timeit(s2)
3.5381240844726562
Slightly better, but for sure there are better ways to achieve this.

How to multiply every other element of an array?

Let's say that I have an array like this:
[1,2,3,4,5,6,7]
how can I multiply every other number of this array except the first by 2
so my new array looks like this
[1,4,3,8,5,12,7]
You can use map and with_index:
[1,2,3,4,5,6,7].map.with_index{|v,i| i % 2 == 0 ? v : v * 2 }
# => [1, 4, 3, 8, 5, 12, 7]
[1,2,3,4,5,6,7].each_slice(2).flat_map{|k, l| [k, *(l * 2 if l)]}
# => [1, 4, 3, 8, 5, 12, 7]

Resources