Problem with sorting teams in Lexicographic order - sorting

I was just trying to sort a list according to its last, second and first item.
a = [['Iran', 1, 1, 1, 0, 4], ['Morocco', 1, 2, 0, -2, 3],['Spain', 1, 0, 2, 2, 5],['Portugal', 1, 1, 1, 0, 4]]
for every list in the list "a", the last item is the points of the team, the second is the wins. I want to sort the list "a" , based on the points , if two or more teams have the same points , according to their wins and if the have both the same points and wins, based on their team name. I tried two ways. The first way was trying to sort them with lambda function:
a = sorted(a, key=lambda x:(x[-1],x[1],x[0])
The second way was:
from operator import itemgetter
a = sorted(a,key=itemgetter(-1,1,0))
but both ways gives the output :
[['Spain', 1, 0, 2, 2, 5], ['Portugal', 1, 1, 1, 0, 4], ['Iran', 1, 1, 1, 0, 4], ['Morocco', 1, 2, 0, -2, 3]]
But I expect something like this ,since Iran and Portugal have the same points and wins and according to 'Lexicographic order', Iran should come first not Portugal.
[['Spain', 1, 0, 2, 2, 5], ['Iran', 1, 1, 1, 0, 4], ['Portugal', 1, 1, 1, 0, 4], ['Morocco', 1, 2, 0, -2, 3]]

Related

Select/4 on a list of lists

On prolog i'm trying to solve the following exercise for connect 4
?- generate_move(2,[[1, 0, 1, 0],[0, 1, 1, 0],[0, 0, 1, 1],[1, 0, 0, 1]],BP).
BP = [[1, 2, 1, 0], [0, 1, 1, 0], [0, 0, 1, 1], [1, 0, 0, 1]] ;
BP = [[1, 0, 1, 2], [0, 1, 1, 0], [0, 0, 1, 1], [1, 0, 0, 1]] ;
BP = [[1, 0, 1, 0], [2, 1, 1, 0], [0, 0, 1, 1], [1, 0, 0, 1]] ;
BP = [[1, 0, 1, 0], [0, 1, 1, 2], [0, 0, 1, 1], [1, 0, 0, 1]] ;
BP = [[1, 0, 1, 0], [0, 1, 1, 0], [2, 0, 1, 1], [1, 0, 0, 1]] ;
BP = [[1, 0, 1, 0], [0, 1, 1, 0], [0, 2, 1, 1], [1, 0, 0, 1]] ;
Where the rule is that is returns every possible move left for a player provided (in this case 2)
I was thinking of using select/4 to find every result possible for each list in the list of lists, then join it. But i'm failing to "condense" results and my second iteration of findall fails:
generate_move(_,[],[]).
generate_move(Player,[H|T],[FinalLine|FinalBoard]) :-
findall(X0,(select(0, H, Player, X0)),FinalLine),
join_results(FinalLine,T,FinalBoard),
generate_move(Player,T,FinalBoard).
join_results([],[],[]).
join_results([H|T],LeftOvers,FinalBoard) :-
append([H],LeftOvers,FinalBoard),
join_results(T,LeftOvers,FinalBoard).
Any tips? My join_results returns false at the second call and so does my findall.

Finding duplicate columns in a nested array

0 1 2 3 4 5 6
0{1,2,1,2,1,5,5}
1{5,4,5,4,5,1,1}
2{2,4,2,4,2,1,1}
3{1,2,1,2,1,1,1}
4{4,4,4,4,4,1,1}
5{2,4,2,4,2,2,2}
output: {{0,2,4}, {1,3}, {5,6}} (can use any data structure)
Let's say there is a nested array like above. If we wanted to find column indices that contain the same exact numbers in the same order (for example, column 0, 2, 4 with (1,5,2,1,4,2) and column 1, 3 with (2,4,4,2,4,4), and column 5, 6 with (5,1,1,1,1,2), how can we go about with this efficiently? Will it require dynamic programming?
Thanks in advance.
You can just iterate through the columns, keeping a hashmap of the columns that you've seen so far. Here's an implementation in python:
x = [[1, 2, 1, 2, 1, 5, 5],
[5, 4, 5, 4, 5, 1, 1],
[2, 4, 2, 4, 2, 1, 1],
[1, 2, 1, 2, 1, 1, 1],
[4, 4, 4, 4, 4, 1, 1],
[2, 4, 2, 4, 2, 2, 2]]
seen_before = {}
for v, col in enumerate(zip(*x)):
if tuple(col) not in seen_before:
seen_before[tuple(col)] = [v]
else:
seen_before[tuple(col)].append(v)
This solves the problem in linear time. I hope that's good enough for you.

Convert string to list of integers

This is the input string: 1,1,1,1,1,1,1,1,1,1,-9\n1,1,1,1,1,1,1,1,1,1,1\n2,1,2,1,2,1,2,1,2,1,2\n1,0,1,0,1,0\n3,1,2,-2,1,-2
I need to convert this string to lists of integers, so the output should be: [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -9], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2], [1, 0, 1, 0, 1, 0], [3, 1, 2, -2, 1, -2]]
My solution is:
text.split("\n").map do |row|
row.split(",").map(&:to_i)
end
Is there a better, more efficient way?
Refactored as a One-Liner
I often find that when people say "more efficient" or "more elegant" they just mean shorter or more compact. There's nothing wrong with your code, and unless you're performing actions on tens of thousands of arrays I doubt efficiency is anything other than a premature optimization. That said, you can write a one-liner for this if you want.
For example, using Ruby 2.7.1 and str as your input string:
str.split.map { _1.split(?,).map &:to_i }
#=> [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -9], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2], [1, 0, 1, 0, 1, 0], [3, 1, 2, -2, 1, -2]]
If you pretty-print the result with Kernel#pp, you'll get the results you expect.
[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -9],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2],
[1, 0, 1, 0, 1, 0],
[3, 1, 2, -2, 1, -2]]
This isn't better than your existing code in any meaningful way, and I won't even claim it's faster. About all I can really say is that it's more compact and uses fewer lines, so please use your own judgment about its readability and utility value.

Understand disaster model in PyMC

I start learning PyMC and strungle to understand the very first tutorial´s example.
disasters_array = \
np.array([ 4, 5, 4, 0, 1, 4, 3, 4, 0, 6, 3, 3, 4, 0, 2, 6,
3, 3, 5, 4, 5, 3, 1, 4, 4, 1, 5, 5, 3, 4, 2, 5,
2, 2, 3, 4, 2, 1, 3, 2, 2, 1, 1, 1, 1, 3, 0, 0,
1, 0, 1, 1, 0, 0, 3, 1, 0, 3, 2, 2, 0, 1, 1, 1,
0, 1, 0, 1, 0, 0, 0, 2, 1, 0, 0, 0, 1, 1, 0, 2,
3, 3, 1, 1, 2, 1, 1, 1, 1, 2, 4, 2, 0, 0, 1, 4,
0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1])
switchpoint = DiscreteUniform('switchpoint', lower=0, upper=110, doc='Switchpoint[year]')
early_mean = Exponential('early_mean', beta=1.)
late_mean = Exponential('late_mean', beta=1.)
I don´t understand why early_mean and late_mean is modeled as stochastic variable following exponential distribution with rate = 1. My intuition is that they should be deterministic calculated using disasters_array and switchpoint variable e.g.
#deterministic(plot=False)
def early_mean(s=switchpoint):
return sum(disasters_array[:(s-1)])/(s-1)
#deterministic(plot=False)
def late_mean(s=switchpoint):
return sum(disasters_array[s:])/s
disasters_array are the data generated by a Poisson process, under the assumptions of this model. late_mean and early_mean are the parameters associated with this process, depending on when in the time series they occurred. The true values of the parameters are unknown, so they are specified as stochastic variables. Deterministic objects are only for nodes that are completely determined by the values of their parents.
Think of early_mean and late_mean stochastics as model parameters, and the Exponential as the prior distribution for these parameters. In the version of the model here, the deterministic r and likelihood D lead to posteriors on early_mean and late_mean through MCMC sampling.

Populate array from vector

I would like to populate an 2 dimensional array, from a vector.
I think the best way to explain myself is to put some examples (with a array of [3,5] length).
When vector is: [1, 0]
[
[4, 3, 2, 1, 0],
[4, 3, 2, 1, 0],
[4, 3, 2, 1, 0]
]
When vector is: [-1, 0]
[
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4]
]
When vector is: [-2, 0]
[
[0, 0, 1, 1, 2],
[0, 0, 1, 1, 2],
[0, 0, 1, 1, 2]
]
When vector is: [1, 1]
[
[2, 2, 2, 1, 0],
[1, 1, 1, 1, 0],
[0, 0, 0, 0, 0]
]
When vector is: [0, 1]
[
[2, 2, 2, 2, 2],
[1, 1, 1, 1, 1],
[0, 0, 0, 0, 0]
]
Have you got any ideas, a good library or a plan?
Any comments are welcome. Thanks.
Note: I consulted Ruby "Matrix" and "Vector" classes, but I don't see any way to use it in my way...
Edit: In fact, each value is the number of cells (from the current cell to the last cell) according to the given vector.
If we take the example where the vector is [-2, 0], with the value *1* (at array[2, 3]):
array = [
[<0>, <0>, <1>, <1>, <2>],
[<0>, <0>, <1>, <1>, <2>],
[<0>, <0>, <1>, *1*, <2>]
]
... we could think such as:
The vector [-2, 0] means that -2 is
for cols and 0 is for rows. So if we
are in array[2, 3], we can move 1 time
on the left (left because 2 is
negative) with 2 length (because
-2.abs == 2). And we don't move on the top or bottom, because of 0 for
rows.
It's quite easy to achieve this:
require 'matrix'
def build(rows, cols, vector)
Matrix.build(rows, cols){|i, j| vector.inner_product([cols-j-1, rows-i-1]) }
end
build(3, 5, Vector[1, 0]) # => your first example
# ...
build(3, 5, Vector[0, 1]) # => your last example
You will need the latest Matrix library which introduces Matrix.build.
Note: I find your examples a bit odd, and the third one even stranger. Looks like we have to divide by the vector you give, unless it's 0? Anyways, just adapt the block to the formula you need.
ok i am a little confused but i am going to take a shot in the dark
What you want is to run through every point in the array and call a function that would calculate the value at that position
so we have
loop i
loop j
array[i,j]=Vectorfunction(i,j,vector);
next j
next i
function(i,j,vector)
Here i am guessing you somehow use the position in the array, and the slope of the line defined by the vector. What that is i can't extract from the data, but i am sure such a function exists.
Most likely this involves arccos to get the angle. and then return i*arcsin+j+arccos

Resources