# Difference between revisions of "99 questions/54A to 60"

RossPaterson (talk | contribs) m (new URL) |
(moved solutions to subpages of 99 questions/Solutions and cleaned up code formatting) |
||

Line 18: | Line 18: | ||

Example in Lisp: | Example in Lisp: | ||

+ | |||

<pre> | <pre> | ||

* (istree (a (b nil nil) nil)) | * (istree (a (b nil nil) nil)) | ||

Line 25: | Line 26: | ||

</pre> | </pre> | ||

− | + | [[99 questions/Solutions/54A | Solutions]] | |

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

== Problem 55 == | == Problem 55 == | ||

Line 61: | Line 38: | ||

Example: | Example: | ||

+ | |||

<pre> | <pre> | ||

* cbal-tree(4,T). | * cbal-tree(4,T). | ||

Line 69: | Line 47: | ||

Example in Haskell, whitespace and "comment diagrams" added for clarity and exposition: | Example in Haskell, whitespace and "comment diagrams" added for clarity and exposition: | ||

− | < | + | |

+ | <haskell> | ||

*Main> cbalTree 4 | *Main> cbalTree 4 | ||

[ | [ | ||

Line 112: | Line 91: | ||

(Branch 'x' Empty Empty) | (Branch 'x' Empty Empty) | ||

] | ] | ||

− | </ | + | </haskell> |

− | + | [[99 questions/Solutions/55 | Solutions]] | |

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

== Problem 56 == | == Problem 56 == | ||

Line 130: | Line 103: | ||

Example in Haskell: | Example in Haskell: | ||

− | < | + | |

+ | <haskell> | ||

*Main> symmetric (Branch 'x' (Branch 'x' Empty Empty) Empty) | *Main> symmetric (Branch 'x' (Branch 'x' Empty Empty) Empty) | ||

False | False | ||

*Main> symmetric (Branch 'x' (Branch 'x' Empty Empty) (Branch 'x' Empty Empty)) | *Main> symmetric (Branch 'x' (Branch 'x' Empty Empty) (Branch 'x' Empty Empty)) | ||

True | True | ||

− | </ | + | </haskell> |

− | + | [[99 questions/Solutions/56 | Solutions]] | |

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

== Problem 57 == | == Problem 57 == | ||

Line 154: | Line 121: | ||

Example: | Example: | ||

+ | |||

<pre> | <pre> | ||

* construct([3,2,5,7,1],T). | * construct([3,2,5,7,1],T). | ||

Line 162: | Line 130: | ||

Example: | Example: | ||

+ | |||

<pre> | <pre> | ||

* test-symmetric([5,3,18,1,4,12,21]). | * test-symmetric([5,3,18,1,4,12,21]). | ||

Line 170: | Line 139: | ||

Example in Haskell: | Example in Haskell: | ||

− | < | + | |

+ | <haskell> | ||

*Main> construct [3, 2, 5, 7, 1] | *Main> construct [3, 2, 5, 7, 1] | ||

Branch 3 (Branch 2 (Branch 1 Empty Empty) Empty) (Branch 5 Empty (Branch 7 Empty Empty)) | Branch 3 (Branch 2 (Branch 1 Empty Empty) Empty) (Branch 5 Empty (Branch 7 Empty Empty)) | ||

Line 177: | Line 147: | ||

*Main> symmetric . construct $ [3, 2, 5, 7, 1] | *Main> symmetric . construct $ [3, 2, 5, 7, 1] | ||

True | True | ||

− | </ | + | </haskell> |

− | + | [[99 questions/Solutions/57 | Solutions]] | |

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

== Problem 58 == | == Problem 58 == | ||

Line 200: | Line 159: | ||

Example: | Example: | ||

+ | |||

<pre> | <pre> | ||

* sym-cbal-trees(5,Ts). | * sym-cbal-trees(5,Ts). | ||

Line 206: | Line 166: | ||

Example in Haskell: | Example in Haskell: | ||

− | < | + | |

+ | <haskell> | ||

*Main> symCbalTrees 5 | *Main> symCbalTrees 5 | ||

[Branch 'x' (Branch 'x' Empty (Branch 'x' Empty Empty)) (Branch 'x' (Branch 'x' Empty Empty) Empty),Branch 'x' (Branch 'x' (Branch 'x' Empty Empty) Empty) (Branch 'x' Empty (Branch 'x' Empty Empty))] | [Branch 'x' (Branch 'x' Empty (Branch 'x' Empty Empty)) (Branch 'x' (Branch 'x' Empty Empty) Empty),Branch 'x' (Branch 'x' (Branch 'x' Empty Empty) Empty) (Branch 'x' Empty (Branch 'x' Empty Empty))] | ||

− | </ | + | </haskell> |

+ | |||

+ | [[99 questions/Solutions/58 | Solutions]] | ||

− | |||

− | |||

− | |||

− | |||

== Problem 59 == | == Problem 59 == | ||

Line 223: | Line 182: | ||

Example: | Example: | ||

+ | |||

<pre> | <pre> | ||

?- hbal_tree(3,T). | ?- hbal_tree(3,T). | ||

Line 231: | Line 191: | ||

Example in Haskell: | Example in Haskell: | ||

− | < | + | |

+ | <haskell> | ||

*Main> take 4 $ hbalTree 'x' 3 | *Main> take 4 $ hbalTree 'x' 3 | ||

[Branch 'x' (Branch 'x' Empty Empty) (Branch 'x' Empty (Branch 'x' Empty Empty)), | [Branch 'x' (Branch 'x' Empty Empty) (Branch 'x' Empty (Branch 'x' Empty Empty)), | ||

Line 237: | Line 198: | ||

Branch 'x' (Branch 'x' Empty Empty) (Branch 'x' (Branch 'x' Empty Empty) (Branch 'x' Empty Empty)), | Branch 'x' (Branch 'x' Empty Empty) (Branch 'x' (Branch 'x' Empty Empty) (Branch 'x' Empty Empty)), | ||

Branch 'x' (Branch 'x' Empty (Branch 'x' Empty Empty)) (Branch 'x' Empty Empty)] | Branch 'x' (Branch 'x' Empty (Branch 'x' Empty Empty)) (Branch 'x' Empty Empty)] | ||

− | </ | + | </haskell> |

+ | |||

+ | [[99 questions/Solutions/59 | Solutions]] | ||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

== Problem 60 == | == Problem 60 == | ||

(**) Construct height-balanced binary trees with a given number of nodes | (**) Construct height-balanced binary trees with a given number of nodes | ||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | + | Consider a height-balanced binary tree of height H. What is the maximum number of nodes it can contain? | |

− | |||

− | + | Clearly, MaxN = 2**H - 1. However, what is the minimum number MinN? This question is more difficult. Try to find a recursive statement and turn it into a function <hask>minNodes</hask> that returns the minimum number of nodes in a height-balanced binary tree of height H. | |

− | Find out how many height-balanced trees exist for N = 15. | + | On the other hand, we might ask: what is the maximum height H a height-balanced binary tree with N nodes can have? Write a function <hask>maxHeight</hask> that computes this. |

+ | |||

+ | Now, we can attack the main problem: construct all the height-balanced binary trees with a given nuber of nodes. Find out how many height-balanced trees exist for N = 15. | ||

Example in Prolog: | Example in Prolog: | ||

+ | |||

<pre> | <pre> | ||

?- count_hbal_trees(15,C). | ?- count_hbal_trees(15,C). | ||

Line 293: | Line 223: | ||

Example in Haskell: | Example in Haskell: | ||

− | < | + | |

+ | <haskell> | ||

*Main> length $ hbalTreeNodes 'x' 15 | *Main> length $ hbalTreeNodes 'x' 15 | ||

1553 | 1553 | ||

Line 301: | Line 232: | ||

[Branch 'x' Empty (Branch 'x' Empty Empty),Branch 'x' (Branch 'x' Empty Empty) Empty], | [Branch 'x' Empty (Branch 'x' Empty Empty),Branch 'x' (Branch 'x' Empty Empty) Empty], | ||

[Branch 'x' (Branch 'x' Empty Empty) (Branch 'x' Empty Empty)]] | [Branch 'x' (Branch 'x' Empty Empty) (Branch 'x' Empty Empty)]] | ||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

</haskell> | </haskell> | ||

− | |||

− | |||

− | |||

− | |||

− | |||

− | + | [[99 questions/Solutions/60 | Solutions]] | |

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

− | |||

[[Category:Tutorials]] | [[Category:Tutorials]] |

## Revision as of 21:48, 13 July 2010

This is part of Ninety-Nine Haskell Problems, based on Ninety-Nine Prolog Problems.

If you want to work on one of these, put your name in the block so we know someone's working on it. Then, change n in your block to the appropriate problem number, and fill in the <Problem description>,<example in lisp>,<example in Haskell>,<solution in haskell> and <description of implementation> fields.

## Binary trees

A binary tree is either empty or it is composed of a root element and two successors, which are binary trees themselves.

## Problem 54A

(*) Check whether a given term represents a binary tree

In Prolog or Lisp, one writes a predicate to do this.

Example in Lisp:

* (istree (a (b nil nil) nil)) T * (istree (a (b nil nil))) NIL

## Problem 55

(**) Construct completely balanced binary trees

In a completely balanced binary tree, the following property holds for every node: The number of nodes in its left subtree and the number of nodes in its right subtree are almost equal, which means their difference is not greater than one.

Write a function cbal-tree to construct completely balanced binary trees for a given number of nodes. The predicate should generate all solutions via backtracking. Put the letter 'x' as information into all nodes of the tree.

Example:

* cbal-tree(4,T). T = t(x, t(x, nil, nil), t(x, nil, t(x, nil, nil))) ; T = t(x, t(x, nil, nil), t(x, t(x, nil, nil), nil)) ; etc......No

Example in Haskell, whitespace and "comment diagrams" added for clarity and exposition:

```
*Main> cbalTree 4
[
-- permutation 1
-- x
-- / \
-- x x
-- \
-- x
Branch 'x' (Branch 'x' Empty Empty)
(Branch 'x' Empty
(Branch 'x' Empty Empty)),
-- permutation 2
-- x
-- / \
-- x x
-- /
-- x
Branch 'x' (Branch 'x' Empty Empty)
(Branch 'x' (Branch 'x' Empty Empty)
Empty),
-- permutation 3
-- x
-- / \
-- x x
-- \
-- x
Branch 'x' (Branch 'x' Empty
(Branch 'x' Empty Empty))
(Branch 'x' Empty Empty),
-- permutation 4
-- x
-- / \
-- x x
-- /
-- x
Branch 'x' (Branch 'x' (Branch 'x' Empty Empty)
Empty)
(Branch 'x' Empty Empty)
]
```

## Problem 56

(**) Symmetric binary trees

Let us call a binary tree symmetric if you can draw a vertical line through the root node and then the right subtree is the mirror image of the left subtree. Write a predicate symmetric/1 to check whether a given binary tree is symmetric. Hint: Write a predicate mirror/2 first to check whether one tree is the mirror image of another. We are only interested in the structure, not in the contents of the nodes.

Example in Haskell:

```
*Main> symmetric (Branch 'x' (Branch 'x' Empty Empty) Empty)
False
*Main> symmetric (Branch 'x' (Branch 'x' Empty Empty) (Branch 'x' Empty Empty))
True
```

## Problem 57

(**) Binary search trees (dictionaries)

Use the predicate add/3, developed in chapter 4 of the course, to write a predicate to construct a binary search tree from a list of integer numbers.

Example:

* construct([3,2,5,7,1],T). T = t(3, t(2, t(1, nil, nil), nil), t(5, nil, t(7, nil, nil)))

Then use this predicate to test the solution of the problem P56.

Example:

* test-symmetric([5,3,18,1,4,12,21]). Yes * test-symmetric([3,2,5,7,1]). No

Example in Haskell:

```
*Main> construct [3, 2, 5, 7, 1]
Branch 3 (Branch 2 (Branch 1 Empty Empty) Empty) (Branch 5 Empty (Branch 7 Empty Empty))
*Main> symmetric . construct $ [5, 3, 18, 1, 4, 12, 21]
True
*Main> symmetric . construct $ [3, 2, 5, 7, 1]
True
```

## Problem 58

(**) Generate-and-test paradigm

Apply the generate-and-test paradigm to construct all symmetric, completely balanced binary trees with a given number of nodes.

Example:

* sym-cbal-trees(5,Ts). Ts = [t(x, t(x, nil, t(x, nil, nil)), t(x, t(x, nil, nil), nil)), t(x, t(x, t(x, nil, nil), nil), t(x, nil, t(x, nil, nil)))]

Example in Haskell:

```
*Main> symCbalTrees 5
[Branch 'x' (Branch 'x' Empty (Branch 'x' Empty Empty)) (Branch 'x' (Branch 'x' Empty Empty) Empty),Branch 'x' (Branch 'x' (Branch 'x' Empty Empty) Empty) (Branch 'x' Empty (Branch 'x' Empty Empty))]
```

## Problem 59

(**) Construct height-balanced binary trees

In a height-balanced binary tree, the following property holds for every node: The height of its left subtree and the height of its right subtree are almost equal, which means their difference is not greater than one.

Example:

?- hbal_tree(3,T). T = t(x, t(x, t(x, nil, nil), t(x, nil, nil)), t(x, t(x, nil, nil), t(x, nil, nil))) ; T = t(x, t(x, t(x, nil, nil), t(x, nil, nil)), t(x, t(x, nil, nil), nil)) ; etc......No

Example in Haskell:

```
*Main> take 4 $ hbalTree 'x' 3
[Branch 'x' (Branch 'x' Empty Empty) (Branch 'x' Empty (Branch 'x' Empty Empty)),
Branch 'x' (Branch 'x' Empty Empty) (Branch 'x' (Branch 'x' Empty Empty) Empty),
Branch 'x' (Branch 'x' Empty Empty) (Branch 'x' (Branch 'x' Empty Empty) (Branch 'x' Empty Empty)),
Branch 'x' (Branch 'x' Empty (Branch 'x' Empty Empty)) (Branch 'x' Empty Empty)]
```

## Problem 60

(**) Construct height-balanced binary trees with a given number of nodes

Consider a height-balanced binary tree of height H. What is the maximum number of nodes it can contain?

Clearly, MaxN = 2**H - 1. However, what is the minimum number MinN? This question is more difficult. Try to find a recursive statement and turn it into a function `minNodes`

that returns the minimum number of nodes in a height-balanced binary tree of height H.

On the other hand, we might ask: what is the maximum height H a height-balanced binary tree with N nodes can have? Write a function `maxHeight`

that computes this.

Now, we can attack the main problem: construct all the height-balanced binary trees with a given nuber of nodes. Find out how many height-balanced trees exist for N = 15.

Example in Prolog:

?- count_hbal_trees(15,C). C = 1553

Example in Haskell:

```
*Main> length $ hbalTreeNodes 'x' 15
1553
*Main> map (hbalTreeNodes 'x') [0,1,2,3]
[[Empty],
[Branch 'x' Empty Empty],
[Branch 'x' Empty (Branch 'x' Empty Empty),Branch 'x' (Branch 'x' Empty Empty) Empty],
[Branch 'x' (Branch 'x' Empty Empty) (Branch 'x' Empty Empty)]]
```