Chomp will take the longest amount of repeated characters from a string and one will limit this to 9, e.g. if given the string "aaaaabbbcc" , the answer would be "aaaaa"
I need to define a function, runs, which will do a similiar thing but it will put the string into separate lists, e.g. if the given string is "aaaaabbbccc" , the answer would be ["aaaaa","bbb","cc"], and I need to use the munch function to do this.
The condition of 9 characters applies too, so if the given string is "aaaaaaaaaa" , the answer would be ["aaaaaaaaa","a"]
I've not actually got any implementation apart from something that I found which does pretty much does the same thing without the limit of 9 characters:
runs :: String -> String
runs x = group x
I thought of 2 ways of doing this, but I have no clue on the actual implementation, with one being to run the munch function for however many unique characters there are, i.e if there is an x amount of a , b , c in the given string, it would run 3 times, and then put those lists together into one list.
Another way that I thought of is to use guards. If the number of any single character in the given string is 9 or less, then just use the group function, otherwise, shorten it down using munch, or something like that.
Is anyone able to tell me if the two ideas I mentioned would work at all or suggest an alternative and how to get started? I'm a bit lost.
here is another approach
define a split function to break list at fixed size chunks
splitn :: Int -> [a] -> [[a]]
splitn _ [] = []
splitn n x = take n x : (splitn n $ drop n x)
now you can write your function as
runs = concatMap (splitn 9) . group
A quick google gives you exactly what you're looking for.
https://codereview.stackexchange.com/questions/158183/string-splitting-function-in-haskell
If it works consider upvoting their answer as I only copied a link
The basic strategy here is to take each unique list element to identify successive list elements that are identical. This let you have list elements in any mixed order. There are three functions but no imports.
The first function is rd which creates the list of unique elements.
The second function, t9 is because there might be over 18 of the same elements. t9 will create 9 character long list segments of identical elements with the remainder as the last list (string).
The final, unnamed function uses rd to compile lists of all elements matching each unique elements. It uses t9 to create segments of 9 elements.
l = "bbbbbbbbbaaaaaaaaaaaadddadaaaaaaacccccccccc"
rd [] = []; rd (x:xs) | elem x xs = rd xs | otherwise = x:rd xs
t9 [] = []; t9 xs = [take 9 xs] ++ t9 (drop 9 xs)
[ t | f <- rd l, s <- [[ g | g <- l, f == g ]], t <- t9 s ]
["bbbbbbbbb","dddd","aaaaaaaaa","aaaaaaaaa","aa","ccccccccc","c"]
Related
I'm having trouble conceptualizing given answer for problem 27 in haskell's 99 problems https://wiki.haskell.org/99_questions/Solutions/27.
The Problem:
"
Group the elements of a set into disjoint subsets.
a) In how many ways can a group of 9 people work in 3 disjoint subgroups of 2, 3 and 4 persons? Write a function that generates all the possibilities and returns them in a list.
Example:
* (group3 '(aldo beat carla david evi flip gary hugo ida))
( ( (ALDO BEAT) (CARLA DAVID EVI) (FLIP GARY HUGO IDA) )
... )
b) Generalize the above predicate in a way that we can specify a list of group sizes and the predicate will return a list of groups.
"
The answer they give is this:
combination :: Int -> [a] -> [([a],[a])]
combination 0 xs = [([],xs)]
combination n [] = []
combination n (x:xs) = ts ++ ds
where
ts = [ (x:ys,zs) | (ys,zs) <- combination (n-1) xs ]
ds = [ (ys,x:zs) | (ys,zs) <- combination n xs ]
group :: [Int] -> [a] -> [[[a]]]
group [] _ = [[]]
group (n:ns) xs =
[ g:gs | (g,rs) <- combination n xs
, gs <- group ns rs ]
I'm having a lot of trouble understanding how the first section (the section defining the function "combination") operates.
I'm pretty new to haskell too, so explain it to me like I'm in 5th grade.
Any feedback appreciated.
combination 0 xs = [([],xs)]
If we want to choose 0 elements from xs, there is only one way. No elements are taken [] and all the elements xs are left there.
combination n [] = []
Otherwise, we want to choose n (>0) elements. If we want to chose them from the empty list [], there are no ways to do that -- it's impossible.
combination n (x:xs) = ts ++ ds
where
ts = [ (x:ys,zs) | (ys,zs) <- combination (n-1) xs ]
ds = [ (ys,x:zs) | (ys,zs) <- combination n xs ]
Otherwise, we want to choose n (>0) elements from a nonempty list x:xs. There are many ways to do that, which we separate in two groups as follows:
we decide to take the element x among the chosen ones, and we are left with choosing n-1 from xs. This is done in ts, which considers all the ways to choose n-1 elements from xs, and then adds x to the list of "chosen" elements ys.
we decide to drop the element x from the input list, and we are left with choosing n from xs. This is done in ds, which considers all the ways to choose n elements from xs, and then adds x to the list of "dropped" elements zs.
We then output all such combinations using ts++ds.
Function combination takes list and one number. It creates the combination of the list considering the list has to be divided only in two parts. This is simply the original problem reduced only with 2 numbers k and n-k.
It does this using ts and ds lists.
ts is when the first element is in first part and then recursion occurs with remaining list and k-1. ds is where first element is in second part and recursion occurs with k and remaining part. Once remaining part is computed first element is added to it.
I want to be able to create a program in haskell that can an find an increasing subsequence from a list of numbers (not yet completed, this part is to compute for each sublist what the longest increasing subsequence is within that sublist). This program essentially take take from an input such as
1
5
1 2 9 6 8
where the first line is the number of test cases and the second line being the number of numbers in the specific test case, and the third line being the test case itself. It is looking for the multiple increasing sequences within the test case. Here is what I have so far:
main = do
inputCases <- getLine
let cases = (read inputCases :: Int)
forM [1..cases] $ \num -> do
inputNumbers <- getLine
let numbers = (read inputNumbers :: Int)
something <- getLine
let singlewords = words something
list = f singlewords
let hello = grid numbers numbers 0
let second = hello
print list
forM [0..numbers] $ \check -> do
forM [check..numbers] $ \check2 -> do
let val = 1
let keeper = val
forM [check..check2] $ \check3 -> do
let val = getVal hello list keeper check check2 check3
let keeper = val
return()
print check
print check2
print val
let hello = updateMatrix second val (check, check2)
let second = hello
f :: [String] -> [Int]
f = map read
grid :: Int -> Int -> a -> [[a]]
grid x y = replicate y . replicate x
getVal :: [[Int]] -> [Int] -> Int -> Int -> Int -> Int -> Int
getVal m b second x y z =
if b!!z < b!!y && 1+m!!x!!z > second then 1+m!!x!!z
else second
updateMatrix :: [[a]] -> a -> (Int, Int) -> [[a]]
updateMatrix m x (r,c) =
take r m ++
[take c (m !! r) ++ [x] ++ drop (c + 1) (m !! r)] ++
drop (r + 1) m
However, my problem is that once the program exits the ForM loop, it does not save the variable "hello" or anything that was declared in the for loop. Is there a better way of doing this? Would recursion work in this case? I am not quite sure how that would be implemented
lis[i][j] will hold the length of the longest increasing subsequence in {a[i], ..., a[j]}
here is the python code that I am trying to translate. Given this code, is there a better way of doing this besides the way I am currently trying to do it?
T = int(input())
for t in range(0, T):
n = int(input())
a = list(map(int, input().split()))
lis = [[0 for j in range(0, n)] for i in range(0, n)]
for i in range(0, n):
for j in range(i, n):
val = 1
for k in range(i, j):
if(a[k] < a[j] and 1 + lis[i][k] > val):
val = 1 + lis[i][k]
lis[i][j] = val
In my other answer, I discussed the answer to the question you asked about how to store information for retrieval later when in a forM loop. In this answer, I will discuss the idiomatic translation of for loops from other languages; generally this is not to produce a forM loop in Haskell.
Because this is an excellent programming exercise, I don't want to give away the answer -- there's a lot of joy and learning to be had from solving the problem yourself. But I do want to illustrate an alternative approach. To keep all the interesting bits of the translation I cooked up of your Python code, I will solve a slightly easier problem in a slightly stylized way: instead of lis[i][j] giving the length of the longest increasing subsequence between indices i and j in the original list, we will have lis[i][j] give the largest value between indices i and j in the original list.
The idea will go like this: instead of iterating over indices i and j, we'll iterate over suffixes starting at i, then over prefixes of suffixes starting at i and ending at j. To begin with, we'll do the naive thing of just calling maximum on each infix expression. So:
import Data.List
maxes0 a =
[ [ maximum inf
| inf <- tail (inits suff)
]
| suff <- init (tails a)
]
For example, we can try it on your example list in ghci:
> maxes0 [1,2,9,6,8]
[[1,2,9,9,9],[2,9,9,9],[9,9,9],[6,8],[8]]
Note right away that there's a difference in shape here: where in Python we produced a square result, here we produce a triangular one, omitting the useless entries that do not correspond to actual infix chunks of the original list. (It's easy to reintroduce dummy values if you actually need a square result for some reason.)
This is already pretty good, and quite idiomatic; however, there is one part of the Python code that it does not capture well yet: the Python code reuses previously computed values to do some dynamic programming. This can be done to the above code, as well, though it does require a bit of mental gymnastics the first few times you see it. We will use laziness and recursion to make available earlier results when computing later ones.
The idea here will be to keep a rolling max as we traverse the suffix, merging as we go the list of maximums of infixes with the new values we see in the suffix. So:
maxes1 a =
[ let row = head suff : zipWith max row (tail suff)
in row
| suff <- init (tails a)
]
We can see in ghci that this works just the same:
> maxes1 [1,2,9,6,8]
[[1,2,9,9,9],[2,9,9,9],[9,9,9],[6,8],[8]]
You can combine these two ideas (making the already-computed bits available via laziness+recursion, and making the infix list available by nested list comprehensions) to produce an idiomatic translation of the Python code which is completely pure, does not mention list indices anywhere, and does not use forM.
forM returns a list of values, one each per input element in the list it's handed, with whatever you compute in the body of the function you give to forM. So you can extract information from the loop body with the usual do-notation binding syntax. Here's a simple example that asks the user whether to double each number in a list:
import Control.Monad
vals = [1..5]
main = do
vals' <- forM vals $ \val -> do
v <- getLine
return (if v == "yes" then val*2 else val)
print vals'
An example of running it:
> main
yes
yes
no
no
yes
[2,4,3,4,10]
Though this example returned numbers for simplicity, you may return arbitrary information of interest from each loop iteration in this way.
I need to make a function "powers" that takes a number n and returns the infinite list of that number to the power of every number e.g.
powers 2 = 2,4,8,16,32......
I need to do this using very specific subset of the language where my only available built in functions are: div, mod, even, odd, head, tail, not, null, length, reverse, elem, map, filter, foldr, sum, product, take, drop, takewhile, dropWhile, zipWith and from.
the subset also has no ^ operator.
there are some further important constraints:
the code must not exceed 1 line of more than 80 characters
no "helper functions" allowed, i.e i cannot write another function to use within this definition.
So far my thinking is along these lines:
powers = \n -> map (\x -> "some function to get n to the power of x") (from 1)
but i cant figure out how to get the function to do this without a helper function.
for example if i was to use a function inflist that returned an infinite list of the number x then i could just do the following.
powers = \n -> map (\x -> product(take x (inflist n))) (from 1)
but i cant do this or anything like it because i couldn't use that function.
Sorry if the notation is a different to normal haskell, its a very strict core haskell subset that uses this notation.
This is a recursion question.
powers n = n : map (* n) (powers n)
(Are you allowed to use :?)
This was fun and funner when the insight came.
Generate successively longer repetitions of 2 in lists with
[ [ 2 | y <- [1..x]] | x <- [1..]]
Then take the product of each list.
map product [ [ 2 | y <- [1..x]] | x <- [1..]]
Be sure to use take x before an invocation
I struggled with a mod and multiple mod functions to limit lists.
If iterate were allowed.
take 24 $ iterate (2*) 2
would generate the list.
Edit 4/4/2018
An infinite recursive function, may be what you are looking for to fill out your function. It might be:
pow l = l ++ pow [(last l * 2)]
To produce a list it is absolutely necessary to assemble a list and it is necessary to use the last element of the list to calculate the next in sequence. This must also be run with take. Also the command following starts the list with 1. It can be started with any number such as 64 or 63. I tried passing the last value as a parameter but then the function would not generate a list. There is a choice, use ':' instead of '++' but it will produce each element in a list. To produce a list of values instead of a list of lists used 'concat $ ' before 'take' to clean it up.
take 10 $ pow [1]
I can remove all occurences of element in the list:
*Main> let d = [1, 2, 3, 4, 5, 6]
*Main> d
[1,2,3,4,5,6]
*Main> [x | x <- d, not(x == 2)]
[1,3,4,5,6]
I just wondering if there is any possibility to remove only FIRST occurence of element in the list, but using list comprehension?
No, there isn't. The list comprehension
[ x | x <- d, GUARD ]
is equivalent by definition to the following:
let ok x = if GUARD then [x] else []
ok _ = []
in concatMap ok d
By the definition of 'if', GUARD must be a pure boolean expression (i.e. evaluate to True of False alone), so it cannot keep track of state as you map over the list (assuming you're going to play by the rules).
Having said that, there is one way around this that uses comprehensions: zip state into your input list and run a list comprehension on that composite list. This composite list might have a type of something like [(Int, Bool)] where the Bool indicates whether this is the first item in the list. You then do something like:
[ x | (x, isFirst) <- zip d (findFirsts d), not (x == 2 && isFirst)]
where the implementation of findFirsts d is left as an exercise to the reader.
But you wouldn't want to do this in this particular case. It's a bad solution here because it basically means you're going to go through the list at least twice, once to figure out which items are the Firsts, and once to actually filter out the item(s) you don't want. If you implemented findFirsts naively, you might be looking at a bunch more work than even that. Not the right tool for the job!
For certain problems, though, like checking for the head or incorporating the specific position of an item into your results (as hvr has demonstrated), this can be a very effective technique.
Two other ways:
Use monadic computations to carry state as you sequentially iterate through the list. Might be OK for cases where you want to traverse arbitrary or complicated structures, or where your computation is going to be complicated, but in this case, you're better off if you:
Just use a simple recursive function solution, which is what Data.List.delete and deleteBy do.
For the record I wanted to point out that the delete function in the Data.List module provides exactly the behaviour you describe.
So you could cheat a bit and just use delete in your list comprehension:
> let l = [1,2,3,2,1]
> [x | x <- delete 2 l]
[1,3,2,1]
I guess this doesn't count.
...so, I was curious how to do this and here's a solution which doesn't use delete:
-- Removes the first occurrence of '2' in 'l', if any.
[x | (x,y) <- zip l [0..], let idx = elemIndex 2 l, idx == Nothing || y /= fromJust idx]
The idea is to first turn the list into a list of tuples where the second element of each tuple is the index of the element, e.g. "abcba" becomes [('a',0),('b',1),('c',2),('b',3),('a',4)]. Then we take each first element of all tuples for which the second tuple element does not equal the value returned by 'elemIndex' (which returns the position of the first occurance of the given element). For instance, elemIndex 'b' "abca" yields 2, so we take the first elements of all tuples where the second element is not 2. And that yields "acba".
The following removes the element only if occuring in head position:
[ x | (i, x) <- zip [0..] d, if i == 0 then x /= 2 else True ]
(which wasn't the question)
Not directly. List comprehensions are equivalent to using concat and map only. They map elements uniformly - if a is changed to b (or removed, or changed into several elements) then all occurences of a will do the same.
An ugly way would be to tag elements with numbers and search for the first one:
f r x = let x' = zip x [0..]
(_,n) = head [v | v <- x', fst v == r]
in [y | (y,m) <- x', y /= r || m /= n]
First zip can be expressed with LC if you use extension "parallel list comprehensions". This is extremely nonidiomatic, better use explicit recursion or Data.List.delete.
How do you shorten a string in Haskell with a given number.
Say:
comp :: String -> String
short :: String -> String
chomp (x:xs) = (x : takeWhile (==x) xs)
using comp I want to select a run of repeated characters from the start of a string, with
the run comprising at most nine characters.
For example:
short "aaaavvvdd"
would output "aaaa"
and short "dddddddddd"
outputs "ddddddddd".
I know I need take but am not sure how to put that into the code.
i've got this far but it doesn't work
short x:xs | length(short x:xs) >9 = take(9)
| otherwise = comp
The Quick Answer
import Data.List
short [] = []
short x = (take 9 . head . group) x
This will give you output that matches your desired output.
That is,
*> short "aaaavvvdd"
"aaaa"
*> short "dddddddddd"
"ddddddddd"
Step by Step Development
Use "group" to separate the items
This solution depends on the "group" function in the Data.List library. We begin with the definition:
short x = group x
This gives us:
*> short "aaaavvvddd"
["aaaa","vvv","ddd"]
Use "head" to return only the first element
Once we have the the elements in a list, we want only the first item of the list. We achieve this using "head":
short x = (head . group) x
"." is the Haskell function for function composition. It's the same as:
short x = head (group x)
or
short x = head $ group x
This will give us:
*> short "aaaavvvdd"
"aaaa"
*> short "dddddddddddddd"
"dddddddddddddd"
Use "take" to get the first nine characters
We finish the program by taking only the first nine characters of this result, and end up with our final function. To do this, we use the "take" function from the prelude:
short x = (take 9 . head . group) x
We now have the result that we wanted, but with one minor problem.
Add another case to eliminate the error
Note that using our current definition on the empty list causes an error,
*> short "aaaavvvddd"
"aaaa"
*> short ""
"*** Exception: Prelude.head: empty list
Because "head" is undefined on the empty list, we need to handle another case: the empty list. Now we have:
short [] = []
short x = (take 9 . head . group) x
This is our "final answer".
Here is another version:
short xs = take 9 $ takeWhile (== head xs) xs
So we take from the list as long as the content equals the head of list (which is the first char of the string). Then we use take to shorten the result when necessary.
Note that we don't need an additional case for empty strings, which is a consequence from Haskell's lazyness: If takeWhile sees that the list argument is empty, it doesn't bother to evaluate the condition argument, so head xs doesn't throw an error.
Here's a definition:
import Data.List (group)
short = take 9 . head . group
Interestingly enough, since our returned string is a prefix of the original string, and is constrained to be at most 9 characters long, it doesn't matter whether we trim down to that limit first or last. So we could also use this definition:
short = head . group . take 9
Both of these are written in the "pointfree" style which doesn't reference a lack of punctuation, but a lack of unnecessary variables. We could have also written the definition as
short s = take 9 (head (group s))
Or, using $ to get rid of parentheses:
short s = take 9 $ head $ group s
The only other step is to extract only the first block of matching characters, which is what head . group does (equivalent to your chomp function).
From the docs:
group :: Eq a => [a] -> [[a]]
The group function takes a list and returns a list of lists such that the concatenation of the result is equal to the argument. Moreover, each sublist in the result contains only equal elements. For example,
group "Mississippi" = ["M","i","ss","i","ss","i","pp","i"]
It is a special case of groupBy, which allows the programmer to supply their own equality test.