How can I use Haskell Memoize to solve LCS? - haskell

Here is the code:
import Data.Function.Memoize
main = do
let
f 0 0 = 0
f 0 _ = 0
f _ 0 = 0
f n m = if a !! n == b !! m
then 1 + f' (n-1) (m-1)
else max (f' (n-1) m) (f' n (m-1))
f' = memoize2 $ f
print $ length a
print $ length b
print $ f (length a - 1) (length b - 1)
where
a = "1234helloworld2ffdfdfdf32rg4364jm5"
b = "03424helloworldfdfdfdfd4353645645jnt"
But the problem is I cannot write the function globally where strings a and b are passed to it as arguments. It seems if I rewrite
f n m
to
f a b n m
and
f' = memoize4 f
the function will speed down.
How can I pass arguments that should not be used in memoization to functions that use memoize?
so I write my global function like this and it does work!
But how can I accumulate the common string it finds and get the final result with this function?
lcs a b = f (length a - 1) (length b - 1)
where
f 0 0 = 0
f 0 _ = 0
f _ 0 = 0
f n m = if a !! n == b !! m
then (1 + f' (n-1) (m-1))
else max (f' (n-1) m) (f' n (m-1))
f' = memoize2 $ f

Related

What's the difference between tail and guarded recursion?

In my exercise I have to decide what kind of recursion the functions are.
We have to choose from linear recursion, tail recursion and guarded recursion
but I don't really understand the difference between the last two.
Can some one explain the difference between guarded and tail recursion?
The functions we have to differentiate for reference:
pow2 0 = 1
pow2 n = 2 * pow2 (n-1)
factAux r i n
| i <= n = factAux (i * r) (i + 1) n | otherwise = r
factorial = factAux 1 1
init [x] = []
init (x:xs) = x : init xs
binom n 0 = 1
binom n k
| n == k = 1
| otherwise = binom (n - 1) k + binom (n - 1) (k - 1)
negList [] = []
negList (x : xs) = if x > 0 then negList (-x : xs) else x : negList xs
I won't solve your homework as it would be counter-educative.
Instead, I will answer the question in the post's title:
Tail recursion
A call is tail-recursive when
It's recursive
The result of that call is returned immediately, without any modification or action done after it
For example:
-- This is tail-rec
f x = if x == 0
then 0
else f (x + 1)
-- This is not
g x = if x == 0
then 0
else g (x + 1) - 1
-- And this is not too
h x = h (h x)
For more info, check this thread.
Guarded recursion
This occurs when a recursive call is positioned under a lazy parameter to a data constructor:
-- This is guarded-rec
f x = if x == 0
then []
else x : f (x - 1) -- (:) is lazy on both operands
-- And this is not
g x = if x == 0
then []
else g (x - 1)
-- And this is not too
data StrictList a = SNil | SCons !a !(StrictList a)
h x = if x == 0
then SNil
SCons x (h x)
Cross-examples
This link may help you seeing the difference. Also check out this, although it gives examples in Prolog.
Tail rec and guard rec
This is contradictory, as guarding a recursive call with a constructor breaks the "doing nothing to the result" requirement of tail recursion.
Tail rec and not guard rec
f x = f x
Not tail rec and guard rec
f x = x : f x
Not tail rec and not guard rec
f x = f x + 1

Number of loops in recursion

I would like to count the number of positive integers/elements in the list. This returns the elements with positive values, how can I count the elements? would like to construct something like count(array(...)).
I would like to see a version with i++ and foldl. That would be very helpful.
countPositivesRec :: [Int] -> [Int]
countPositivesRec [] = []
countPositivesRec (x:xs) | x >= 0 = x : tl
| otherwise = tl
where tl = countPositivesRec xs
Here's a hint: follow the same recursion scheme as before, but return an int at every step.
countPositivesRec :: [Int] -> Int
---
countPositivesRec [] = 0 -- no positives in the empty list
countPositivesRec (x:xs) | x >= 0 = ??
| otherwise = ??
where tl = countPositivesRec xs
One you solve this, it can be rewritten using foldr, if you want.
If you really want to use foldl instead, I would suggest you start by defining a function f such that
f (f (f 0 x0) x1) x2
evaluates to the number of positives in x0,x1,x2. Then you can use foldl f 0 inputList
The function you've written is filter (>=0). As Paul pointed out, the only step remaining is to count and length does that. We can transform the function step by step:
countPositivesRec :: [Int] -> [Int]
countPositivesRec [] = []
countPositivesRec (x:xs) | x >= 0 = x : tl
| otherwise = tl
where tl = countPositivesRec xs
Observe that xs is only used in the transformed form tl. That's what makes this a right fold.
onlypos1 = foldr maybekeep []
where maybekeep x tl | x >= 0 = x : tl
| otherwise = tl
This operation is known as a filter, keeping only some parts:
onlypos2 = filter dowekeep
where dowekeep x = x >= 0
onlypos3 = filter (\x -> x >= 0)
onlypos4 = filter (>= 0)
But this is of course only one of many possible approaches. For instance, strictness analysis can lead to the conclusion that length is better implemented as foldl' (\a _ -> succ a) 0 than foldr (\_ a -> succ a) 0. Indeed, that is its basic form in the Prelude:
length = foldl' (\c _ -> c+1) 0
We see that the combining function of length ignores the value of one argument, merely requires it to be there. This can naturally be merged with our condition that only some elements count:
lengthFilter1 = length . filter
lengthFilter2 pred = foldl' predCount 0
where predCount c x = if pred x then c+1 else c
countNonNegative = lengthFilter2 nonNegative
where nonNegative x = x >= 0
Incidentally, 0 isn't positive. It's non-negative.
In the end, Haskell's lazy lists mean we can use them to fuse traversals; length . filter (>=0) will only read the input list once, because the only reason it's processing results from filter is that length consumes them. The filtered list never exists as a fully expanded structure, unlike e.g. Python or PHP. This form is likely one of the most readable, but others exist, e.g.:
countNonNegatives xs = sum [1 | x <- xs, x >= 0]
You have
filtering p cons x r = if | p x -> cons x r | otherwise -> r
countPositives = length
. filter (> 0)
= foldr (\x r -> r + 1) 0 -- r++
. foldr (filtering (> 0) (:) ) []
= foldr (filtering (> 0) (\x r -> r + 1)) 0
(since folds fuse by composing their reducer transformers, a-la "fold replaces the cons with a reducer operation, so why create the cons in the first place if it gonna be replaced anyway"), and
filtering (> 0) (\x r -> r + 1) x r
= if | (> 0) x -> (\x r -> r + 1) x r | otherwise -> r
= if | x > 0 -> r + 1 | otherwise -> r
and thus, a version with fold and increment that you wanted,
countPositives = foldr (\x r -> if | x > 0 -> r + 1 | otherwise -> r) 0 -- r++
You can take it from here.

How can I extract list of similar elements from a haskell list

Given a list such as [1,0,0,0,3,0,0,0,0,2,4,0,0] and an index, how can I extract consecutive patterns of 0 in Haskell. For example if the given index is between 1 and 3 inclusive, the result is [0,0,0] if it is between 5 and 8 [0,0,0,0] and so on
First, build a list where run lengths are stored for each number:
runs :: (Eq a) => [a] -> [(a, Int)]
runs = map (head &&& length) . group
so e.g.
runs [1,0,0,0,1,0,0,0,0,1,1,0,0] == [(1,1),(0,3),(1,1),(0,4),(1,2),(0,2)]
Then, index into this list by walking it in run length-sized steps:
indexRuns :: Int -> [(a, Int)] -> [a]
indexRuns i [] = error "Index out of bounds"
indexRuns i ((x, l):rs)
| i < l = replicate l x
| otherwise = indexRuns (i - l) rs
You can do this in O(n) time:
extract :: Eq a => Int -> [a] -> [a]
extract _ [] = []
extract idx (x:xs) = extract' x [x] 1 xs
where
extract' _ _ _ [] = [] -- Index out of bounds
extract' v vs n (r : rest)
| idx == n = vs ++ (takeWhile (== v) rest)
| (v == r) = extract' v (r:vs) (n+1) rest
| otherwise = extract' r [r] (n+1) rest
This will count the number of zeros around the index
numZeros::Int->[Int]->Int
numZeros 0 (1:_) = 0
numZeros i (1:rest) = numZeros (i-1) rest
numZeros i theList
| i < zeroLen = zeroLen
| otherwise = numZeros (i-zeroLen) $ drop zeroLen theList
where
zeroLen = length (takeWhile (==0) theList)
You can replicate 0 the appropriate number of times to get the final list.
f = f' (takeWhile (== 0)) where
f' c n xs | n < 0 || null xs = []
f' c n (1:xs) = f (n - 1) xs
f' c 0 xs = c xs
f' c n (0:xs) = f' ((0:) . c) (n - 1) xs
Or even more obfuscated
f n xs = g (splitAt n xs) >>= takeWhile (== 0) where
g (xs, ys#(0:_)) = [reverse xs, ys]
g _ = []
Some tests:
main = mapM_ (\i -> print $ (i, f i [1,0,0,0,1,0,0,0,0,1,1,0,0])) [-1..13]
prints
(-1,[])
(0,[])
(1,[0,0,0])
(2,[0,0,0])
(3,[0,0,0])
(4,[])
(5,[0,0,0,0])
(6,[0,0,0,0])
(7,[0,0,0,0])
(8,[0,0,0,0])
(9,[])
(10,[])
(11,[0,0])
(12,[0,0])
(13,[])

haskell matrix power without using if-else statement

I have the following function to obtain power of a matrix
X^0 = identity matrix,
X^1 =X;
X^2 = X'X;
X^3 = X X' X;
X^4 = X' X X' X ......
I tried with following function:
import Numeric.Container
import Numeric.LinearAlgebra
mpow :: Field t => (Matrix t) -> Integer -> (Matrix t)
mpow x 0 = ident $ cols x
mpow x 1 = x
mpow x n =
if (mod n 2) == 0 then
multiply (trans x) (mpow x $ n - 1)
else
multiply x (mpow x $ n - 1)
Is it possible to rewrite this function without using the if-else statement ?
Yes, you could use guards. But quite often it will compile into the same internal representation in Haskell.
import Numeric.Container
import Numeric.LinearAlgebra
mpow :: Field t => (Matrix t) -> Integer -> (Matrix t)
mpow x 0 = ident $ cols x
mpow x 1 = x
mpow x n | (mod n 2) == 0 = multiply (trans x) (mpow x $ n - 1)
| otherwise = multiply x (mpow x $ n - 1)
As freyrs mentioned, guards and if statements are exactly equivalent as they are both converted to case of when you compile your code. But, you can still get rid of them:
mpow' :: Field t => (Matrix t) -> Integer -> (Matrix t)
mpow' x 0 = ident $ cols x
mpow' x 1 = x
mpow' x n = multiply (head (drop n' fs) $ x) (mpow' x $ n - 1)
where fs = [trans, id]
n' = fromInteger (mod n 2)
However, this isn't more concise, nor does it better communicate what your function is doing to the reader. So don't do this, unless you really hate conditionals.

Does the IO Monad evaluate lazily?

Here is the following code in which I try to found some prime divisors. I have tried to convert TAOCP algorithms to Haskell programs but I can understand when something evaluates lazily or eagerly:
modof2 n = let a0 = shiftR n 1
a1 = shiftL a0 1
in n-a1
iseven n = modof2 n == 0
factoringby2 n = let s=(lastf (takeWhile f [1..])) + 1
d=n `quot` powerof2 s
in (s,d)
where f s = let d = n `quot` (powerof2 s)
in if isodd d
then False
else True
lastf [] = 0
lastf xs = last xs
miller_rabin_prime_test n 0 result=return result
miller_rabin_prime_test n k result| (isodd n) && n>3 = do
a<-randomRIO(2,n-2)
let z = basic_step n a (fst sd) (snd sd)
miller_rabin_prime_test n (k-1) z
where sd=factoringby2 n
basic_step:: Integer->Integer->Int->Integer->Bool
basic_step n a s d =any (\x-> x==1 || x==n-1) (map x (map u [0..s-1]))
where u j=powerof2(j)*d
x j=modular_pow a j n 1
isprime n = if n==2 || n==3
then return True
else if n<2
then return False
else if iseven n
then return False
else miller_rabin_prime_test n 5 True
x_m :: Double->Integer->Integer
x_m 0 n = 2
x_m m n = f (x_m (m-1) n) `mod` n
where f x = x^2 +1
l::Double->Double
l m = 2 ^ (floor (log2 m))
where log2 m = log m / log 2
g m n = let a = x_m m n
b = x_m ((l m)-1) n
in gcd (a-b) n
gg n = [g m n|m<-[1..]]
algorithmB n = do
testprime<-isprime n
let a = head (filter (1>) (gg n))
c<-algorithmB (n `div` a)
if testprime
then return []
else return (a:c)
algorithmB does not terminate. Why this happens? I think that c<-algorithmB (n div a) is the reason because it does not evaluate lazily. Is that true?
Thanks
algorithmB calls itself in an infinite loop. Of course it doesn't return!

Resources