How do you find nth elements in the matrix at a given row and column position? For example, if you have
type Matrice a = [[a]]
example :: Matrice Int
example = [ [3, 5],
[2, 1],
[0, 4],
[6, 8] ]
Prelude > example 0 1
5
Prelude > example 2 0
0
Prelude > example 1 1
2
I know how to work out with only given list such as
nth :: Int -> [a] -> Maybe a
nth _ [] = Nothing
nth 1 (x : _) = Just x
nth n (_ : xs) = nth (n - 1) xs
But my question is, how do you access nth element in a matrix as in the given example
Just handle each list individually, and !! will work:
Prelude> example
[[3,5],[2,1],[0,4],[6,8]]
Prelude> :t example
example :: Matrice Int
Prelude> example !! 0 !! 1
5
But lists are probably not the right data structure for this, because indexing is O(n). Depending on your task, Data.Vector or Data.Array may be better suited. See also Haskell: Lists, Arrays, Vectors, Sequences.
!! can be used for accessing an element by index, but be careful, since it's raising an exception, if the index is too large.
example !! 2 !! 0
And you've already written a function for accessing nth element of a list, just apply it twice:
nth :: Int -> Int -> [[a]] -> Maybe a
nth k n matrix = nth' n =<< nth' k matrix
where
nth' _ [] = Nothing
nth' 0 (x: _) = Just x
nth' n (_ : xs) = nth' (n - 1) xs
Or using your created Matrice type:
nth :: Matrice a -> Int -> Int -> Maybe a
nth matrix k n = nth' n =<< nth' k matrix
where
nth' _ [] = Nothing
nth' 0 (x: _) = Just x
nth' n (_ : xs) = nth' (n - 1) xs
Related
I want to split a list into groups with n elements. For example:
n = 2
[1, 2, 3, 4, 5, 6] ->[[1, 2], [3, 4], [5,6]]
n = 3
[1, 2, 3, 4, 5, 6] -> [[1, 2, 3] [4, 5, 6]]
I tried to implement a function, which returns n if n is 0 or greater than the length of the list and the fitted list if n is less than the length of the list.
split :: Int -> [a] -> Either Int [[a]]
split n [a]
|n <= lenght [a] = Right n (take n [a]) : (split n (drop n [a]))
|n == 0 = Left n
|otherwise = Left n
However, I get a "variable not in scope" error. I've already tried around, but I'm stuck.
Did I make a mistake with the data types?
You have a typo with lenght vs. length, but if we change that there are still errors.
If we look at Right n (take n [a]) we can see that Right and Left only accept a single argument.
Your pattern split n [a] also only matches a list with a single element.
Let's break this down into smaller pieces. Creating a function that splits a list is straightforward.
split' n [] = []
split' n lst = take n lst : (split' n $ drop n lst)
Prelude> split' 3 [1,2,3,4,5,6]
[[1,2,3],[4,5,6]]
Now it's straightforward to make this local to split to incorporate the checks you specified and return the desired Either type.
split :: Int -> [a] -> Either Int [[a]]
split n [] = Left n
split n lst
| n == 0 || n > length lst = Left n
| otherwise = Right lst'
where
split' n [] = []
split' n lst = take n lst : (split' n $ drop n lst)
lst' = split' n lst
I am learning Haskell and am currently creating a program that finds all common divisors from 3 different Int:s.
I have a working program but the evaluation time is very long on big numbers. I want advice on how to optimize it.
EXAMPLE: combineDivisors 234944 246744 144456 == [1,2,4,8]
As said I am very new to this so any help is appreciated.
import Data.List
combineDivisors :: Int -> Int -> Int -> [Int]
combineDivisors n1 n2 n3 =
mergeSort list
where list = getTrips concList
concList = isDivisor n1 ++ isDivisor n2 ++ isDivisor n3
isDivisor n = [x | x <- [1..n], mod n x == 0]
getTriplets :: Ord a => [a] -> [a]
getTriplets = map head . filter (\l -> length l > 2) . group . sort
--Merge sort--
split :: [a] -> ([a],[a])
split xs =
let
l = length xs `div` 2
in
(take l xs, drop l xs)
merge :: [Int] -> [Int] -> [Int]
merge [] ys = ys
merge xs [] = xs
merge (x:xs) (y:ys)
| y < x = y : merge (x:xs) ys
| otherwise = x : merge xs (y:ys)
mergeSort :: [Int] -> [Int]
mergeSort [] = []
mergeSort [x] = [x]
mergeSort xs =
let
(xs1,xs2) = split xs
in
merge (mergeSort xs1) (mergeSort xs2)
If you don't care too much about memory usage, you can just use Data.IntSet and a function to find all factors given a number to do this.
First, let's make a function that returns an IntSet of all factors of a number-
import qualified Data.IntSet as IntSet
factors :: Int -> IntSet.IntSet
factors n = IntSet.fromList . f $ 1 -- Convert the list of factors into a set
where
-- Actual function that returns the list of factors
f :: Int -> [Int]
f i
-- Exit when i has surpassed square root of n
| i * i > n = []
| otherwise = if n `mod` i == 0
-- n is divisible by i - add i and n / i to the list
then i : n `div` i : f (i + 1)
-- n is not divisible by i - continue to the next
else f (i + 1)
Now, once you have the IntSet corresponding to each number, you just have to do a intersection on them to get the result
commonFactors :: Int -> Int -> Int -> [Int]
commonFactors n1 n2 n3 = IntSet.toList $ IntSet.intersection (factors n3) $ IntSet.intersection (factors n1) $ factors n2
That works but is a bit ugly. How about making an intersections function that can take multiple IntSets and produce a final intersection result.
intersections :: [IntSet.IntSet] -> IntSet.IntSet
intersections [] = IntSet.empty
intersections (t:ts) = foldl IntSet.intersection t ts
That should fold on a list of IntSets to find the final intersection
Now you can refactor commonFactors to-
commonFactors :: Int -> Int -> Int -> [Int]
commonFactors n1 n2 n3 = IntSet.toList . intersections $ [factors n1, factors n2, factors n3]
Better? I'd think so. How about one last improvement, a general commonFactors function for n amount of ints
commonFactors :: [Int] -> [Int]
commonFactors = IntSet.toList . intersections . map factors
Note that this is using an IntSet, so it is naturally limited to Ints. If you want to use Integer instead - just replace IntSet with a regular Set Integer
Output
> commonFactors [234944, 246744, 144456]
[1,2,4,8]
You should use the standard algorithm where you prime factorize their GCD:
import Data.List
import qualified Data.Map.Strict as M
-- infinite list of primes
primes :: [Integer]
primes = 2:3:filter
(\n -> not $ any
(\p -> n `mod` p == 0)
(takeWhile (\p -> p * p <= n) primes))
[5,7..]
-- prime factorizing a number
primeFactorize :: Integer -> [Integer]
primeFactorize n
| n <= 1 = []
-- we search up to the square root to find a prime factor
-- if we find one then add it to the list, divide and recurse
| Just p <- find
(\p -> n `mod` p == 0)
(takeWhile (\p -> p * p <= n) primes) = p:primeFactorize (n `div` p)
-- if we don't then the number has to be prime so we're done
| otherwise = [n]
-- count the number of each element in a list
-- e.g.
-- getCounts [1, 2, 2, 3, 4] == fromList [(1, 1), (2, 2), (3, 1), (4, 1)]
getCounts :: (Ord a) => [a] -> M.Map a Int
getCounts [] = M.empty
getCounts (x:xs) = M.insertWith (const (+1)) x 1 m
where m = getCounts xs
-- get all possible combinations from a map of counts
-- e.g. getCombos (M.fromList [('a', 2), ('b', 1), ('c', 2)])
-- == ["","c","cc","b","bc","bcc","a","ac","acc","ab","abc","abcc","aa","aac","aacc","aab","aabc","aabcc"]
getCombos :: M.Map a Int -> [[a]]
getCombos m = allFactors
where
list = M.toList m
factors = fst <$> list
counts = snd <$> list
possible = (\n -> [0..n]) <$> counts
allCounts = sequence possible
allFactors = (\count -> concat $ zipWith replicate count factors) <$> allCounts
-- get the common factors of a list of numbers
commonFactorsList :: [Integer] -> [Integer]
commonFactorsList [] = []
commonFactorsList l = sort factors
where
totalGcd = foldl1 gcd l
-- then get the combinations them and take their products to get the factor
factors = map product . getCombos . getCounts . primeFactorize $ totalGcd
-- helper function for 3 numbers
commonFactors3 :: Integer -> Integer -> Integer -> [Integer]
commonFactors3 a b c = commonFactorsList [a, b, c]
I am trying to count the number of non-empty lists in a list of lists with recursive code.
My goal is to write something simple like:
prod :: Num a => [a] -> a
prod [] = 1
prod (x:xs) = x * prod xs
I already have the deifniton and an idea for the edge condition:
nonEmptyCount :: [[a]] -> Int
nonEmptyCount [[]] = 0
I have no idea how to continue, any tips?
I think your base case, can be simplified. As a base-case, we can take the empty list [], not a singleton list with an empty list. For the recursive case, we can consider (x:xs). Here we will need to make a distinction between x being an empty list, and x being a non-empty list. We can do that with pattern matching, or with guards:
nonEmptyCount :: [[a]] -> Int
nonEmptyCount [] = 0
nonEmptyCount (x:xs) = -- …
That being said, you do not need recursion at all. You can first filter your list, to omit empty lists, and then call length on that list:
nonEmptyCount :: [[a]] -> Int
nonEmptyCount = length . filter (…)
here you still need to fill in ….
Old fashion pattern matching should be:
import Data.List
nonEmptyCount :: [[a]] -> Int
nonEmptyCount [] = 0
nonEmptyCount (x:xs) = if null x then 1 + (nonEmptyCount xs) else nonEmptyCount xs
The following was posted in a comment, now deleted:
countNE = sum<$>(1<$)<<<(>>=(1`take`))
This most certainly will look intimidating to the non-initiated, but actually, it is equivalent to
= sum <$> (1 <$) <<< (>>= (1 `take`))
= sum <$> (1 <$) . (take 1 =<<)
= sum . fmap (const 1) . concatMap (take 1)
= sum . map (const 1) . concat . map (take 1)
which is further equivalent to
countNE xs = sum . map (const 1) . concat $ map (take 1) xs
= sum . map (const 1) $ concat [take 1 x | x <- xs]
= sum . map (const 1) $ [ r | x <- xs, r <- take 1 x]
= sum $ [const 1 r | (y:t) <- xs, r <- take 1 (y:t)] -- sneakiness!
= sum [const 1 r | (y:_) <- xs, r <- [y]]
= sum [const 1 y | (y:_) <- xs]
= sum [ 1 | (_:_) <- xs] -- replace each
-- non-empty list
-- in
-- xs
-- with 1, and
-- sum all the 1s up!
= (length . (take 1 =<<)) xs
= (length . filter (not . null)) xs
which should be much clearer, even if in a bit sneaky way. It isn't recursive in itself, yes, but both sum and the list-comprehension would be implemented recursively by a given Haskell implementation.
This reimplements length as sum . (1 <$), and filter p xs as [x | x <- xs, p x], and uses the equivalence not (null xs) === (length xs) >= 1.
See? Haskell is fun. Even if it doesn't yet feel like it, but it will be. :)
I have list of lists of Int and I need to add an Int value to the last list from the list of lists. How can I do this? My attempt is below
f :: [[Int]] -> [Int] -> Int -> Int -> Int -> [[Int]]
f xs [] cur done total = [[]]
f xs xs2 cur done total = do
if total >= length xs2 then
xs
else
if done == fib cur then
f (xs ++ [[]]) xs2 (cur + 1) 0 total
else
f ((last xs) ++ [[xs2!!total]]) xs2 cur (done + 1) (total + 1)
The problem is:
We have a list A of Int
And we need to slpit it on N lists B_1 ,..., B_n , length of B_i is i-th Fibonacci number.
If we have list [1 , 2 , 3 , 4 , 5 , 6 , 7] (xs2 in my code)
The result should be [[1] , [2] , [3 , 4] , [5 , 6 , 7]]
The easy way to deal with problems like this is to separate the problem into sub-problems. In this case, you want to change the last item in a list. The way you want to change it is by adding an item to it.
First let's tackle changing the last item of a list. We'll do this by applying a function to the last item, but not to any other items.
onLast :: [a] -> (a -> a) -> [a]
onLast xs f = go xs
where
go [] = []
go [x] = [f x]
go (x:xs) = x:go xs
You want to change the last item in the list by adding an additional value, which you can do with (++ [value]).
Combining the two with the value you want to add (xs2!!total) we get
(onLast xs (++ [xs2!!total]))
f :: [[Int]] -> Int -> [[Int]]
f [] _ = []
f xs i = (take n xs) ++ [[x + i | x <- last xs]]
where n = (length xs) - 1
last = head . (drop n)
For example,
*Main> f [[1, 2, 3], [], [4, 5, 6]] 5
[[1,2,3],[],[9,10,11]]
*Main> f [[1, 2, 3]] 5
[[6,7,8]]
*Main> f [] 3
You approach uses a do block, this is kind of weird since do blocks are usually used for monads. Furthermore it is rather unclear what cur, done and total are doing. Furthermore you use (!!) :: [a] -> Int -> a and length :: [a] -> Int. The problem with these functions is that these run in O(n), so it makes the code inefficient as well.
Based on changed specifications, you want to split the list in buckets with length the Fibonacci numbers. In that case the signature should be:
f :: [a] -> [[a]]
because as input you give a list of numbers, and as output, you return a list of numbers. We can then implement that as:
f :: [a] -> [[a]]
f = g 0 1
where g _ _ [] = []
g a b xs = xa : g b (a+b) xb
where (xa,xb) = splitAt b xs
This generates:
*Main> f [1,2,3,4,5,6]
[[1],[2],[3,4],[5,6]]
*Main> f [1,2,3,4,5,6,7]
[[1],[2],[3,4],[5,6,7]]
*Main> f [1,2,3,4,5,6,7,8]
[[1],[2],[3,4],[5,6,7],[8]]
*Main> f [1,2,3,4,5,6,7,8,9]
[[1],[2],[3,4],[5,6,7],[8,9]]
The code works as follows: we state that f = g 0 1 so we pass the arguments of f to g, but g also gets an 0 and a 1 (the first Fibonacci numbers).
Each iteration g checks whether we reached the end of the list. If so, we return an empty list as well. Otherwise we determine the last Fibonacci number that far (b), and use a splitAt to obtain the first b elements of the list we process, as well as the remainder. We then emit the first part as head of the list, and for the tail we calculate the next Fibonacci number and pass that to g with the tail of splitAt.
I would like to implement a function that takes as input a size n and a list. This function will cut the list into two lists, one of size n and the rest in another list. I am new to this language and have a hard time learning the syntax.
The main problem I have is that is finding a way to express a size of the list without using any loops or mutable variables.
Can anyone give a me some pointers?
Let's start with the function's type signature. Since it gets n and a list as arguments and returns a pair of lists, you have a function split:
val split : int -> 'a list -> 'a list * 'a list
Here is one approach to implement this function:
let split n xs =
let rec splitUtil n xs acc =
match xs with
| [] -> List.rev acc, []
| _ when n = 0 -> List.rev acc, xs
| x::xs' -> splitUtil (n-1) xs' (x::acc)
splitUtil n xs []
The idea is using an accumulator acc to hold elements you have traversed and decreasing n a long the way. Because elements are prepended to acc, in the end you have to reverse it to get the correct order.
The function has two base cases to terminate:
There's no element left to traverse (xs = [] at that point).
You have gone through the first n elements of the list (n decreases to 0 at that time).
Here is a short illustration of how split computes the result:
split 2 [1; 2; 3] // call the auxiliary function splitUtil
~> splitUtil 2 [1; 2; 3] [] // match the 3rd case of x::xs'
~> splitUtil 1 [2; 3] [1] // match the 3rd case of x::xs'
~> splitUtil 0 [3] [2; 1] // match the 2nd case of n = 0 (base case)
~> List.rev [2; 1], [3] // call List.rev on acc
~> [1; 2], [3]
let split n list =
let rec not_a_loop xs = function
| (0, ys) | (_, ([] as ys)) -> (List.rev xs), ys
| (n, x::ys) -> not_a_loop (x::xs) (n-1, ys)
not_a_loop [] (n, list)
New solution - splitAt is now built into List and Array. See commit around 2014 on github. I noticed this today while using F# in VS.2015
Now you can simply do this...
let splitList n list =
List.splitAt n list
And as you might expect the signature is...
n: int -> list: 'a list -> 'a list * 'a list
Example usage:
let (firstThree, remainder) = [1;2;3;4;5] |> (splitList 3)
printfn "firstThree %A" firstThree
printfn "remainder %A" remainder
Output:
firstThree [1; 2; 3]
remainder [4; 5]
Github for those interested: https://github.com/dsyme/visualfsharp/commit/1fc647986f79d20f58978b3980e2da5a1e9b8a7d
One more way, using fold:
let biApply f (a, b) = (f a, f b)
let splitAt n list =
let splitter ((xs, ys), n') c =
if n' < n then
((c :: xs, ys), n' + 1)
else
((xs, c :: ys), n' + 1)
List.fold splitter (([], []), 0) list
|> fst
|> biApply List.rev
Here is a great series on folds than you can follow to learn more on the topic.