Sort Arrays in Array in Lua - arrays

Hi i am quite new to lua and i need to sort an Array in Lua.
So i have following code
local distances = {2,3,1}
table.sort(distances)
now i get
distances[1] -> 1
distances[2] -> 2
distances[3] -> 3
now i need to save some information for my "distances" aswell
something like the following
local distances = {{C1,2},{C2,3},{C3,1}}
now it is impossible to call the sort-function, but i need them sorted.
Is it possible to reach this?
distances[1] -> {C3,1}
distances[2] -> {C2,2}
distances[3] -> {C1,3}
Thanks guys :)

table.sort takes a comparison function as its second argument.
table.sort(distances, function (left, right)
return left[2] < right[2]
end)

Related

Haskell - Sum of the differences between each element in each matrix

I am very new to Haskell (and functional programming in general) and I am trying to write a function called
"profileDistance m1 m2" that takes two matrices as parameters and needs to calculate the sum of the differences between each element in each matrix... I might have not explained that very well. Let me show it instead.
The matrices are on the form of: [[(Char,Int)]]
where each matrix might look something like this:
m1 = [[('A',1),('A',2)],
[('B',3),('B',4)],
[('C',5),('C',6)]]
m2 = [[('A',7),('A',8)],
[('B',9),('B',10)],
[('C',11),('C',12)]]
(Note: I wrote the numbers in order in this example but they can be ANY numbers in any order. The chars in each row in each matrix will however match like shown in the example.)
The result (in the case above) would look something like (psuedo code):
result = ((snd m1['A'][0])-(snd m2['A'][0]))+((snd m1['A'][1])-(snd m2['A'][1]))+((snd m1['B'][0])-(snd m2['B'][0]))+((snd m1['B'][1])-(snd m2['B'][1]))+((snd m1['C'][0])-(snd m2['C'][0]))+((snd m1['C'][1])-(snd m2['C'][1]))
This would be easy to do in any language that has for-loops and is non-functional but I have no idea how to do this in Haskell. I have a feeling that functions like map, fold or sum would help me here (admittedly I am not a 100% sure on how fold works). I hope there is an easy way to do this... please help.
Here a proposal:
solution m1 m2 = sum $ zipWith diffSnd flatM1 flatM2
where
diffSnd t1 t2 = snd t1 - snd t2
flatM1 = concat m1
flatM2 = concat m2
I wrote it so that it's easier to understand the building blocks.
The basic idea is to iterate simultaneously on our two lists of pairs using zipWith. Here its type:
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
It means it takes a function with type a -> b -> c, a list of a's and a list of b's, and it returns a list of c's. In other words, zipWith takes case of the iteration, you just have to specify what you want to do with every item the iteration yields, that in your case will be a pair of pairs (one from the first matrix, another one from the second).
The function passed to zipWith takes the snd element from each pair, and computes the difference. Looking back at zipWith signature you can deduce it will return a list of numbers. So the last thing we need to do is summing them, using the function sum.
There's one last problem. We actually do not have two lists of pairs to be passed to zipWith!, but two matrices. We need to "flatten" them in a list, preserving the order of the elements. That's exactly what concat does, hence the calls to that function in the definitions of flatM1 and flatM2.
I suggest you look into the implementation of every function I mentioned to have a better grasp of how iteration is expressed by mean of recursion. HTH

Function Recursion within itself - haskell

I was trying to recursively pass a function to itself a given number of times. So given the input in form of Function | RepeatNumber(Count) | Argument. So as an example if given the input: f 3 2 it would return f(f(f 2) This should then also work if the Function value where "square" it would Square the argument.
In terms of the logic I approached it as follows:
def repeatnew func count arg
if count == 1 then (func arg)
else (func (repeatnew func (count -1) arg))
I've been trying to research a solution to this for a while and I came across using Iterate and some other functions. Finally I came across this: https://wiki.haskell.org/Higher_order_function However I was unable to implement a working solution.
Edit: The solutions I did try to implement I could get compiling correctly, I am still very inexperienced with haskell and would appreciate an explanation on how to create a higher order function using my parameters.
Spinning off from #Antisthenes' comment, One other way to do this is using the foldl1 with no base case.
pipeNTimes :: (a -> a) -> Int -> (a -> a)
pipeNTimes f n = foldl1 (.) $ replicate n f
pipeNTimes (*2) 3 2 -- returns 16
I am admittedly only a beginner at Haskell, so this may be a naive implementation, but I think this does what you are looking for:
applyRecursively f x y
| x == 1 = f y
| otherwise = f (applyRecursively f (x-1) y)
The applyRecursively function takes a function and two numbers as arguments.
If the middle argument (the count) is 1 then we apply the parameter function to the argument y. This is the edge case that stops the recursion.
The otherwise guard clause then calls recursively with the x parameter decremented, and applies function f to the result.
I have tested it using a lambda like this:
applyRecursively (\x -> x + 1) 3 3
It should add 1 to the values of 3 three times - it returns a value of 6 so it looks like it works.
As I say, I'm a beginner but I think this does what you're looking for.

Sort an array of arrays in Erlang

I need to sort arrays but not classical ones. Moreover, in Erlang !
I'm talking about arrays where each element is an array of two integers.
For example :
[ [6,0], [12,1], [5,2], [10,3] ]
I need this array to be sorted in function of the first element of each arrays
Like this :
[ [5,2], [6,0], [10,3], [12,1] ]
First, I succeed with this :
-module(insertSort).
-export([insertion/1,insert/1,insert/2]).
insertion(L) -> lists:foldl(fun insert/2, [], L).
insert([]) -> [].
insert(X,[]) -> [X];
insert([],Y) -> [Y];
insert(X= [X1,_], L= [[H1,_] | _]) when X1 =< H1 -> [X|L];
insert(X,[H|T]) -> [H|insert(X, T)].
Sometimes, arrays are sorted. But I have two examples that gives me two weird cases:
First :
[ [10,3], [5,2], [12,1], [6,0] ]
become :
[[[5,2], [6,0], [10,3], [12,1]]]]
Not bad but I can't work with that weird construction. It seems that I have an array, where there is an array inside, where there is all my two-elements arrays inside.
Second :
[ [5,16], [11,12], [9,8], [16,4] ]
become :
[[[5,16], "\t\b","\v\f",[16,4]]]
Yes, really, with these \t\b..
I'm a beginner in Erlang but I succeed to do a lot of things by myself.
My project is about Shank Algorithm, trying to solve y = a^x mod n where y, a and n are given.
Can you please help me by telling me what is wrong with my insertSort module ?
Thanks a lot, sorry for my english, I tried to do my best.
As I said in my comment, the sort function of the lists library does exactly what you want.
1> lists:sort( [ [6,0], [12,1], [5,2], [10,3] ]).
[[5,2],[6,0],[10,3],[12,1]]
2>
You probably shouldn't write your own sorting function. If lists:sort(List) isn't what you want for your use case, you could sort on only the first element of the sublists like this:
lists:sort(fun ([H1|_],[H2|_]) -> H1 =< H2 end,
List)
I think problem is with line:
insert([],Y) -> [Y];
Y is already a sorted list so it should be returned as it is
insert([],Y) -> Y;
Erlang strings are list of integers so when your list is not really a string but contains code points of your specified encoding, then it is printed in string notation, but it's still a list. List [65,65,67,68] is equal to "ABCD". Try to type that list into your shell, it's just an erlang pretty printing... not accurate sometimes.

Haskell iteration (not literally) over a list

I know I should be forgetting about iterating in functional languages, but I dont know how else to put forth my question.
If I have a list of integers arranged in ascending or descending order, and I have an arbitrary number that may or may not be present in the list, how can I loop over the list to find a number that is small than the given number and return that integer.
I just need to know how to go about it.
You could use find to find the first element matching a predicate you specify. Example:
find even [3,5,7,6,2,3,4]
Or, you could drop all the unwanted elements from the left:
dropWhile (not . even) [3,5,7,6,2,3,4]
(and possibly take the first element remaining, which has to be even).
Or, you could filter out unwanted elements
filter even [3,5,7,6,2,3,4]
Or, you could use recursion and code everything yourself.
You can recursively deconstruct the list with pattern matching:
searchList :: Int -> [Int] -> ???
searchList n [] = ???
searchList n (x:xs) = ???
You check whether x is the number you want, and if not you can call searchList n xs to search the rest of the list.
The normal way to do something like that would be with the library function foldr, but it would be better to understand how to do this with recursion first.
You can have "state" in a list iteration by using a fold - the state is passed from one iteration to the next in a function argument.
An example:
sup :: [Int] -> Int -> Int
sup xs y = go (head xs) xs
where
go s [] = s
go s (x:xs) = if x >= y then s else go x xs
Here s is the "state" -- it is the latest value in the list that is less than y.
Because you said the input list would never be empty, head xs is okay here.
This is almost what you want. Perhaps you can modify it to handle all of your conditions.

Haskell - Array

I'm a newbie to Haskell, got stuck on a simple question:
aaa :: [[(Char, Float)]] -> Float -> [[(Char, Float)]]
aaa [[]] a = error "no indata"
aaa [[(a,b)]] c = [[(a, b/c)]]
aaa inD c = ??
How to make it work with more than 1 element in Array?
Ex: aaa [[('a',3)],[('b',4)],[('c',5)]] 4
the result: [[('a',0.75)],[('b',1)],[('c',1.25)]]
Any hint pls, thx!
You can define operations on lists as follows (I give you a simpler example that adds 1 to each list item)
f [] = []
f (head:tail) = (head + 1):(f tail)
I.e. head:tail represents a list; to be more specific, it represents the first list item (head) and the remaining list if we take the first item away (tail). Then, you usually apply your stuff to head and make a recursive call using tail.
Completing your example (without testing) this would yield:
aaa ([(a,b)]:tail) c = [(a, b/c)] : (aaa tail c)
One thing: You are dealing with a list and want to modify each element of the list in a specific way (but each element is transformed the same way). For such occasions, Haskell provides its intrinsic map function, which takes:
the function to transform a list items
the list of items
as parameters and returns the transformed list.
First of all, that [...] stuff denotes lists, not arrays; there is a fundamental difference between those two.
Try to think in terms of fmap :: Functor a => (a -> b) -> f a -> f b. This function takes another function and applies it over a data-structure. You could use it to implement your function. Here is a simple implementation. Try to understand it:
aaa l c = fmap (fmap (fmap (/c))) l

Resources