function that returns a list [0,[x1],[x1,x2],[x1,x2,x3]...] where [x1,x2,x3....] is the original list - haskell

How can I make in Haskell a function that gets a list and return a list of lists in this way:
[x1,x2,x3,x4,x5....]
it should return :
[[0],[x1],[x1,x2],[x1,x2,x3],[x1,x2,x3,x4][x1,x2,x3,x4,x5]....]
without using ready function that do it in Haskell.

I assume you mean the empty list [] at the start, not [0].
In which case, it's just inits.
Here's it's definition if you want to write it yourself:
inits xs = [] : case xs of [] -> []
x : xs' -> map (x :) (inits xs')

Assuming you want the empty list at the start:
prefixes :: [a] -> [[a]]
prefixes ls = map (\x -> take x ls) [0..(length ls)]

Code:
import System.IO
transform :: [Int] -> [[Int]]
transform list = trans 0
where trans n = case (length list) >= n of
True -> (take n list):( trans (n+1) )
False -> []
main = do
print . show $ transform [1..7]
Output:
$> ./transform
"[[],[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5],[1,2,3,4,5,6],[1,2,3,4,5,6,7]]"
Edit: To work with Infinite Lists
transform :: [a] -> [[a]]
transform list = trans 0 []
where
trans :: a -> [a] -> [[a]]
trans n last = case last == list of
False -> [take n list]++(trans (n+1) $ take n list)
True -> []

Related

How can I find the list with maximum length using recursion?

I am trying to use a recursive function that prints the list that has the maximum length out of the lists resulting from my following code:
allincreasing :: Ord a => [a] -> [[a]]
allincreasing = map nub . filter isSorted . subsequences
main = do
print $ allincreasing[3,2,6,4,5,1]
I need to pass the output below to a recursive function that find the one with max length :
[[],[3],[2],[6],[3,6],[2,6],[4],[3,4],[2,4],[5],[3,5],[2,5],[4,5],[3,4,5],[2,4,5],[1]]
I tried to do it using the following code based on my understanding of an answer to this question but I couldn't implement the recursion part well. Here is my attempt:
longest :: Ord a => [[a]] -> [a]
longest [y] = y --base case: if there's only one element left, return it.
longest (x:y:lst) --extract the first two elements x, y from the list.
| length x < length y = longest (y:lst)
| otherwise = x : (longest (y:lst))
lis :: Ord a => [a] -> a
lis = length . longest . allincreasing
Note: I am required to use recursion to solve the problem of longest increasing sequence.
When you want to track stuf alongsiede recursion (like the max list so far...) one use accumulators (you could read about them here...):
Edited due to comment request:
module Main where
import Data.List
isSorted :: (Ord a) => [a] -> Bool
isSorted [] = True
isSorted [x] = True
isSorted (x:y:xs) = x <= y && isSorted (y:xs)
allincreasing :: Ord a => [a] -> [[a]]
allincreasing = map nub . filter isSorted . subsequences
main :: IO ()
main = do
let list = [3,2,6,4,5,1]
print $ allincreasing list
print $ longest $ allincreasing list
longest :: Ord a => [[a]] -> [a]
longest list = longest' list []
where
longest' [] acc = acc
longest' (x:xs) [] = longest' xs x
longest' (x:xs) acc
| length acc >= length x = longest' xs acc
| length acc < length x = longest' xs x
longest' _ _ = error "something went wrong..."

How to remove second largest element in a list in haskell?

I have created a program to remove first smallest element but I dont how to do for second largest:
withoutBiggest (x:xs) =
withoutBiggestImpl (biggest x xs) [] (x:xs)
where
biggest :: (Ord a) => a -> [a] -> a
biggest big [] = big
biggest big (x:xs) =
if x < big then
biggest x xs
else
biggest big xs
withoutBiggestImpl :: (Eq a) => a -> [a] -> [a] -> [a]
withoutBiggestImpl big before (x:xs) =
if big == x then
before ++ xs
else
withoutBiggestImpl big (before ++ [x]) xs
Here is a simple solution.
Prelude> let list = [10,20,100,50,40,80]
Prelude> let secondLargest = maximum $ filter (/= (maximum list)) list
Prelude> let result = filter (/= secondLargest) list
Prelude> result
[10,20,100,50,40]
Prelude>
A possibility, surely not the best one.
import Data.Permute (rank)
x = [4,2,3]
ranks = rank (length x) x -- this gives [2,0,1]; that means 3 (index 1) is the second smallest
Then:
[x !! i | i <- [0 .. length x -1], i /= 1]
Hmm.. not very cool, let me some time to think to something better please and I'll edit my post.
EDIT
Moreover my previous solution was wrong. This one should be correct, but again not the best one:
import Data.Permute (rank, elems, inverse)
ranks = elems $ rank (length x) x
iranks = elems $ inverse $ rank (length x) x
>>> [x !! (iranks !! i) | i <- filter (/=1) ranks]
[4,2]
An advantage is that this preserves the order of the list, I think.
Here is a solution that removes the n smallest elements from your list:
import Data.List
deleteN :: Int -> [a] -> [a]
deleteN _ [] = []
deleteN i (a:as)
| i == 0 = as
| otherwise = a : deleteN (i-1) as
ntails :: Int -> [a] -> [(a, Int)] -> [a]
ntails 0 l _ = l
ntails n l s = ntails (n-1) (deleteN (snd $ head s) l) (tail s)
removeNSmallest :: Ord a => Int -> [a] -> [a]
removeNSmallest n l = ntails n l $ sort $ zip l [0..]
EDIT:
If you just want to remove the 2nd smallest element:
deleteN :: Int -> [a] -> [a]
deleteN _ [] = []
deleteN i (a:as)
| i == 0 = as
| otherwise = a : deleteN (i-1) as
remove2 :: [a] -> [(a, Int)] -> [a]
remove2 [] _ = []
remove2 [a] _ = []
remove2 l s = deleteN (snd $ head $ tail s) l
remove2Smallest :: Ord a => [a] -> [a]
remove2Smallest l = remove2 l $ sort $ zip l [0..]
It was not clear if the OP is looking for the biggest (as the name withoutBiggest implies) or what. In this case, one solution is to combine the filter :: (a->Bool) -> [a] -> [a] and maximum :: Ord a => [a] -> a functions from the Prelude.
withoutBiggest l = filter (/= maximum l) l
You can remove the biggest elements by first finding it and then filtering it:
withoutBiggest :: Ord a => [a] -> [a]
withoutBiggest [] = []
withoutBiggest xs = filter (/= maximum xs) xs
You can then remove the second-biggest element in much the same way:
withoutSecondBiggest :: Ord a => [a] -> [a]
withoutSecondBiggest xs =
case withoutBiggest xs of
[] -> xs
rest -> filter (/= maximum rest) xs
Assumptions made:
You want each occurrence of the second-biggest element removed.
When there is zero/one element in the list, there isn't a second element, so there isn't a second-biggest element. Having the list without an element that isn't there is equivalent to having the list.
When the list contains only values equivalent to maximum xs, there also isn't a second-biggest element even though there may be two or more elements in total.
The Ord type-class instance implies a total ordering. Otherwise you may have multiple maxima that are not equivalent; otherwise which one is picked as the biggest and second-biggest is not well-defined.

How to extract the same elements from two lists in Haskell?

here's my question:
How to extract the same elements from two equal length lists to another list?
For example: given two lists [2,4,6,3,2,1,3,5] and [7,3,3,2,8,8,9,1] the answer should be [1,2,3,3]. Note that the order is immaterial. I'm actually using the length of the return list.
I tried this:
sameElem as bs = length (nub (intersect as bs))
but the problem is nub removes all the duplications. The result of using my function to the former example is 3 the length of [1,3,2] instead of 4 the length of [1,3,3,2]. Is there a solution? Thank you.
Since the position seems to be irrelevant, you can simply sort the lists beforehand and then traverse both lists:
import Data.List (sort)
intersectSorted :: Ord a => [a] -> [a] -> [a]
intersectSorted (x:xs) (y:ys)
| x == y = x : intersectSorted xs ys
| x < y = intersectSorted xs (y:ys)
| x > y = intersectSorted (x:xs) ys
intersectSorted _ _ = []
intersect :: Ord a => [a] -> [a] -> [a]
intersect xs ys = intersectSorted (sort xs) (sort ys)
Note that it's also possible to achieve this with a Map:
import Data.Map.Strict (fromListWith, assocs, intersectionWith, Map)
type Counter a = Map a Int
toCounter :: Ord a => [a] -> Counter a
toCounter = fromListWith (+) . flip zip (repeat 1)
intersectCounter :: Ord a => Counter a -> Counter a -> Counter a
intersectCounter = intersectionWith min
toList :: Counter a -> [a]
toList = concatMap (\(k,c) -> replicate c k) . assocs
intersect :: Ord a => [a] -> [a] -> [a]
intersect xs ys = toList $ intersectCounter (toCounter xs) (toCounter ys)
You could write a function for this. There is probably a more elegant version of this involving lambda's or folds, but this does work for your example:
import Data.List
same (x:xs) ys = if x `elem` ys
then x:same xs (delete x ys)
else same xs ys
same [] _ = []
same _ [] = []
The delete x ys in the then-clause is important, without that delete command items from the first list that occur at least once will be counted every time they're encountered.
Note that the output is not sorted, since you were only interested in the length of the resulting list.
import Data.List (delete)
mutuals :: Eq a => [a] -> [a] -> [a]
mutuals [] _ = []
mutuals (x : xs) ys | x `elem` ys = x : mutuals xs (delete x ys)
| otherwise = mutuals xs ys
gives
mutuals [2,4,6,3,2,1,3,5] [7,3,3,2,8,8,9,1] == [2,3,1,3]

Haskell search an element on a List

I want a function that changes (1 to 0) on a list of lists, when number of 1's in that line/column isn't even. I have done these functions:
1) Sees if the lines in a list are even or not:
parityLine :: [[Int]] -> [Bool]
parityLine [] =[]
parityLine (x:xs)
|sum(x) `mod` 2 == 0 = True:(parityLine(xs))
|otherwise = False:(parityLine(xs))
2) Sum the corresponding elements on a list of lists:
sumPositions :: [[Int]] -> [Int]
sumPositions [] = []
sumPositions (x:xs) = foldl (zipWith (+)) (repeat 0) (x:xs)
3) Sees if the columns in a list are even or not:
parityColumn :: [Int] -> [Bool]
parityColumn [] = []
parityColumn (x:xs)
|head(x:xs) `mod` 2 == 0 = True:parityColumn(xs)
|otherwise = False:parityColumn(xs)
4) Does the operation or with two boolean lists:
bol :: [Bool] -> [Bool] -> [[Bool]]
bol [] _ = []
bol (x:xs) (y:ys)= (map (||x) (y:ys)):(bol xs (y:ys))
5) Correct List:
correct :: [[Int]] -> [[Bool]]
correct [] = []
correct (x:xs)=(bol(parityLine (x:xs))(parityColumn(sumPositions(x:xs))))
So what I want is to alter the function correct to [[Int]]->[[Int]] that does this:
My Int list(x:xs) With my correct function applied
[[0,0,1,1], [[True,True,True,True],
[1,0,1,1], [True,True,False,True],
[0,1,0,1], [True,True,True,True]
[1,1,1,1]] [True,True,True,True]]
Now I can see that in the second line third column, False, so I have to correct that number 1 to have a number of 1's even. If there is more than one False in that list, I only want to correct one of these 1's.
As a result, I want that function correct returns:
[[0,0,1,1],
[1,0,0,1],
[0,1,0,1],
[1,1,1,1]]
Thanks.
I'll give an answer that starts where you are rather than from scratch, so we're doing it more your way than mine.
First let's do it for a single element:
leaveIf :: Bool -> Int -> Int
leaveIf yes 0 = if yes then 0 else 1
leaveIf yes 1 = if yes then 1 else 0
(You could use guards for that, but my phone doesn't have the vertical bar character!)
Next we can do it for a list of lists:
edit :: [[Bool]] -> [[Int]] -> [[Int]]
edit boolss intss = zipWith (zipWith leaveIf) boolss intss
EDIT: You'd like to only change one, so we'll need a way of making subsequent Falses into Trues:
makeTrue :: [Bool] -> [Bool]
makeTrue xs = map (const True) xs
I've used the function const :: a -> b -> a. For example, const 5 'c' is just 5. I could shorten that definition to makeTrue = map (const True). Once you get used to thinking that way, you'll find the shorter version clearer.
oneFalse :: [[Bool]] -> [[Bool]]
oneFalse [] = []
oneFalse (xs:xss) = let (trues,falses) = break (==False) xs in
case falses of
[] -> trues:oneFalse xss
(False:others) -> (trues ++ False : makeTrue others) : map makeTrue xss
(==False) could be written more simply as not, but less clearly perhaps.
so for example
> oneFalse [[True,True,True,True],[True,False,True,False],[True,False,False,True]]
[[True,True,True,True],[True,False,True,True],[True,True,True,True]]
So now we can have
editOne :: [[Bool]] -> [[Int]] -> [[Int]]
editOne boolss intss = zipWith (zipWith leaveIf) (oneFalse boolss) intss
AndrewC already gave an solution which changed all 1s corresponding to Falses. If we only want to correct the first one, we have to find a replacement for zipWith:
leaveIf ok x = if ok then x else 1 -x
-- Varianto of zipWith, which changes at most one element of the list
modFirst :: Eq b => (a -> b -> b) -> [a] -> [b] -> [b]
modFirst _ [] _ = []
modFirst _ _ [] = []
modFirst f (x:xs) (y:ys) = z : if y == z then modFirst f xs ys else ys
where z = f x y
edit :: [[Bool]] -> [[Int]] -> [[Int]]
edit boolss intss = modFirst (modFirst leaveIf) boolss intss
correct' :: [[Int]] -> [[Int]]
correct' xss = edit (correct' xss) xss
The result is the not necessarily a list of lists where all lines/rows contain an even number of 1's:
correct' [[0,1,0],[1,1,1],[0,1,0]] = [[1,1,0],[1,1,1],[0,1,0]
You need to iterate it a few times, until all errors are fixed (i.e., compute a fixpoint).
I'd like to add that your original program can be simplified quite a bit (without changing your algorithm):
parityLine :: [[Int]] -> [Bool]
parityLine = map (even . sum)
parityColumn :: [Int] -> [Bool]
parityColumn = map even
sumPositions :: [[Int]] -> [Int]
sumPositions = foldl (zipWith (+)) (repeat 0)
bol :: [Bool] -> [Bool] -> [[Bool]]
bol xs ys = map (\x -> map (||x) ys) xs
correct :: [[Int]] -> [[Bool]]
correct xs = bol (parityLine xs) (parityColumn $ sumPositions xs)

Remove every nth element from string

How can you remove every nth element of a string?
I'm guessing you would use the drop function in some kind of way.
Like this drops the first n, how can you change this so only drops the nth, and then the nth after that, and so on, rather than all?
dropthem n xs = drop n xs
Simple. Take (n-1) elements, then skip 1, rinse and repeat.
dropEvery _ [] = []
dropEvery n xs = take (n-1) xs ++ dropEvery n (drop n xs)
Or in showS style for efficiency's sake
dropEvery n xs = dropEvery' n xs $ []
where dropEvery' n [] = id
dropEvery' n xs = (take (n-1) xs ++) . dropEvery n (drop n xs)
-- groups is a pretty useful function on its own!
groups :: Int -> [a] -> [[a]]
groups n = map (take n) . takeWhile (not . null) . iterate (drop n)
removeEveryNth :: Int -> [a] -> [a]
removeEveryNth n = concatMap (take (n-1)) . groups n
remove_every_nth :: Int -> [a] -> [a]
remove_every_nth n = foldr step [] . zip [1..]
where step (i,x) acc = if (i `mod` n) == 0 then acc else x:acc
Here's what the function does:
zip [1..] is used to index all items in the list, so e.g. zip [1..] "foo" becomes [(1,'f'), (2,'o'), (3,'o')].
The indexed list is then processed with a right fold which accumulates every element whose index is not divisible by n.
Here's a slightly longer version that does essentially the same thing, but avoids the extra memory allocations from zip [1..] and doesn't need to calculate modulus.
remove_every_nth :: Int -> [a] -> [a]
remove_every_nth = recur 1
where recur _ _ [] = []
recur i n (x:xs) = if i == n
then recur 1 n xs
else x:recur (i+1) n xs
Try to combine take and drop to achieve this.
take 3 "hello world" = "hel"
drop 4 "hello world" = "o world"
I like the following solution:
del_every_nth :: Int -> [a] -> [a]
del_every_nth n = concat . map init . group n
You just have to define a function group which groups a list in portions of length n. But that's quite easy:
group :: Int -> [a] -> [[a]]
group n [] = []
group n xs = take n xs : group n (drop n xs)

Resources