How can I create a function which lazily makes permutations for the chars '_' and '*' like this:
For example:
Main> function 3
["___","*__","_*_","__*","**_","_**","*_*","***"]
First element is made only from _, the next 3 are permutations that lists: *__, the second 3 are permutations that lists **_, and the last element contains only *.
How can I do that?
Here's another "correct order" version:
function :: Int -> [String]
function c = concatMap helper $ zip (reverse [0..c]) [0..c]
helper :: (Int, Int) -> [String]
helper (c, 0) = [replicate c '_']
helper (0, c) = [replicate c '*']
helper (cUnderscores, cAsterisks) = map ('_' :) (helper (cUnderscores - 1, cAsterisks))
++ map ('*' :) (helper (cUnderscores, cAsterisks - 1))
You might want to look at replicateM.
let k = ["_", "*"]
let p = [ a ++ b ++ c | a <- k, b <- k, c <- k ]
The “correct order” version:
import Data.List
function k = concatMap (nub . permutations . pat) [0..k]
where pat x = replicate x '*' ++ replicate (k-x) '_'
I don’t know how to step from one permutation to another in constant time, though.
Related
I want to rotate a string in haskell, so if I give "Now I want to scream" to rotate [[want to scream now I],[scream now I want to]] , if the string start with "I" or "to" then must eliminate it. Till now I still have problems with the rotation.
reverseWords :: String -> String
reverseWords = unwords . reverse . words
shiftt :: [a] -> Int -> [a]
shiftt l n = drop n l ++ take n l
rot::String->[String]
rot l = [ reverseWords l i | i <- [0 .. (length l) -1]]
create a list of all rotations, then filter out based on your predicate. For example,
rotations x = take (length x) $ iterate rot1 x
where rot1 = drop 1 x ++ take 1 x
filteredRots = map unwords . filter (\x -> length (head x) > 2) . rotations . words
and use as
> filteredRots "Now I want to scream"
["Now I want to scream","want to scream Now I","scream Now I want to"]
Prelude>
If I was given a string like skhfbvqa, how would I generate the next string? For this example, it would be skhfbvqb, and the next string of that would be skhfbvqc, and so on. The given string (and the answer) will always be N characters long (in this case, N=8).
What I tried:
I tried to generate the entire (infinite) list of possible combinations, and get the required (next) string of the given string, but unsurprisingly, it's so slow, that I don't even get the answer for N=6.
I used list comprehension:
allStrings = [ c : s | s <- "" : allStrings, c <- ['a'..'z'] ]
main = do
input <- readFile "k.in"
putStrLn . head . tail . dropWhile (not . (==) input) . map reverse $ allStrings
(Please excuse my incredibly bad Haskell-ing :) Still a noob)
So my question is, how can I do this? If there are multiple methods, a comparison between them is much appreciated. Thanks!
Here's a version with base conversion (this way you could add and subtract arbitrarily if you like):
encode x base = encode' x [] where
encode' x' z | x' == 0 = z
| otherwise = encode' (div x' base) ((mod x' base):z)
decode num base =
fst $ foldr (\a (b,i) -> (b + a * base^i,i + 1)) (0,0) num
Output:
*Main> map (\x -> toEnum (x + 97)::Char)
$ encode (decode (map (\x -> fromEnum x - 97) "skhfbvqa") 26 + 1) 26
"skhfbvqb"
I would go and make a helper function f :: Integer -> String and one g :: String -> Integer, where f 1 = "a", ... f 27 = "aa", f 28 = "ab" and so on and the inverse g.
Then incrementString = f . succ . g
Note: I omitted the implementation of f on purpose for learning
Update
for a different approach you could define a increment with carry function inc' :: Char -> (Char, Bool), and then
incString :: String -> String
incString = reverse . incString'
where incString' [] = []
incString' (x:xs) = case inc' x of (x',True) -> x': incString' xs
(x',False) -> x':xs
Note: this function is not tail recursive!
I found this to work. It just uses pattern matching to see if the string begins with a z and adds an additional a accordingly.
incrementString' :: String -> String
incrementString' [] = ['a']
incrementString' ('z':xs) = 'a' : incrementString' xs
incrementString' (x:xs) = succ x : xs
incrementString :: String -> String
incrementString = reverse . incrementString' . reverse
Im am making a function which compares two strings to see if one is a rearrangement of the other. for example "hhe" and "heh" would produce true but "hhe" and "hee" would be false. I thought I could do this by summing the elements of the string and seeing if they are the same. I am knew to haskell, so I dont know if I can sum chars like in C. Code so far:
comp :: String -> String-> Bool
comp x y = (sum x) == (sum y)
This produces an error when compiling.
You can first sort, then compare the strings
import Data.List
import Data.Function
comp = (==) `on` sort
which can then be used like this
"abcd" `comp` "dcba" --yields True
It doesn't make sense to "sum" two strings. Use permutations instead:
comp :: String -> String -> Bool
comp x = (`elem` permutations x)
Live demo
Though there are problems with your implementation, as suggested by others, the direct answer to your question is that you can first convert characters to Int (a type that supports arithmetic) with fromEnum.
> sum . map fromEnum $ "heh"
309
Taking your example code at face value, the problem with it is that Char doesn't implement Num, so sum :: Num a => [a] -> a is incompatible.
We can fix that, however, by using fromEnum to convert the Chars to Ints:
isPermutationOf :: String -> String-> Bool
isPermutationOf x y = hash x == hash y
where hash = sum . map fromEnum
And this will work on your example case:
λ isPermutationOf "hhe" "heh"
True
The downside is that it also has some false positives:
λ isPermutationOf "AAA" "ab"
True
We can try to reduce those somewhat by making sure that the lengths, maxes, and mins of the inputs are the same:
isPermutationOf :: String -> String-> Bool
isPermutationOf x y = hash x == hash y && maximum x == maximum y && minimum x == minimum y
where hash = sum . map fromEnum
But though that catches some cases
λ isPermutationOf "AAA" "ab"
False
It doesn't catch them all
λ isPermutationOf "abyz" "acxz"
True
To do that, we really need to make sure we've got the same number of each Char in both inputs. We could solve this by using a Data.Map.Map to store the counts of each Char or by using Data.List.sort to sort each of the inputs, but if we only want to use the Prelude, we'll need to roll our own solution.
There's any number of examples on how to write quicksort in haskell out there, so I'm not going to tell you how to do that. So here's a dumb isPermutationOf that uses math instead.
isPermutationOf xs ys = all (\k -> powsum k as == powsum k bs) [0..n]
where as = map fromEnum xs
bs = map fromEnum ys
n = length xs
powsum k zs = sum (map (^k) zs)
Basically, we can view an n-length string as a set of n unknowns. isPermutationOf checks the n+1 equations:
eq0: x00 + x10 + ... + xn-10 = y00 + y10 + ... + ym-10
eq1: x01 + x11 + ... + xn-11 = y01 + y11 + ... + ym-11
eq2: x02 + x12 + ... + xn-12 = y02 + y12 + ... + ym-12
...
eqn: x0n + x1n + ... + xn-1n = y0n + y1n + ... + ym-1n
eq0 is essentially a length check. Given xs, the other n equations work out to n equations for n unknowns, which will give us a solution for ys unique up to permutation.
But really, you should use a (bucket) sort instead, because the above algorithm is O(n^2), which is slow for this kind of check.
if you do not want to use standard library(learning purpose) function, you can quickSort both string and check for equality of string (bonus: quickSort)
isEqual :: String -> String -> Bool
isEqual a b = sortString a == sortString b
where
sortString :: String -> String
sortString [] = []
sortString (x:xs) = sortString (filter (<x) xs) ++ [x] ++ sortString (filter (>=x) xs)
I want to create function that split string to list of substrings where each substring have length of k:
*Main> split_string_to_kmers "some_text" 3
["som","ome","me_","e_t","_te","tex","ext"]
Here is my solution:
split_string_to_kmers s k = split_string_to_kmers_helper s k []
where split_string_to_kmers_helper [] k acc = acc
split_string_to_kmers_helper s k acc
| length s >= k = split_string_to_kmers_helper (tail s) k (acc ++ [(take k s)])
| otherwise = acc
I am just wondering if there is a way to rewrite my code so it will be more haskell specific.
I guess this slightly different enough.
import Data.List (tails)
mySplit :: String -> Int -> [String]
mySplit str k = filter (\s -> length s == k) $ map (take k) (tails str)
You could make this more efficient by combining the filter and the map. But that is up to you.
Simple solution is next (not the same tail of list):
import Data.List.Split(chop)
splitRepN n = chop (\xs -> (take n xs,tail xs))
And we have next results:
> splitRepN 3 "some_text"
["som","ome","me_","e_t","_te","tex","ext","xt","t"]
And we cut short tails for full solution:
splitRepN' n = takeWhile ((== n). length) . splitRepN n
> splitRepN' 3 "some_text"
["som","ome","me_","e_t","_te","tex","ext"]
I am doing another Project Euler problem and I need to find when the result of these 3 lists is equal (we are given 40755 as the first time they are equal, I need to find the next:
hexag n = [ n*(2*n-1) | n <- [40755..]]
penta n = [ n*(3*n-1)/2 | n <- [40755..]]
trian n = [ n*(n+1)/2 | n <- [40755..]]
I tried adding in the other lists as predicates of the first list, but that didn't work:
hexag n = [ n*(2*n-1) | n <- [40755..], penta n == n, trian n == n]
I am stuck as to where to to go from here.
I tried graphing the function and even calculus but to no avail, so I must resort to a Haskell solution.
Your functions are weird. They get n and then ignore it?
You also have a confusion between function's inputs and outputs. The 40755th hexagonal number is 3321899295, not 40755.
If you really want a spoiler to the problem (but doesn't that miss the point?):
binarySearch :: Integral a => (a -> Bool) -> a -> a -> a
binarySearch func low high
| low == high = low
| func mid = search low mid
| otherwise = search (mid + 1) high
where
search = binarySearch func
mid = (low+high) `div` 2
infiniteBinarySearch :: Integral a => (a -> Bool) -> a
infiniteBinarySearch func =
binarySearch func ((lim+1) `div` 2) lim
where
lim = head . filter func . lims $ 0
lims x = x:lims (2*x+1)
inIncreasingSerie :: (Ord a, Integral i) => (i -> a) -> a -> Bool
inIncreasingSerie func val =
val == func (infiniteBinarySearch ((>= val) . func))
figureNum :: Integer -> Integer -> Integer
figureNum shape index = (index*((shape-2)*index+4-shape)) `div` 2
main :: IO ()
main =
print . head . filter r $ map (figureNum 6) [144..]
where
r x = inIncreasingSerie (figureNum 5) x && inIncreasingSerie (figureNum 3) x
Here's a simple, direct answer to exactly the question you gave:
*Main> take 1 $ filter (\(x,y,z) -> (x == y) && (y == z)) $ zip3 [1,2,3] [4,2,6] [8,2,9]
[(2,2,2)]
Of course, yairchu's answer might be more useful in actually solving the Euler question :)
There's at least a couple ways you can do this.
You could look at the first item, and compare the rest of the items to it:
Prelude> (\x -> all (== (head x)) $ tail x) [ [1,2,3], [1,2,3], [4,5,6] ]
False
Prelude> (\x -> all (== (head x)) $ tail x) [ [1,2,3], [1,2,3], [1,2,3] ]
True
Or you could make an explicitly recursive function similar to the previous:
-- test.hs
f [] = True
f (x:xs) = f' x xs where
f' orig (y:ys) = if orig == y then f' orig ys else False
f' _ [] = True
Prelude> :l test.hs
[1 of 1] Compiling Main ( test.hs, interpreted )
Ok, modules loaded: Main.
*Main> f [ [1,2,3], [1,2,3], [1,2,3] ]
True
*Main> f [ [1,2,3], [1,2,3], [4,5,6] ]
False
You could also do a takeWhile and compare the length of the returned list, but that would be neither efficient nor typically Haskell.
Oops, just saw that didn't answer your question at all. Marking this as CW in case anyone stumbles upon your question via Google.
The easiest way is to respecify your problem slightly
Rather than deal with three lists (note the removal of the superfluous n argument):
hexag = [ n*(2*n-1) | n <- [40755..]]
penta = [ n*(3*n-1)/2 | n <- [40755..]]
trian = [ n*(n+1)/2 | n <- [40755..]]
You could, for instance generate one list:
matches :: [Int]
matches = matches' 40755
matches' :: Int -> [Int]
matches' n
| hex == pen && pen == tri = n : matches (n + 1)
| otherwise = matches (n + 1) where
hex = n*(2*n-1)
pen = n*(3*n-1)/2
tri = n*(n+1)/2
Now, you could then try to optimize this for performance by noticing recurrences. For instance when computing the next match at (n + 1):
(n+1)*(n+2)/2 - n*(n+1)/2 = n + 1
so you could just add (n + 1) to the previous tri to obtain the new tri value.
Similar algebraic simplifications can be applied to the other two functions, and you can carry all of them in accumulating parameters to the function matches'.
That said, there are more efficient ways to tackle this problem.