In Haskell, given a list of lists, where each sublist contains any number of integers, how can I write a function that returns the total number of elements in all the lists?
For example if my list is:
[[1,2,3],[4,3],[2,1],[5]]
The function would return 8, since there are 8 total elements in the list of lists. I know you can use length [] to get the length of a normal list, but how do I do this with a list of lists? I would assume the solution to be recursive, but could use some help, since I am new to the language.
Three ways:
Get the length of each inner list, and sum them all:
GHCi> sum (fmap length [[1,2,3],[4,3],[2,1],[5]])
8
(Note this is equivalent to Thomas English's answer: map is fmap specialised to lists.)
Flatten the list of lists, and then get the length:
GHCi> length (concat [[1,2,3],[4,3],[2,1],[5]])
8
Use the Compose wrapper, which will make length drill through the two layers of lists.
GHCi> import Data.Functor.Compose
GHCi> length (Compose [[1,2,3],[4,3],[2,1],[5]])
8
(While explaining exactly what is going on here is a little bit tricky -- in a nutshell, we are exploiting that Compose has a Foldable instance -- behind the scenes it boils down to something very much like the first solution.)
I would assume the solution to be recursive
Indeed. It's just that the additional recursion is performed by the other functions we use (fmap for lists, sum, concat, etc.), and so we don't have to write the recursive algorithms explicitly.
You should check out how to use the 'map' function. Learn You a Haskell is a good resource to learn more!
mylist = [[1,2,3],[4,3],[2,1],[5]]
-- Get the length of each sublist with map
sublist_lengths = map length mylist
-- sublist_lengths = [3, 2, 2, 1]
result = sum sublist_lengths
One additional (pedantic) solution using folds:
foldr ((+) . foldr ((+) . const 1) 0) 0
-- or more simply:
foldr ((+) . length) 0
This incredibly ugly fold generalizes to:
sum [1 | xs <- xss, x <- xs]
which is certainly easier to read.
So all you need is to treat each list in the list as separate. What tools can do that? As Adam Smith demonstrates foldr is probably the tool of choice however fmap looks good, too and may be shorter.
What other tools are there? One of my favorites, the list comprehension.
The basic list comprehension lets you process each element of a list in turn.
For yours:
yourList = [[1,2,3],[4,3],[2,1],[5]]
[length l | l <- yourList] -- gets the length of each list and
sum [length l | l <- yourList] -- adds up all the lengths produced
Related
How might I go about efficiently generating an infinite list of Catalan numbers? What I have now works reasonably quickly, but it seems to me that there should be a better way.
c 1 = 1
c n = sum (zipWith (*) xs (reverse xs)) : xs
where xs = c (n-1)
catalan = map (head . c) [1..]
I made an attempt at using fix instead, but the lambda isn't lazy enough for the computation to terminate:
catalan = fix (\xs -> xs ++ [zipWith (*) xs (reverse xs)])
I realize (++) isn't ideal
Does such a better way exist? Can that function be made sufficiently lazy? There's an explicit formula for the nth, I know, but I'd rather avoid it.
The Catalan numbers [wiki] can be defined inductively with:
C0 = 1 and Cn+1=(4n+2)×Cn/(n+2).
So we can implement this as:
catalan :: Integral i => [i]
catalan = xs
where xs = 1 : zipWith f [0..] xs
f n cn = div ((4*n+2) * cn) (n+2)
For example:
Prelude> take 10 catalan
[1,1,2,5,14,42,132,429,1430,4862]
I'm guessing you're looking for a lazy, infinite, self-referential list of all the Catalan numbers using one of the basic recurrence relations. That's a common thing to do with the Fibonacci numbers after all. But it would help to specify the recurrence relation you mean, if you want answers to your specific question. I'm guessing this is the one you mean:
cat :: Integer -> Integer
cat 1 = 1
cat n = sum [ cat i * cat (n - i) | i <- [1 .. n - 1] ]
If so, the conversion to a self-referential form looks like this:
import Data.List (inits)
cats :: [Integer]
cats = 1 : [ sum (zipWith (*) pre (reverse pre)) | pre <- tail (inits cats) ]
This is quite a lot more complex than the fibonacci examples, because the recurrence refers to all previous entries in the list, not just a fixed small number of the most recent. Using inits from Data.List is the easiest way to get the prefix at each position. I used tail there because its first result is the empty list, and that's not helpful here. The rest is a straight-forward rewrite of the recurrence relation that I don't have much to say about. Except...
It's going to perform pretty badly. I mean, it's better than the exponential recursive calls of my cat function, but there's a lot of list manipulation going on that's allocating and then throwing away a lot of memory cells. That recurrence relation is not a very good fit for the recursive structure of the list data type. You can explore a lot of ways to make it more efficient, but they'll all be pretty bad in the end. For this particular case, going to a closed-form solution is the way to go if you want performance.
Apparently, what you wanted is
> cats = 1 : unfoldr (\ fx -> let x = sum $ zipWith (*) fx cats in Just (x, x:fx)) [1]
> take 10 cats
[1,1,2,5,14,42,132,429,1430,4862]
This avoids the repeated reversing of the prefixes (as in the linked answer), by unfolding with the state being a reversed prefix while consing onto the state as well as producing the next element.
The non-reversed prefix we don't have to maintain, as zipping the reversed prefix with the catalans list itself takes care of the catalans prefix's length.
You did say you wanted to avoid the direct formula.
The Catalan numbers are best understood by their generating function, which satisfies the relation
f(t) = 1 + t f(t)^2
This can be expressed in Haskell as
f :: [Int]
f = 1 : convolve f f
for a suitable definition of convolve. It is helpful to factor out convolve, for many other counting problems take this form. For example, a generalized Catalan number enumerates ternary trees, and its generating function satisfies the relation
g(t) = 1 + t g(t)^3
which can be expressed in Haskell as
g :: [Int]
g = 1 : convolve g (convolve g g)
convolve can be written using Haskell primitives as
convolve :: [Int] -> [Int] -> [Int]
convolve xs = map (sum . zipWith (*) xs) . tail . scanl (flip (:)) []
For these two examples and many other special cases, there are formulas that are quicker to evaluate. convolve is however more general, and cognitively more efficient. In a typical scenario, one has understood a counting problem in terms of a polynomial relation on its generating function, and now wants to compute some numbers in order to look them up in The On-Line Encyclopedia of Integer Sequences. One wants to get in and out, indifferent to complexity. What language will be least fuss?
If one has seen the iconic Haskell definition for the Fibonacci numbers
fibs :: [Int]
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
then one imagines there must be a similar idiom for products of generating functions. That search is what brought me here.
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.
I have the following code:
let numbers = [[1],[2],[3],[4]]
I want to append "3" to the sublist at index 2 of the list ([3]), like this:
(numbers !! 2) ++ [3]
to get this:
numbers = [[1],[2],[3,3],[4]]
But Im very confused :P Any idea?
other way is by take and drop
take 2 numbers ++[(numbers !! 2) ++ [3]]++drop 3 numbers
take the first 2 array --> [[1],[2]]
find the target array and [3] to it --> [[3]++[3]] returns [[3,3]]
drop 3 first array --> [[4]]
[[1],[2]] ++ [[3]++[3]] ++ [[4]] = [[1],[2],[3,3],[4]]
If writing the recursive update function is difficult for you, you can convert your list structure to a synthetic indexed array with zip
zip [0..] [[1],[2],[3],[4]]
and write your concat version based on the index as you do in other languages with indexed arrays
appendAt n a = map (\(i,x) -> if i==n then x++[a] else x) . zip [0..]
then,
appendAt 2 3 numbers
wll give you the desired result.
As chi already commented, the best way to do such an update on part of a structure in modern Haskell is with lense combinators, specifically, ix:
Prelude Control.Lens> let numbers = [[1],[2],[3],[4]]
Prelude Control.Lens> numbers & ix 2 %~ (++[3])
[[1],[2],[3,3],[4]]
(Don't be scared of lenses. The main lens package is huge and dependency-heavy, but most of its killer features, including ix, are also covered by the compatible and much smaller microlens package.)
As others have noted, in Haskell you don't normally modify a data structure in place. Instead, you break it apart, introduce your modification, and put it back together to create a new data structure that incorporates the change.
For making changes to a specific list element, I've found the splitAt function to be useful for breaking apart lists. For example, if you split your list at index 2, it produces the following pair of lists:
> splitAt 2 numbers
( [[1],[2]] , [[3],[4]] ) -- spaces added to make it clearer
Note that the element you want to change is the first element of the second list. You can use Haskell's pattern matching to process this pair conveniently:
> let (a, x:b) = splitAt 2 numbers
> a -- initial part of list
[[1],[2]]
> x -- element to change
[3]
> b -- rest of list
[[4]]
> a ++ x : b -- put list back together unchanged
[[1],[2],[3],[4]]
> a ++ (x ++ [3]) : b -- put list together w/ modification
[[1],[2],[3,3],[4]]
If this was turned into a Haskell function, it would probably look like:
appendSublist :: Int -> [a] -> [[a]] -> [[a]]
appendSublist idx y lst
= let (a, x:b) = splitAt idx lst
in a ++ (x ++ y) : b
which you'd use like this:
> appendSublist 2 [3] numbers
[[1],[2],[3,3],[4]]
This basic pattern:
let (a, x:b) = splitAt idx lst in a ++ (...replacement for x...) : b
is worth memorizing, since it's pretty useful.
Eventually, you'll probably want to learn to use the lens library for this kind of thing. Lenses are more concise and more flexible (i.e., work for all sorts of things, not just specific list items), but there's a pretty big learning curve, as you can maybe guess from #leftaroundabout's answer.
I've just started out learning Haskell, and am trying my hand at Project Euler.
I have a list of numbers I'd like to create into a 2-D list split into sublists of lengths defined in another list.
So, I'd like a function which takes a list of Ints and a list of lengths and operates on them like so:
f [1..20] [5,8,6] = [[1,2,3,4,5],[6,7,8,9,10,11,12,13],[14,15,16,17,18,19]]
It would be great if the function could take an infinite list of numbers and lengths and just keep sublisting.
I have little idea of how to go about this. Looking around Stack Overflow, I'm seeing (fairly complex to my novice eyes) solutions to packing a list into sublists of equal length, but not much like what I'm interested in.
Let's use recursion to implement the following function according to your specification:
splitAts :: [a] -> [Int] -> [[a]]
Note that I've flipped the order of arguments, because this way, the partially applied function splitAts n can be thought of as the meaningful operation that, given any list, will split it into sublists of the given length.
The easy case is when there are no (more) sublist lengths specified:
splitAts [] xs = []
The recursive case is when there is some first sublist length n: in this case, the first sublist we return will have this length, and the rest will simply be the split of the rest of the list according to the rest of the lengths:
splitAts (n:ns) xs = take n xs : splitAts ns (drop n xs)
There already exists a function splitAt that does the take n / drop n in one sweep, so the above can be rewritten as the better-performing
splitAts (n:ns) xs = here : splitAts ns there
where
(here, there) = splitAt n xs
Example run:
*Main> splitAts [5, 8, 6] [1..20]
[[1,2,3,4,5],[6,7,8,9,10,11,12,13],[14,15,16,17,18,19]]
It is nicely lazy: not just this works:
*Main> splitAts [5, 8, 6] [1..]
[[1,2,3,4,5],[6,7,8,9,10,11,12,13],[14,15,16,17,18,19]]
but this one as well:
*Main> take 10 (splitAts [3,5..] [1..])
[[1,2,3],[4,5,6,7,8],[9,10,11,12,13,14,15],[16,17,18,19,20,21,22,23,24],
[25,26,27,28,29,30,31,32,33,34,35],[36,37,38,39,40,41,42,43,44,45,46,47,48]]
So, I'm new here, and I would like to ask 2 questions about some code:
Duplicate each element in list by n times. For example, duplicate [1,2,3] should give [1,2,2,3,3,3]
duplicate1 xs = x*x ++ duplicate1 xs
What is wrong in here?
Take positive numbers from list and find the minimum positive subtraction. For example, [-2,-1,0,1,3] should give 1 because (1-0) is the lowest difference above 0.
For your first part, there are a few issues: you forgot the pattern in the first argument, you are trying to square the first element rather than replicate it, and there is no second case to end your recursion (it will crash). To help, here is a type signature:
replicate :: Int -> a -> [a]
For your second part, if it has been covered in your course, you could try a list comprehension to get all differences of the numbers, and then you can apply the minimum function. If you don't know list comprehensions, you can do something similar with concatMap.
Don't forget that you can check functions on http://www.haskell.org/hoogle/ (Hoogle) or similar search engines.
Tell me if you need a more thorough answer.
To your first question:
Use pattern matching. You can write something like duplicate (x:xs). This will deconstruct the first cell of the parameter list. If the list is empty, the next pattern is tried:
duplicate (x:xs) = ... -- list is not empty
duplicate [] = ... -- list is empty
the function replicate n x creates a list, that contains n items x. For instance replicate 3 'a' yields `['a','a','a'].
Use recursion. To understand, how recursion works, it is important to understand the concept of recursion first ;)
1)
dupe :: [Int] -> [Int]
dupe l = concat [replicate i i | i<-l]
Theres a few problems with yours, one being that you are squaring each term, not creating a new list. In addition, your pattern matching is off and you would create am infinite recursion. Note how you recurse on the exact same list as was input. I think you mean something along the lines of duplicate1 (x:xs) = (replicate x x) ++ duplicate1 xs and that would be fine, so long as you write a proper base case as well.
2)
This is pretty straight forward from your problem description, but probably not too efficient. First filters out negatives, thewn checks out all subtractions with non-negative results. Answer is the minumum of these
p2 l = let l2 = filter (\x -> x >= 0) l
in minimum [i-j | i<-l2, j<-l2, i >= j]
Problem here is that it will allow a number to be checkeed against itself, whichwiull lend to answers of always zero. Any ideas? I'd like to leave it to you, commenter has a point abou t spoon-feeding.
1) You can use the fact that list is a monad:
dup = (=<<) (\x -> replicate x x)
Or in do-notation:
dup xs = do x <- xs; replicate x x; return x
2) For getting only the positive numbers from a list, you can use filter:
filter (>= 0) [1,-1,0,-5,3]
-- [1,0,3]
To get all possible "pairings" you can use either monads or applicative functors:
import Control.Applicative
(,) <$> [1,2,3] <*> [1,2,3]
[(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)]
Of course instead of creating pairs you can generate directly differences when replacing (,) by (-). Now you need to filter again, discarding all zero or negative differences. Then you only need to find the minimum of the list, but I think you can guess the name of that function.
Here, this should do the trick:
dup [] = []
dup (x:xs) = (replicate x x) ++ (dup xs)
We define dup recursively: for empty list it is just an empty list, for a non empty list, it is a list in which the first x elements are equal to x (the head of the initial list), and the rest is the list generated by recursively applying the dup function. It is easy to prove the correctness of this solution by induction (do it as an exercise).
Now, lets analyze your initial solution:
duplicate1 xs = x*x ++ duplicate1 xs
The first mistake: you did not define the list pattern properly. According to your definition, the function has just one argument - xs. To achieve the desired effect, you should use the correct pattern for matching the list's head and tail (x:xs, see my previous example). Read up on pattern matching.
But that's not all. Second mistake: x*x is actually x squared, not a list of two values. Which brings us to the third mistake: ++ expects both of its operands to be lists of values of the same type. While in your code, you're trying to apply ++ to two values of types Int and [Int].
As for the second task, the solution has already been given.
HTH