[mercury-users] challenge

Henk Vandecasteele Henk.Vandecasteele at cs.kuleuven.ac.be
Mon Sep 28 19:24:44 AEST 1998


Peter Schachte wrote:
> 
> Here's a programming challenge that should be a bit more interesting
> than writing rot13 in Mercury.  Given a type
> 
>         :-type tree(T) ---> empty ; tree(tree(T), T, tree(T)).
> 
> write a predicate
> 
>         :- pred collect_pairs(tree(T), tree(T), list(pair(T))).
>         :- mode collect_pairs(in, in, out).
> 
> collect_pairs(T, U, L) should hold exactly when L is a list of
> corresponding elements of T and U in an inorder traversal of the
> trees.  The catch is that T and U may not be the same shape.  You can
> assume the trees will contain the same numbers of nodes if you like,
> or just collect as many pairs as there are nodes in the smaller tree.
> Take your pick.
> 
> Oh, and no fair turning T and U into lists and then operating on the
> lists.  What I'm looking for is code to traverse two different-shaped
> trees at once.  I speculate that there is no reasonably elegant way to
> do it, but I'd be delighted to be proved wrong.

How about this:

:- module collect_pairs.
:- interface.

:- import_module list.

:- type tree(T) ---> empty ; tree(tree(T), T, tree(T)).
:- type pair(T) ---> (T,T).

:- pred collect_pairs(tree(T)::in, tree(T)::in, list(pair(T))::out) is
semidet.

:- implementation.



collect_pairs(empty, empty, []).
collect_pairs(Tree1, Tree2, List):-
	Tree1 = tree(Left1, El1, Right1),
	Tree2 = tree(Left2, El2, Right2),
	( Left1 = empty ->
	    ( Left2 = empty ->
		List = [(El1, El2)|List2],
		collect_pairs(Right1, Right2, List2);
		Left2 = tree(Left3, El3, Right3),
		collect_pairs(Tree1, tree(Left3,El3,
					  tree(Right3, El2, Right2)),
			      List)
	    );
	    ( Left2 = empty ->
		Left1 = tree(Left4, El4, Right4),
		collect_pairs(tree(Left4, El4,
				   tree(Right4, El1, Right1)),
			      Tree2, List);
		Left1 = tree(Left4, El4, Right4),
		Left2 = tree(Left3, El3, Right3),
		collect_pairs(tree(Left4, El4,
				   tree(Right4, El1, Right1)),
			      tree(Left3, El3,
				   tree(Right3, El2, Right2)),
			      List)
	    )

	).



I hope I understood the question.

Henk





More information about the users mailing list