Difference between revisions of "99 questions/70B to 73"

From HaskellWiki
Jump to navigation Jump to search
m
 
(6 intermediate revisions by 3 users not shown)
Line 3: Line 3:
 
This is part of [[H-99:_Ninety-Nine_Haskell_Problems|Ninety-Nine Haskell Problems]], based on [https://prof.ti.bfh.ch/hew1/informatik3/prolog/p-99/ Ninety-Nine Prolog Problems].
 
This is part of [[H-99:_Ninety-Nine_Haskell_Problems|Ninety-Nine Haskell Problems]], based on [https://prof.ti.bfh.ch/hew1/informatik3/prolog/p-99/ Ninety-Nine Prolog Problems].
   
== Multiway Trees ==
+
<h2 style="border:none">Multiway Trees</h2>
   
 
A multiway tree is composed of a root element and a (possibly empty) set of successors which are multiway trees themselves. A multiway tree is never empty. The set of successor trees is sometimes called a forest.
 
A multiway tree is composed of a root element and a (possibly empty) set of successors which are multiway trees themselves. A multiway tree is never empty. The set of successor trees is sometimes called a forest.
   
https://prof.ti.bfh.ch/hew1/informatik3/prolog/p-99/p70.gif
+
https://www.ic.unicamp.br/~meidanis/courses/mc336/2009s2/prolog/problemas/p70.gif
   
 
== Problem 70B ==
 
== Problem 70B ==
  +
<div style="border-bottom:1px solid #eee">(*) Check whether a given term represents a multiway tree. <span style="float:right"><small>(no solution needed)</small></span>
 
  +
</div>
(*) Check whether a given term represents a multiway tree.
 
  +
&nbsp;<br>
   
 
In Prolog or Lisp, one writes a predicate to check this.
 
In Prolog or Lisp, one writes a predicate to check this.
Line 49: Line 50:
 
The last is the tree illustrated above.
 
The last is the tree illustrated above.
   
As in problem 54A, all members of this type are multiway trees; there is no use for a predicate to test them.
+
As in Problem 54A, all members of this type are multiway trees; there is no use for a predicate to test them.
  +
   
 
== Problem 70C ==
 
== Problem 70C ==
  +
<div style="border-bottom:1px solid #eee">(*) Count the nodes of a multiway tree. <span style="float:right"><small>[[99 questions/Solutions/70C|Solutions]]</small></span>
 
  +
</div>
(*) Count the nodes of a multiway tree.
 
  +
&nbsp;<br>
   
 
Example in Haskell:
 
Example in Haskell:
   
 
<haskell>
 
<haskell>
Tree> nnodes tree2
+
λ> nnodes tree2
 
2
 
2
 
</haskell>
 
</haskell>
   
[[99 questions/Solutions/70C | Solutions]]
 
   
 
== Problem 70 ==
 
== Problem 70 ==
  +
<div style="border-bottom:1px solid #eee">(**) Construct a multiway tree from a node string. <span style="float:right"><small>[[99 questions/Solutions/70|Solutions]]</small></span>
 
  +
</div>
(**) Tree construction from a node string.
 
  +
&nbsp;<br>
   
 
We suppose that the nodes of a multiway tree contain single characters. In the depth-first order sequence of its nodes, a special character ^ has been inserted whenever, during the tree traversal, the move is a backtrack to the previous level.
 
We suppose that the nodes of a multiway tree contain single characters. In the depth-first order sequence of its nodes, a special character ^ has been inserted whenever, during the tree traversal, the move is a backtrack to the previous level.
Line 72: Line 75:
 
By this rule, the tree below (<tt>tree5</tt>) is represented as: <tt>afg^^c^bd^e^^^</tt>
 
By this rule, the tree below (<tt>tree5</tt>) is represented as: <tt>afg^^c^bd^e^^^</tt>
   
https://prof.ti.bfh.ch/hew1/informatik3/prolog/p-99/p70.gif
+
https://www.ic.unicamp.br/~meidanis/courses/mc336/2009s2/prolog/problemas/p70.gif
   
 
Define the syntax of the string and write a predicate tree(String,Tree) to construct the Tree when the String is given.
 
Define the syntax of the string and write a predicate tree(String,Tree) to construct the Tree when the String is given.
 
Make your predicate work in both directions.
 
Make your predicate work in both directions.
   
  +
Example in Haskell:
[[99 questions/Solutions/70 | Solutions]]
 
   
  +
<haskell>
  +
λ> stringToTree "afg^^c^bd^e^^^"
  +
Node 'a' [Node 'f' [Node 'g' []],Node 'c' [],Node 'b' [Node 'd' [],Node 'e' []]]
   
  +
λ> treeToString (Node 'a' [Node 'f' [Node 'g' []],Node 'c' [],Node 'b' [Node 'd' [],Node 'e' []]])
== Problem 71 ==
 
  +
"afg^^c^bd^e^^^"
   
  +
</haskell>
(*) Determine the internal path length of a tree.
 
  +
  +
 
== Problem 71 ==
  +
<div style="border-bottom:1px solid #eee">(*) Determine internal path length of multiway tree. <span style="float:right"><small>[[99 questions/Solutions/71|Solutions]]</small></span>
  +
</div>
  +
&nbsp;<br>
   
 
We define the internal path length of a multiway tree as the total sum of the path lengths from the root to all nodes of the tree. By this definition, <tt>tree5</tt> has an internal path length of 9.
 
We define the internal path length of a multiway tree as the total sum of the path lengths from the root to all nodes of the tree. By this definition, <tt>tree5</tt> has an internal path length of 9.
Line 89: Line 102:
   
 
<haskell>
 
<haskell>
Tree> ipl tree5
+
λ> ipl tree5
 
9
 
9
Tree> ipl tree4
+
λ> ipl tree4
 
2
 
2
 
</haskell>
 
</haskell>
 
[[99 questions/Solutions/71 | Solutions]]
 
   
   
 
== Problem 72 ==
 
== Problem 72 ==
  +
<div style="border-bottom:1px solid #eee">(*) Construct bottom-up order sequence of multiway tree nodes. <span style="float:right"><small>[[99 questions/Solutions/72|Solutions]]</small></span>
 
  +
</div>
(*) Construct the bottom-up order sequence of the tree nodes.
 
  +
&nbsp;<br>
   
 
Write a predicate bottom_up(Tree,Seq) which constructs the bottom-up sequence of the nodes of the multiway tree Tree.
 
Write a predicate bottom_up(Tree,Seq) which constructs the bottom-up sequence of the nodes of the multiway tree Tree.
Line 107: Line 119:
   
 
<haskell>
 
<haskell>
Tree> bottom_up tree5
+
λ> bottom_up tree5
 
"gfcdeba"
 
"gfcdeba"
 
</haskell>
 
</haskell>
 
[[99 questions/Solutions/72 | Solutions]]
 
   
   
 
== Problem 73 ==
 
== Problem 73 ==
  +
<div style="border-bottom:1px solid #eee">(**) Lisp-like multiway tree representation. <span style="float:right"><small>[[99 questions/Solutions/73|Solutions]]</small></span>
 
  +
</div>
(**) Lisp-like tree representation.
 
  +
&nbsp;<br>
   
 
There is a particular notation for multiway trees in Lisp. Lisp is a prominent functional programming language, which is used primarily for artificial intelligence problems. As such it is one of the main competitors of Prolog. In Lisp almost everything is a list, just as in Prolog everything is a term.
 
There is a particular notation for multiway trees in Lisp. Lisp is a prominent functional programming language, which is used primarily for artificial intelligence problems. As such it is one of the main competitors of Prolog. In Lisp almost everything is a list, just as in Prolog everything is a term.
Line 122: Line 133:
 
The following pictures show how multiway tree structures are represented in Lisp.
 
The following pictures show how multiway tree structures are represented in Lisp.
   
https://prof.ti.bfh.ch/hew1/informatik3/prolog/p-99/p73.png
+
https://www.ic.unicamp.br/~meidanis/courses/mc336/2009s2/prolog/problemas/p73.png
   
 
Note that in the "lispy" notation a node with successors (children) in the tree is always the first element in a list, followed by its children. The "lispy" representation of a multiway tree is a sequence of atoms and parentheses '(' and ')', which we shall collectively call "tokens". We can represent this sequence of tokens as a Prolog list; e.g. the lispy expression (a (b c)) could be represented as the Prolog list ['(', a, '(', b, c, ')', ')']. Write a predicate tree_ltl(T,LTL) which constructs the "lispy token list" LTL if the tree is given as term T in the usual Prolog notation.
 
Note that in the "lispy" notation a node with successors (children) in the tree is always the first element in a list, followed by its children. The "lispy" representation of a multiway tree is a sequence of atoms and parentheses '(' and ')', which we shall collectively call "tokens". We can represent this sequence of tokens as a Prolog list; e.g. the lispy expression (a (b c)) could be represented as the Prolog list ['(', a, '(', b, c, ')', ')']. Write a predicate tree_ltl(T,LTL) which constructs the "lispy token list" LTL if the tree is given as term T in the usual Prolog notation.
Line 131: Line 142:
   
 
<haskell>
 
<haskell>
Tree> display lisp tree1
+
λ> display lisp tree1
 
"a"
 
"a"
Tree> display lisp tree2
+
λ> display lisp tree2
 
"(a b)"
 
"(a b)"
Tree> display lisp tree3
+
λ> display lisp tree3
 
"(a (b c))"
 
"(a (b c))"
Tree> display lisp tree4
+
λ> display lisp tree4
 
"(b d e)"
 
"(b d e)"
Tree> display lisp tree5
+
λ> display lisp tree5
 
"(a (f g) c (b d e))"
 
"(a (f g) c (b d e))"
 
</haskell>
 
</haskell>
   
 
As a second, even more interesting exercise try to rewrite tree_ltl/2 in a way that the inverse conversion is also possible.
 
As a second, even more interesting exercise try to rewrite tree_ltl/2 in a way that the inverse conversion is also possible.
 
[[99 questions/Solutions/73 | Solutions]]
 
   
   

Latest revision as of 05:50, 11 June 2023


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

Multiway Trees

A multiway tree is composed of a root element and a (possibly empty) set of successors which are multiway trees themselves. A multiway tree is never empty. The set of successor trees is sometimes called a forest.

p70.gif

Problem 70B

(*) Check whether a given term represents a multiway tree. (no solution needed)

 

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

Example in Prolog:

?- istree(t(a,[t(f,[t(g,[])]),t(c,[]),t(b,[t(d,[]),t(e,[])])])).
Yes

In Haskell, we define multiway trees as a datatype, as in the module Data.Tree:

data Tree a = Node a [Tree a]
        deriving (Eq, Show)

Some example trees:

tree1 = Node 'a' []

tree2 = Node 'a' [Node 'b' []]

tree3 = Node 'a' [Node 'b' [Node 'c' []]]

tree4 = Node 'b' [Node 'd' [], Node 'e' []]

tree5 = Node 'a' [
                Node 'f' [Node 'g' []],
                Node 'c' [],
                Node 'b' [Node 'd' [], Node 'e' []]
                ]

The last is the tree illustrated above.

As in Problem 54A, all members of this type are multiway trees; there is no use for a predicate to test them.


Problem 70C

(*) Count the nodes of a multiway tree. Solutions

 

Example in Haskell:

λ> nnodes tree2
2


Problem 70

(**) Construct a multiway tree from a node string. Solutions

 

We suppose that the nodes of a multiway tree contain single characters. In the depth-first order sequence of its nodes, a special character ^ has been inserted whenever, during the tree traversal, the move is a backtrack to the previous level.

By this rule, the tree below (tree5) is represented as: afg^^c^bd^e^^^

p70.gif

Define the syntax of the string and write a predicate tree(String,Tree) to construct the Tree when the String is given. Make your predicate work in both directions.

Example in Haskell:

λ> stringToTree "afg^^c^bd^e^^^"
Node 'a' [Node 'f' [Node 'g' []],Node 'c' [],Node 'b' [Node 'd' [],Node 'e' []]]

λ> treeToString (Node 'a' [Node 'f' [Node 'g' []],Node 'c' [],Node 'b' [Node 'd' [],Node 'e' []]])
"afg^^c^bd^e^^^"


Problem 71

(*) Determine internal path length of multiway tree. Solutions

 

We define the internal path length of a multiway tree as the total sum of the path lengths from the root to all nodes of the tree. By this definition, tree5 has an internal path length of 9.

Example in Haskell:

λ> ipl tree5
9
λ> ipl tree4
2


Problem 72

(*) Construct bottom-up order sequence of multiway tree nodes. Solutions

 

Write a predicate bottom_up(Tree,Seq) which constructs the bottom-up sequence of the nodes of the multiway tree Tree.

Example in Haskell:

λ> bottom_up tree5
"gfcdeba"


Problem 73

(**) Lisp-like multiway tree representation. Solutions

 

There is a particular notation for multiway trees in Lisp. Lisp is a prominent functional programming language, which is used primarily for artificial intelligence problems. As such it is one of the main competitors of Prolog. In Lisp almost everything is a list, just as in Prolog everything is a term.

The following pictures show how multiway tree structures are represented in Lisp.

p73.png

Note that in the "lispy" notation a node with successors (children) in the tree is always the first element in a list, followed by its children. The "lispy" representation of a multiway tree is a sequence of atoms and parentheses '(' and ')', which we shall collectively call "tokens". We can represent this sequence of tokens as a Prolog list; e.g. the lispy expression (a (b c)) could be represented as the Prolog list ['(', a, '(', b, c, ')', ')']. Write a predicate tree_ltl(T,LTL) which constructs the "lispy token list" LTL if the tree is given as term T in the usual Prolog notation.

(The Prolog example given is incorrect.)

Example in Haskell:

λ> display lisp tree1
"a"
λ> display lisp tree2
"(a b)"
λ> display lisp tree3
"(a (b c))"
λ> display lisp tree4
"(b d e)"
λ> display lisp tree5
"(a (f g) c (b d e))"

As a second, even more interesting exercise try to rewrite tree_ltl/2 in a way that the inverse conversion is also possible.