Finding max list within a list - haskell

I was trying to get the list with the greatest sum within a list and then return that list. But when I call the function with
max_list [[1,2],[3,6],[10,34,5]]
it gives me the error:
Exception: a4.hs:65:1-64: Non-exhaustive patterns in function max_list
This is the code:
max_num :: [Int] -> Int
max_num [x] = x
max_num (x:xs) | (max_num xs) > x = maxVal xs
| otherwise = x
max_list :: [[Int]] -> [Int]
max_list [[a]] = head(filter (\x -> (sum_int x) == (max_num [[a]]) [[a]])
My logic is as follows:
I will
Sum the elements in the sublist
Compare that element to see if it equals the max-value of the list
Filter out the values that do not equal the max-value
Example call:
head (filter (\x -> (sum x) == 11) [[1,3],[4,7],[2,5]])
> [4,7]
So in that case I calculated the value 11 before hand and its sum of each element is [4, 11, 7] and it will give me the value whose sum is equal to the max value

There is a function in Data.List called maximumBy with the signature
maximumBy :: (a -> a -> Ordering) -> [a] -> a
and Data.Function has on with the signature
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
Applied with the compare function (compare :: Ord a => a -> a -> Ordering), we can see how this is exactly what you're looking for.
import Data.List (maximumBy)
import Data.Function (on)
{- for clarity:
compare :: Ord a => b -> b -> Ordering
(compare `on`) :: Ord b => (a -> b) -> a -> a -> Ordering
compare `on` sum :: (Num a, Ord a) => [a] -> [a] -> Ordering
-- well actually [a] is t a for a foldable t, but same diff -}
result = maximumBy (compare `on` sum) [[1,2],[3,6],[10,34,5]]
to implement this yourself, you could write a fold that compares each value according to its sum, recursing until the sum of x is greater than anything that comes before after it.
myMaximumBySum [] = [] -- degenerate case
myMaximumBySum [x] = x -- tautological case
myMaximumBySum (x:xs)
| sum x > sum (myMaximumBySum xs) = x
| otherwise = myMaximumBySum xs
-- or more naturally:
myMaximumBySum = foldr f []
where f x acc = if sum x > sum acc then x else acc

Related

How to check in a tuple if element matches?

I am trying to check whether my second part of my tuple is 1.0 and if it is then I am storing it in the list. But I can't figure out how to implement the check.
number :: [(Integer, Double)] -> [Integer]
number lst = number' lst []
where
number' [] a = a
((mat,1.0): xs) a = number'(xs) (mat:a) -- Here I am getting my error
((_,lst): xs) a = number'(xs) a
Maybe someone has an idea.
The reason this doesn't work is because you need to write number' for every line:
number :: [(Integer, Double)] -> [Integer]
number lst = number' lst []
where
number' [] a = a
number' ((mat,1.0): xs) a = number'(xs) (mat:a)
number' ((_,lst): xs) a = number'(xs) a
But this will return the "keys" in reverse.
You can pattern match with:
number :: (Eq a, Num a) => [(a, b)] -> [a]
number ((x, 1):xs) = x : number xs
number (_:xs) = number xs
number [] = []
You can however work with list comprehension:
number :: (Eq a, Num a) => [(a, b)] -> [a]
number xs = [ x | (x, 1) <- xs ]
or with a combination of map and filter:
number :: (Eq a, Num a) => [(a, b)] -> [a]
number = map fst . filter ((1 ==) . snd)

Haskell concat / filter according specific rules

According to following rules, I tried to solve the following problem:
No definition of recursion
No List of Comprehension
Only Prelude-Module is allowed.
Now I have to implement higher-order for concat and filter.
Im at this point:
concat' :: [[a]] -> [a]
concat' a = (concat a)
filter' :: (a -> Bool) -> [a] -> [a]
filter' p [] = []
filter' p (x:xs)
| p x = x : filter p xs
| otherwise = filter p xs
The concat function is working (nothing special so far) -> Is that a defined recursion? I mean I use the predefined concat from standard-prelude but myself I don't define it - or am I wrong?
For the filter, the function I've looked up the definition of standard prelude but that's either not working and it contains a definition of recursion.
I'm supposing the concat and filter functions should be avoided. Why would we need to implement concat and filter if they're already available? So try implementing them from scratch.
We can use folding instead of recursion and list comprehensions. The below solutions use the function foldr.
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
concat' :: [[a]] -> [a]
concat' = foldr (++) []
filter' :: (a -> Bool) -> [a] -> [a]
filter' p = foldr (\x acc -> if p x then x:acc else acc) []
Examples:
main = do
print $ concat' ["A", "B", "CAB"] -- "ABCAB"
print $ filter' (\x -> x `mod` 2 == 0) [1..9] -- [2, 4, 6, 8]
You may do as follows;
concat' :: Monad m => m (m b) -> m b
concat' = (id =<<)
filter' p = ((\x-> if p x then [x] else []) =<<)
=<< is just flipped version of the monadic bind operator >>=.
filter' (< 10) [1,2,3,10,11,12]
[1,2,3]

Haskell and comprehension lists

I'm writing a function that compares two vectors in haskell using comprehension lists. The thing is that I want to add booleans to my final list, but Haskell interprets this code as if x == y, add the element to the list (that's how comprehensive lists works I know). What I want is a list with booleans if the coordinates I'm comparing are true or false.
Is it possible to do this with comprehension lists?
igualdad :: Vector -> Vector -> [Bool]
igualdad v1 v2 = [ x == y | x <- xs, y <- ys]
where xs = vectorToFloatList v1
ys = vectorToFloatList v2
PD: I'm going to use foldr (&&) True with the list that returns igualdad, in order to get the final result that I want.
Thanks.
What I want is a list with booleans if the coordinates I'm comparing are True or False. Is it possible to do this with comprehension lists?
You get such a list. For two Vectors v and w with lengths m and n respectively, you will get a list with m×n elements, such that the item vi and wj will be compared in the result list in the element with index i×m + j.
If you hwever want a list of length min(m, n), such that the item at index i checks if vi and wi are the same, then we can make use of zip :: [a] -> [b] -> [(a, b)]:
igualdad :: Vector -> Vector -> [Bool]
igualdad v1 v2 = [ x == y | (x, y) <- zip (vectorToFloatList xs) (vectorToFloatList ys)]
or with zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] and on :: (b -> b -> c) -> (a -> b) -> a -> a -> c:
import Data.Function(on)
igualdad :: Vector -> Vector -> [Bool]
igualdad = on (zipWith (==)) vectorToFloatList
or we can make use of the ParallelListComp extension [ghc-doc] and run this with:
{-# LANGUAGE ParallelListComp #-}
igualdad :: Vector -> Vector -> [Bool]
igualdad v1 v2 = [ x == y | x <- vectorToFloatList xs | y <- vectorToFloatList ys]
PD: I'm going to use foldr (&&) True with the list that returns igualdad.
There exists a function for that already: that is and :: Foldable f => f Bool -> Bool. If you however want to check if all the items are the same, you can just use all :: Foldable f => (a -> Bool) -> f a -> Bool here:
import Data.Function(on)
sameVec :: Vector -> Vector -> Bool
sameVec = on (all (uncurry (==) .) . zip) vectorToFloatList

Product of 2 list haskell

I have 2 lists, x and y, I must calculate the product of
(xi^2 - yi^2 + 2*xi*yi) with xi from x
and yi from y
List x = [2,4,5,6,8] xi = 2/3/...
List y = [7,3,4,59,0] yi = 7/3/4...
It's a bit tricky because I can use only functions without the product function without recursion and list comprehension.
prod :: [Int] -> [Int] -> Int
I would write the product function myself:
product :: [Integer] -> Integer
product [] = 1
product i f = foldl (*) 1 [i..f]
But I don't know how to apply it to the both strings.
Well you can define a product yourself with foldl :: (b -> a -> b) -> b -> [a] -> [b] like:
ownProduct :: Num b => [b] -> b
ownProduct = foldl (*) 1
Because a foldl starts with the initial value (1) and applies that value to the first element of the list. The result of that operation is applied to the function again but now with the second element of that list and so on until we reach the end. So foldl (*) 1 [x1,x2,...,xn] is equal to (((1*x1)*x2)*...)*xn.
Furthermore you can use a zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] function to convert two streams (one of as and one of bs) into a stream of c by applying the function element-wise.
So you can implement it like:
twoListProduct :: Num b => [b] -> [b] -> b
twoListProduct x y = foldl (*) 1 $ zipWith helper x y
where helper xi yi = xi*xi - yi*yi + 2*xi*yi
Allow me to reuse the excelent answer of #WillemVanOnsem in a more step-by-step aproach:
First, you must join the two list somehow. zip :: [a] -> [b] -> [(a,b)] is a handy function for doing this, from two list it returns a list of pairs.
zip [2,4,5,6,8] [7,3,4,59,0]
> [(2,7),(4,3),(5,4),(6,59),(8,0)]
Now, you must do your work with the pairs. Lets define de function you must apply to a pair:
squareB :: (Integer,Integer) -> Integer
squareB (x,y) = x^2 - y^2 + 2*x*y
Lets use map for aplying the square of a binomial function to each pair:
multiplicands:: [Integer] -> [Integer] -> [Integer]
multiplicands xs1 xs2 = map squareB (zip xs1 xs2)
For example:
multiplicands [2,4,5,6,8] [7,3,4,59,0]
>[-17,31,49,-2737,64]
Now, lets fold them from the left using (*) with base case 1, ie: (((1 * x1) * x2) .... xn):
solution :: [Integer] -> [Integer] -> Integer
solution xs1 xs2 = foldl (*) 1 (multiplicands xs1 xs2)
Lets check this function:
solution [2,4,5,6,8] [7,3,4,59,0]
> 452336326
with Willems' function:
twoListProduct [2,4,5,6,8] [7,3,4,59,0]
> 4523363264
You may also do as follows;
quadratics :: Num a => Int -> [a] -> [a] -> a
quadratics i ns ms = ((\(f,s) -> f*f + 2*f*s - s*s) . head . drop i . zip ns) ms
*Main> quadratics 0 [2,4,5,6,8] [7,3,4,59,0]
-17
*Main> quadratics 3 [2,4,5,6,8] [7,3,4,59,0]
-2737

How to know in Haskell in what row and column of a table ([[a]]) you are

I want to make a sudoku solver in Haskell (as an exercise). My idea is:
I have t :: [[Int]] representing a 9x9 grid so that it contains 0 in an empty field and 1-9 in a solved field.
A function solve :: [[Int]] -> [[Int]] returns the solved sudoku.
Here is a rough sketch of it (i'd like to point out i'm a beginner, i know it is not the most optimal code):
solve :: [[Int]] -> [[Int]]
solve t
| null (filter (elem 0) t) = t
| t /= beSmart t = solve (beSmart t)
| otherwise = guess t
The function beSmart :: [[Int]] -> [[Int]] tries to solve it by applying some solving algorithms, but if methodical approach fails (beSmart returns the unchanged sudoku table in that case) it should try to guess some numbers (and i'll think of that function later). In order to fill in an empty field, i have to find it first. And here's the problem:
beSmart :: [[Int]] -> [[Int]]
beSmart t = map f t
where f row
| elem 0 row = map unsolvedRow row
| otherwise = row
where unsolvedRow a
| a == 0 = tryToDo t r c --?!?!?!?! skip
| otherwise = a
The function tryToDo :: [[Int]]] -> Int -> Int - > Int needs the row and column of the field i'm trying to change, but i have no idea how to get that information. How do i get from map what element of the list i am in at the moment? Or is there a better way to move around in the table? I come from iterative and procedural programing and i understand that perhaps my approach to the problem is wrong when it comes to functional programing.
I know this is not really an answer to your question, but I would argue, that usually you would want a different representation (one that keeps a more detailed view of what you know about the sudoku puzzle, in your attempted solution you can only distinguish a solved cell from a cell that is free to assume any value). Sudoku is a classical instance of CSP. Where modern approaches offer many fairly general smart propagation rules, such as unit propagation (blocking a digit in neighboring cells once used somewhere), but also many other, see AC-3 for further details. Other related topics include SAT/SMT and you might find the algorithm DPLL also interesting. In the heart of most solvers there usually is some kind of a search engine to deal with non-determinism (not every instance must have a single solution that is directly derivable from the initial configuration of the instance by application of inference rules). There are also techniques such as CDCL to direct the search.
To address the question in the title, to know where you are, its probably best if you abstract the traversal of your table so that each step has access to the coordinates, you can for example zip a list of rows with [0..] (zip [0..] rows) to number the rows, when you then map a function over the zipped lists, you will have access to pairs (index, row), the same applies to columns. Just a sketch of the idea:
mapTable :: (Int -> Int -> a -> b) -> [[a]] -> [[b]]
mapTable f rows = map (\(r, rs) -> mapRow (f r) rs) $ zip [0..] rows
mapRow :: (Int -> a -> b) -> [a] -> [b]
mapRow f cols = map (uncurry f) $ zip [0..] cols
or use fold to turn your table into something else (for example to search for a unit cell):
foldrTable :: (Int -> Int -> a -> b -> b) -> b -> [[a]] -> b
foldrTable f z rows = foldr (\(r, rs) b -> foldrRow (f r) b rs) z $ zip [0..] rows
foldrRow :: (Int -> a -> b -> b) -> b -> [a] -> b
foldrRow f z cols = foldr (uncurry f) z $ zip [0..] cols
to find which cell is unital:
foldrTable
(\x y v acc -> if length v == 1 then Just (x, y) else acc)
Nothing
[[[1..9],[1..9],[1..9]],[[1..9],[1..9],[1..9]],[[1..9],[1],[1..9]]]
by using Monoid you can refactor it:
import Data.Monoid
foldrTable' :: Monoid b => (Int -> Int -> a -> b) -> [[a]] -> b
foldrTable' f rows = foldrTable (\r c a b -> b <> f r c a) mempty rows
unit :: Int -> Int -> [a] -> Maybe (Int, Int)
unit x y c | length c == 1 = Just (x, y)
| otherwise = Nothing
firstUnit :: [[[a]]] -> Maybe (Int, Int)
firstUnit = getFirst . foldrTable' (\r c v -> First $ unit r c v)
so now you would do
firstUnit [[[1..9],[1..9],[1..9]],[[1,2],[3,4],[5]]]
to obtain
Just (1, 2)
correctly determining that the first unit cell is at position 1,2 in the table.
[[Int]] is a good type for a sodoku. But map does not give any info regarding the place it is in. This is one of the ideas behind map.
You could zip together the index with the value. But a better idea would be to pass the whole [[Int]] and the indexes to to the function. So its type would become:
f :: [[Int]] -> Int -> Int -> [[Int]]
inside the function you can now access the current element by
t !! x !! y
Already did this a while ago as a learning example. It is definitely not the nicest solution, but it worked for me.
import Data.List
import Data.Maybe
import Data.Char
sodoku="\
\-9-----1-\
\8-4-2-3-7\
\-6-9-7-2-\
\--5-3-1--\
\-7-5-1-3-\
\--3-9-8--\
\-2-8-5-6-\
\1-7-6-4-9\
\-3-----8-"
sodoku2="\
\----13---\
\7-5------\
\1----547-\
\--418----\
\951-67843\
\-2---4--1\
\-6235-9-7\
\--7-98--4\
\89----1-5"
data Position = Position (Int, Int) deriving (Show)
data Sodoku = Sodoku [Int]
insertAtN :: Int -> a -> [a] -> [a]
insertAtN n y xs = intercalate [y] . groups n $ xs
where
groups n xs = takeWhile (not.null) . unfoldr (Just . splitAt n) $ xs
instance Show Sodoku where
show (Sodoku s) = (insertAtN 9 '\n' $ map intToDigit s) ++ "\n"
convertDigit :: Char -> Int
convertDigit x = case x of
'-' -> 0
x -> if digit>=1 && digit<=9 then
digit
else
0
where digit=digitToInt x
convertSodoku :: String -> Sodoku
convertSodoku x = Sodoku $ map convertDigit x
adjacentFields :: Position -> [Position]
adjacentFields (Position (x,y)) =
[Position (i,y) | i<-[0..8]] ++
[Position (x,j) | j<-[0..8]] ++
[Position (u+i,v+j) | i<-[0..2], j<-[0..2]]
where
u=3*(x `div` 3)
v=3*(y `div` 3)
positionToField :: Position -> Int
positionToField (Position (x,y)) = x+y*9
fieldToPosition :: Int -> Position
fieldToPosition x = Position (x `mod` 9, x `div` 9)
getDigit :: Sodoku -> Position -> Int
getDigit (Sodoku x) pos = x !! (positionToField pos )
getAdjacentDigits :: Sodoku -> Position -> [Int]
getAdjacentDigits s p = nub digitList
where
digitList=filter (\x->x/=0) $ map (getDigit s) (adjacentFields p)
getFreePositions :: Sodoku -> [Position]
getFreePositions (Sodoku x) = map fieldToPosition $ elemIndices 0 x
isSolved :: Sodoku -> Bool
isSolved s = (length $ getFreePositions s)==0
isDeadEnd :: Sodoku -> Bool
isDeadEnd s = any (\x->x==0) $ map length $ map (getValidDigits s)$ getFreePositions s
setDigit :: Sodoku -> Position -> Int -> Sodoku
setDigit (Sodoku x) pos digit = Sodoku $ h ++ [digit] ++ t
where
field=positionToField pos
h=fst $ splitAt field x
t=tail$ snd $ splitAt field x
getValidDigits :: Sodoku -> Position -> [Int]
getValidDigits s p = [1..9] \\ (getAdjacentDigits s p)
-- Select numbers with few possible choices first to increase execution time
sortImpl :: (Position, [Int]) -> (Position, [Int]) -> Ordering
sortImpl (_, i1) (_, i2)
| length(i1)<length(i2) = LT
| length(i1)>length(i2) = GT
| length(i1)==length(i2) = EQ
selectMoves :: Sodoku -> Maybe (Position, [Int])
selectMoves s
| length(posDigitList)>0 = Just (head posDigitList)
| otherwise = Nothing
where
posDigitList=sortBy sortImpl $ zip freePos validDigits
validDigits=map (getValidDigits s) freePos
freePos=getFreePositions s
createMoves :: Sodoku -> [Sodoku]
createMoves s=
case selectMoves s of
Nothing -> []
(Just (pos, digits)) -> [setDigit s pos d|d<-digits]
solveStep :: Sodoku -> [Sodoku]
solveStep s
| (isSolved s) = [s]
| (isDeadEnd s )==True = []
| otherwise = createMoves s
solve :: Sodoku -> [Sodoku]
solve s
| (isSolved s) = [s]
| (isDeadEnd s)==True = []
| otherwise=concat $ map solve (solveStep s)
s=convertSodoku sodoku2
readSodoku :: String -> Sodoku
readSodoku x = Sodoku []

Resources