Re: Learning Scheme - critique
- From: Jussi Piitulainen <jpiitula@xxxxxxxxxxxxxxxx>
- Date: 22 Jan 2008 23:37:04 +0200
S. Robert James writes:
;;; The cardinality of the returned set =
;;; product of the cardilaties of each of the n-sets.
(define (cartesian-product. list-of-sets)
(define los list-of-sets)
(if (null? los)
'() ; The null cartesian-product is the empty set
Think again. I believe you are right that the size of the cartesian
product should be the product of the sizes of the sets - but the empty
product is taken to be 1, not 0.
(if (null? other-sets)
(map list first-set)
If you make the empty cartesian product be (()), you don't need this
special case. The right thing just happens.
(if (null? first-set)
'() ; If any of the n-sets are empty, their cartesian-
; product is empty
This special case vanishes if you follow my suggestion below. You can
simply trust `map' to do the right thing with the empty list. (Or you
could still keep this as an optimization, but it does make the code
longer.)
(let
((first-element (car first-set))
(other-elements (cdr first-set)))
(append
(map (lambda (y) (cons first-element y)) (cartesian-
product other-sets))
(cartesian-product (cons other-elements other-
sets)))))))))
That must be the inefficiency you perceived: you compute the cartesian
product of other-sets or more in two branches, recursively. It's like
the use of Fibonacci numbers to teach that recursion is inefficient.
I suggest you turn this around so that the cartesian product of
other-sets is computed just once, and then each element of first-set
is prepended to each element of that. Using a `map' within `map' for
this, the result is a list of lists that needs flattening. This is
best done with a special version of `map', but you can start with
(apply append (map ...))
All comments - be they on the algo, simplicity, conventions, or
style - are appreciated. Two things strike me as akward about it
already - 1. I would think that the algo should be much shorter and
2. tracing it shows the code to calculate things quite inefficiently
- but I'm not sure how to improve it. Any comments appreciated.
I hope my comments above are helpful. In case they are less than
clear, below is my code in rot-13 so as to not spoil all your own fun
too fast. (That special version of `map' I leave to you.)
(qrsvar (cebq frgf)
(vs (ahyy? frgf)
'(())
(yrg ((svefgf (pne frgf))
(erfgf (cebq (pqe frgf))))
(nccyl nccraq
(znc (ynzoqn (r)
(znc (ynzoqn (e)
(pbaf r e))
erfgf))
svefgf)))))
.
- Follow-Ups:
- Re: Learning Scheme - critique
- From: S. Robert James
- Re: Learning Scheme - critique
- References:
- Learning Scheme - critique
- From: S. Robert James
- Learning Scheme - critique
- Prev by Date: Re: help with call/cc
- Next by Date: Re: Learning Scheme - critique
- Previous by thread: Re: Learning Scheme - critique
- Next by thread: Re: Learning Scheme - critique
- Index(es):
Relevant Pages
|