Height of a Rose Tree Haskell - haskell

Consider the following definition of Rose Trees:
data RTree a = R a [RTree a]
I need help defining the function rtHeight :: (RTree a) -> Int that calculates the height of a rose tree.
So far, I have tried the following
rtHeight R a [] = 1
rtHeight R a l = 1 + rtHeight l
However, this does not work becuase l is a list of rose trees.
I have also tried the following:
rtHeight R a [] = 1
rtHeight R a l = maximum (map (rtHeight) l)
I believe this fails becuase I am not adding a level while I am going down the tree.

Here is my final answer. Tested and it worked:
rtHeight R a [] = 1
rtHeight R a l = 1 + maximum (map (rtHeight) l)

In Why Functional Programming Matters (PDF), the author includes a code that is equivalent to the following:
reduce_tree f g z t =
f (label t) (reduce (g . reduce_tree f g z) z (branches t))
Using it, we can write
rtHeight t = reduce_tree f g z t
where
f _ y = 1 + y -- 1 more than maximum height of subtrees
g x y = max x y -- y is maximum height of subtrees to the right
z = 0 -- the smallest height is 0
label (R a _ ) = a
branches (R _ bs) = bs
reduce = foldr
As an illustration, for a tree t = R a [b,c,d], this calculates t's height as
rtHeight t = 1 + max (rtHeight b) -- rtHeight == reduce_tree f g z
(max (rtHeight c)
(max (rtHeight d)
0))
That is because, for the built-in foldr function,
foldr g z [a,b,c,...,n] == g a (g b (g c (... (g n z)...)))
An interesting identity is foldr (g . h) z xs == foldr g z (map h xs), and since maximum (xs ++ [0]) == foldr max 0 xs, your direct recursive formulation of rtHeight can be recovered from this generalized formulation.

Related

Summing up all the nodes a tree with a generic type. (Haskell)

I have been trying to write a code which takes all the integers in a tree and return a sum of them. I'm trying to do this with type a, which is from a data time:
data Tree a = Nil | Value a (Tree a) (Tree a)
deriving Show
and we want to use:
tree = Value 2 (Value 2 (Value 2 Nil Nil) Nil) (Value 2 Nil Nil)
and my code is as follow:
countTree :: (a -> a -> a) -> a -> Tree a -> a
countTree p k (Nil) = h
countTree p k (Value x y z) = x (+) (countTree p k y) (+) (countTree p k z)
and I want to run my code as countTree (+) 0 tree and the results should return 8.
The problem is that when I run my code it tells me that x has four arguments but it's type a has zero which I honestly don't understand why. I've modifying sections of my code, but no success once so ever, I could really use some assistance.
x (+) (countTree p k y) (+) (countTree p k z)
is attempting to treat x as a function, and pass to it as arguments all of
(+) (countTree p k y) (+) (countTree p k z)
If you want to have "x + recur left + recur right", you'd want something like:
x + (countTree p k y) + (countTree p k z)
I'm pretty sure however you actually want to use p, not + hard coded. Using prefix notation, you'd have to rearrange it a bit to something like :
(p (p x (countTree p k y)) (countTree p k z))
Or, you could use backticks to inline the calls to p as #bipll suggested:
x `p` (countTree p k y) `p` (countTree p k z)
A side note, but I'm also pretty sure you want h to be k.

Haskell Memoization Codewars Number of trailing zeros of factorial n

I am trying to solve the Codewars problem called: Number of trailing zeros of N! with Haskell.
I know that I don't need to calculate the factorial to know the trailing zeros and in fact I am just counting how many many numbers are divisible by 5 and how many times for each.
I have written 2 version, one that uses memoization when defactoring a number in order to get how many times is divisible by 5 and another one that do not use memoization.
What surprise me is that the supposed DP approach takes longer than the trivial recursive one. I am probably doing something very stupid in my code.
These are the functions:
zeros x = helperZeros [1..x]
helperZeros :: [Integer] -> Integer
helperZeros = sumArrayTuple . filter (\x -> x `mod` 5 == 0)
sumArrayTuple = foldl (\acc x -> acc + (fastDef x)) 0
data Tree a = Tree (Tree a) a (Tree a)
instance Functor Tree where
fmap f (Tree l m r) = Tree (fmap f l) (f m) (fmap f r)
index :: Tree Integer -> Integer -> Integer
index (Tree _ m _) 0 = m
index (Tree l _ r) n = case (n-1) `divMod` 2 of
(q,0) -> index l q
(q,1) -> index r q
nats = go 0 1
where
go n s = Tree (go l s') n (go r s' )
where
l = n + s
r = l + s
s' = s * 2
fastDef:: Integer -> Integer
fastDef x = trace (show x) index memTreetDef x
memTreetDef = fmap (defact fastDef) nats
defact f n
| n `mod` 5 /= 0 = 0
| otherwise = 1 + f (n `div` 5)
zeros' x = helperZeros' [1..x]
helperZeros' :: [Integer] -> Integer
helperZeros' = sumArrayTuple' . filter (\x -> x `mod` 5 == 0)
sumArrayTuple' = foldl (\acc x -> acc + (def x)) 0
def n
| n `mod` 5 /= 0 = 0
| otherwise = 1 + def (n `div` 5)
What I am trying to memoize is the result of the defact function, for example if I have already calculate defact 200, then it would reuse this result to calculate defact 1000.
I am fairly new to DP in Haskell.
If you are tested your code performance with trace and show here, that is the issue: they are very slow compared to the main code. If not, performance of variants must be about the same.
The def function is a poor candidate for memoization. The average depth of recursion is not very different from 1. The rest of the complexity is reduced to the operation mod, that is, the division that is hardly more expensive than table look up (and division by constant can be optimized to multiplication).

Primitive Recursive function

In A tutorial on universality and expressiveness of fold chapter 4.1, it states that this pattern of recursion
h y [] = f y
h y (x:xs) = g y x xs (h y xs)
is primitive recursion, but I don't understand why the pattern
h [] = v
h (x:xs) = g x (h xs)
is not primitive recursion according to the definition of primitive recursive.
The value of h y' is still based on h y in the h (x:xs) = g x (h xs) if we let y = xs and y' = x:xs.
The primitive recursion scheme is parametric on the choice of f,g
h y [] = f y
h y (x:xs) = g y x xs (h y xs)
That is, we are free to choose f,g as we want, and h will be defined through primitive recursion.
In particular, we can choose
f = \y -> v
g = \y x xs -> g' x z
where g' is any other function picked by us. We then get
h y [] = v
h y (x:xs) = g' x (h y xs)
Now, if we let
h' xs = h () xs
we fix the y argument to an immaterial value so to recover the function in the question. Pedantically, h' is not obtained directly as an instance of the general form, so h' is technically not defined through the primitive recursion scheme seen above (i.e., it is not an instance of that). Sometimes, instead of y we find there many variables y1 .. yn allowing us to pick n=0 and remove the y as we want in this case.

Haskell user defined data types

I want define kind of R data as rational numbers, where R is (denominator,numerator) and I defined as:
data R = R {n::Int,
d::Int} deriving Show
Now I tried to do a function that given two arguments(a list of R and a R) and returns a list with the equivalents of R. I try this, but give me a error of types.
equivalentes' :: [R] -> R -> [R]
equivalentes' [] _ = []
equivalentes' (x:xs) r
| (n x `mod` n r == 0) && (d x `mod` d r == 0) = (R(d n)x): equivalentes' xs r
| otherwise = equivalentes' xs r
My idea is to return something like this:
> equivalentes'[R(2,4),R(3,5),R(4,8)] (R(1,2))
[R (2,4),R (4,8)]
The problem is with the expression
R (d n) x : equivalentes' xs r
And specifically with
d n
The n function has type R -> Int, as does the d function, but you've passed n to d as its argument. Maybe you meant something like
R (d x) x
But since x has type R, this also wouldn't work, so you could have meant
R (d x) (n x)
or something similar.
On a different note, you can't do R (1, 2), because (1, 2) is a tuple of two Ints, not just two separate Ints. you could do instead R 1 2, or uncurry R (1, 2) if you really wanted to use tuples.
In Haskell, both functions and constructors are applied by juxtaposition. For example f x is the function f applied to the argument x. f x y is the function f applied to x, with the result applied to y. You can think of f x y as f applied to two arguments, x and y. You don't need parenthesis for function or constructor application, for example f (x y) means something different - in this case x is being applied to y, and f (x, y) means the function f applied to the tuple (x, y).
For your code, you need to use
R 2 4 instead of R(2,4)
R (n x) (d x) instead of R(d n)x
When we make these syntax changes, equivalentes would be written as
equivalentes :: [R] -> R -> [R]
equivalentes [] _ = []
equivalentes (x:xs) r
| (n x `mod` n r == 0) && (d x `mod` d r == 0) = R (n x) (d x): equivalentes xs r
| otherwise = equivalentes xs r
And your example would be written as
equivalentes [R 2 4,R 3 5,R 4 8] (R 1 2)

Is it possible to define subtraction in Primitive Recursion without a predecessor function?

I have an assignment where I'm writing a bunch of basic Primitive Recursive functions, one of them is subtraction. I was not provided with a definition for predecessor and think it's unlikely I can define it as eval Pred [x] = x-1. Below is my definition of PR and I have several other functions defined such as times, AND, OR, NOT, pow, true, false, and ite. Is it possible to define subtraction with only what I have here? If so can someone give me some guidance. My current thinking is I can do something like, given minus[x,y] recurse y times then return P 2 . If y > x I should return zero. Below is my definition of PR.
import Prelude hiding (pred,and,or,not)
data PR = Z
| S
| P Int
| C PR [PR]
| PR PR PR
deriving Show
eval :: PR -> [Integer] - Integer
eval Z _ = 0
eval S [x] = x+1
eval (P n) xs = nth n xs
eval (C f gs) xs = eval f (map (\g -> eval g xs) gs)
eval (PR g h) (0:xs) = eval g xs
eval (PR g h) (x:xs) = eval h ((x-1) : eval (PR g h) ((x-1):xs) : xs)
nth _ [] = error "nth nil"
nth 0 _ = error "nth index"
nth 1 (x:_) = x
nth (n) (_:xs) = nth (n-1) xs
one = C S [Z]
plus = PR (P 1) (C S [P 2])
Edit; I've found my problem is with defining the correct base case. PR (P 3) (P 1) returns P 1 - 1, which is a step in the right direction, however, I need to recurse P 3 times. I'm thinking something like PR (PR Z (P 3)) (P 1) will do it. That of course is not correct but the idea is to recurse from P 3 to Z with P 1 decrementing each time.
I realized the way to do this is to define predecessor using PR.
pred = PR Z (P 1)
returns x-1 or zero if x = 0.
From there modus can be defined as follows
modus = C modus' [P 2, P 1]
modus' = PR P 1 (C pred [P 2])
Which recursively decrements P 1 P 2 times or until P 1 is equal to zero.

Resources