How to recurse through a list of tuples? - haskell

I am attempting to make a very simple program that finds the average distance a group of points is from 0. The input will be a group of tuples (i.e. (1,2) and (2,3)), it should calculate each points distance from 0 and then find the average.
I understand the logic and the general formula (again, it's very simple), which I have here:
averageDist ((x,y):xs) = (sqrt((x*x)+(y*y)))/length xs
I just don't understand the syntax for lists when using tuples. As you can see, I tried (x,y):xs and while it compiles, ghci thinks that all values are different types. How can I fix this program so I can iterate and apply the formula to each tuple?
I'm totally new to Haskell and I appreciate any and all help.
Thanks

First write an average function:
average :: [Double] -> Double
average xs = ...
and a distance function:
distance :: (Double,Double) -> Double
distance (x,y) = ...
Then you can use these functions together with map:
averageDistance :: [(Double,Double)] -> Double
averageDistance xs = average ( map distance xs )

Related

How can I generate every possible solution of a varied size grid which has n points

To give overall context, I have a 2d grid of size N (the size is known but can vary and is always a square i.e x axis = y axis) and M points on the grid that I'm trying to find (the amount of points is known but their locations are not). I want to iterate through every possible solution for said grid. Also the points don't have to be in a specific order, so
[(1,1),(1,2)]
is the same as
[(1,2),(1,1)]
So for example assume the grid was a 2x2 and their was 2 points. Then all the possible solutions would be
[(1,1),(1,2)]
[(1,1),(2,1)]
[(1,1),(2,2)]
[(1,2),(2,1)]
...and so on...
I'm trying to create a function that will output these to me.
I know the function below can create me a full grid, but I don't know how to use this to generate all the possible point locaitons. And whether this grid is even useful in the first place
createGrid :: Int -> [(Int, Int)]
createGrid num = [ (x,y) | x <- [1..num], y <- [1..num]]
Any help would be appreciated
It sounds like you just want a list of the unique ways to choose M items from a list (grid) of N*M items. You already know how to generate this list, so all you need is the ways to choose K items from a list. This is a well-trodden path; for example, see Function to generate the unique combinations of a list in Haskell.
In general it is useful to try to do this sort of splitting up: break your program into smaller pieces and see how many of them are easy to solve. If you try to do everything all at once in one function, you end up repeating work and often wind up with a function that is difficult to read.
For a given grid, if m is 0, then we return the empty list, when m is greater than 0, then we yield a point and recurse on the rest of the list, so:
possibleGrids :: Int -> Int -> [[(Int, Int)]]
possibleGrids n mm = go mm 1 0
where go 0 _ _ = [[]]
go m i j = [(x, y) : tl | x <- [i .. n], y <- [1 .. n], x > i || y > j, tl <- go (m-1) x y]
The first parameter here is n, the size of the grid. The second one is m, the number of points to mark. For a 2×2 grid, this gives us:
ghci> possibleGrids 2 0
[[]]
ghci> possibleGrids 2 1
[[(1,1)],[(1,2)],[(2,1)],[(2,2)]]
ghci> possibleGrids 2 2
[[(1,1),(1,2)],[(1,1),(2,1)],[(1,1),(2,2)],[(1,2),(2,1)],[(1,2),(2,2)],[(2,1),(2,2)]]
The code uses symmetry breaking, so it will not mark twice (or more) the same point, nor will it provide the list of points in a different order.

how to do this in haskell ? [x^0,x^1,x^2,x^3 ...]

i want to have a list like this one
[x^0,x^1,x^2,x^3 ...]
is it possible to have such a list
for example
ex : x = 2 [1,2,4,8,16,32 ..]
You can use iterate or unfoldr to double a number many times. This could be more efficient than computing x^n for each n.
Below, I use x=2, but you can use any x.
> take 10 $ iterate (*2) 1
[1,2,4,8,16,32,64,128,256,512]
> take 10 $ unfoldr (\x -> Just (x,2*x)) 1
[1,2,4,8,16,32,64,128,256,512]
Also beware that bounded integer types such as Int will overflow pretty fast in this way.
Yes, it is pretty easy thing to do in haskell.
You create an infinite stream of positive numbers and then map over them with function n ↦ x^n
f :: Num a => a -> [a]
f x = fmap (\n -> x^n) [0..]
> take 10 (f 2)
[1,2,4,8,16,32,64,128,256,512]
In Haskell, the list is linear no matter the progression. By linear, I mean non-recursive. The elements in the list are not dependent on one or more previous elements or an initial element.
In Haskell such lists are used very much. In Haskell there are two primary facilities for producing such lists. The first is map and it is effective without any filtering or recursion.
f b n = map (b^) [0..n]
The second is the list comprehension
f b n = [b^x|x<-[0..n]]
In both it is simple to set the limit or number of elements in the result. These could both be made into infinite lists if desired by excluding the n in both the left and right side of the equations.

Sum up distances of a permutation list (Haskell)

I have a list of Towns and a function, which gives out the distance between two of them. For example:
dist!(Bielefeld,Muenchen) = 598
Now I want to make a function where I can calculate the full length of a random tour between all Towns. For example:
tourlength [a permutation of the 12 Towns] = whole way you have to travel (as Int)
I hope you know what I mean. I'm not sure how to integrate the dist! function into the new one.
My second problem is that I want to calculate which city has the shortest distance to a second one. To solve that, I wanted to use the greedy function below:
greedy a [] = [a]
greedy a X = a : greedy (z X - [z])
z = argmin x : dist a x
tspgreedy X = greedy (s x - [s])
But I don't know how to translate it to haskell...
Thanks for food for thought
In answer to your first question, one way of calculating the total distance of a journey that passes through a series of towns goes like this:
import Data.Complex (Complex, magnitude)
type Town = Complex Double
dist :: Town -> Town -> Int
dist x y = round $ magnitude (x-y)
journeyDistance :: [Town] -> Int
journeyDistance itinerary = sum . zipWith dist itinerary . drop 1 . cycle $ itinerary
(Don't be put off by the use of complex numbers; you can define your towns and the distances between them however you like, say, by a table lookup.) The idea behind this code is to zip the list representing the itinerary with itself -- but offset by one town (hence drop 1) -- calculating distances as we zip. That is, we pair every town with its successor in the itinerary, but the pairing operation is not the usual tuple construction but rather our own distance function (hence zipWith dist). cycle constructs an infinite repetition of the itinerary to ensure there are enough towns to "fully zip" with the original, finite list of towns.
In fact, because the second list in the zip "cycles around", the last town in the first list will be paired with the first town, forming a roundtrip. If you'd rather end your journey in the last town without returning to the first, then you could write the function like this:
journeyDistance itinerary = sum . init . zipWith dist itinerary . drop 1 . cycle $ itinerary
A quick way to solve your second problem might be like this:
import Data.List (minimumBy, tails)
import Data.Ord (comparing)
closestTowns :: [Town] -> (Town, Town)
closestTowns towns = minimumBy (comparing $ uncurry dist) [(x, y) | (x:xs) <- tails towns, y <- xs]

Haskell Homework - Decimal List [Int] -> Int

The assignment is to define function decimal :: [Int] -> Int in which a list of positive ints is to give the decimal number so that the list [1,4,3,1,9] is to return the Integer 14319. I am to use the fold function.
I don't really have good idea to start here, so I just need a push in the right direction, but I was thinking about the Horner-scheme. Thanks!
In the fold, you start from the left and move towards the right. As you consume the next element from the list, you multiply what you already had by 10 and add the new element to that.
So if you seed the foldl with 0, and had [1,2,3], your function would multiply current (0) by 10 (also 0), then add 1. Moving on, multiply current (1) by 10 (to get 10) and add 2 (12). Then finally for 3, 12 * 10 = 120, 120 + 3 = 123.
That should be pretty easy to code up :)
Maybe this equation would guide you.
Since this is a homework, let's stop at the suggestion that you expand this expression for some list, and try to extract a recurrent relationship:
x_0*10^n+x_1*10^(n-1)+...+x_n*10^0 = (((x_0*10+x_1)*10+x_2)...)*10+x_n
If you compare this to folds, you will see one fold matches this pattern for a particular function of two arguments.
This is my variant
import Data.List
decimal :: [Int] -> Int
decimal xs = foldl' (\sum (pos,x) -> (sum + x*(10^(l-pos)))) 0 $ zip [1..] xs where
l = length xs
*Main> decimal [1,4,3,1,9]
14319
In Haskell, you have really powerfull weapon - functions for lists processing. One of these functions is foldl (we use strict version of foldl, foldl') It's type
foldl :: (a -> b -> a) -> a -> [b] -> a
This functions takes thre arguments, an accumulating agrument, a list processed, and, the most interest,
the function that perform any operation with accumulator and list element and returns the result. Fold is really significant function so you should read detail manual about it.
But, there is a problem, we have three variables it our equation: list element processed (x), total list length (n) and position of processed element (k). But we can traverse to foldl only one element.
How can we traverse position of each element? Let's form tuples from Int where first element is a position, and second is a value. It is a standard trick, zip function helps us:
zip [1..] [1,4,3,4,6]
[(1,1),(2,4),(3,3),(4,4),(5,6)]
Than we pass our list of tuples into foldl function, and foldl call lambda function (\sum (pos,x) -> (sum + x*(10^(l-pos)))) for each element of list, summing result in sum

First column of a matrix given as a list of rows in Haskell

If I have a matrix given as a list of rows [[1,2,3],[4,5,6]], I want to return the first column, [1,4]. I'm an absolute beginner in Haskell and I have no idea on even how to deal with nested lists.
The following code will do the job:
map head [[1,2,3],[4,5,6]]
map is one of the most useful functions in haskell (and other functional programming languages). Given a list [a,b,c,d] and a function f, map f [a,b,c,d] will return the list [f a, f b, f c, f d]. The head function extracts the first element of a list. This is why
map head [[1,2,3],[4,5,6]] ->
[head [1,2,3], head [4,5,6]] ->
[1,4]
More generically:
col :: Int -> [[a]] -> [a]
col n = map (head . drop n)
Keep in mind that this will fail if n is greater than or equal to the length of any of the lists you give it.
The library function to convert a matrix of rows to a matrix of columns is Data.List.transpose. So one way to solve your problem is
import Data.List (transpose)
col = head . transpose
You could also write a function to get any column from the matrix:
colN n matrix = transpose matrix !! n
Disclaimers:
Remember that transpose is expensive if you need to transpose the whole matrix. For just the first column, it should be about the same cost as the other solutions people have given.
Also, transpose is relatively dangerous in complicated code because its result is the same type as its argument: [[a]] -> [[a]]. So it's easy to throw in the wrong number of transposes. (I learned this the hard way.)
The following code will do the job:
map head [[1,2,3],[4,5,6]]
To expand on Jonas' answer; map applies a function to each element of a list. The result of "mapping" a function over a list is a new list of a different type.
The input list you have here is of type [[Int]], that means, each element in the list is a list of Ints. So you want a function that takes each of the sublists and returns its first element; That is head.
To sum up, map will take the function head, apply it to each of the sublists so that you will get a new list of type [Int] containing just the head (first element) of each list.

Resources