Reputation: 25
(define is1?
(lambda (tuple)
(if (and (= 2 (length tuple))
(= 1 (- (cadr tuple) (car tuple)))
(list? tuple))
#t
#f)))
(define greenlist?
(lambda (x) (andmap is1? x)))
(greenlist? '((2 4 6) (5 6) (1 2)))
(greenlist? '(3 4 5 6))
The second command: (greenlist? '(3 4 5 6))
returns an error when it should return false.
Instead I get this error:
length: contract violation
expected: list?
given: 3
What should I change in my code so it returns false instead of an error?
Here is the definition of a greenlist:
A greenlist is a non-empty list of pairs of integers where a pair of integers is a list of exactly two integers and where each pair
'( x y)
has the property that y – x = 1.Example:
'((5 6) (3 4) (2 3) (-5 -4))
is a greenlist.
Upvotes: 0
Views: 458
Reputation: 235984
The problem is that the order of the conditions matters: in an and
expression the conditions are evaluated in left-to-right order, if one condition is false
then the other conditions are skipped (short-circuit evaluation).
Your input is a list of lists, so you should test first if the current element is an actual list - otherwise you'll attempt to take the length
of an object which isn't a list (the number 3
in your example), which is an error.
By the way: it's possible to simplify the code, you don't actually need to use an if
, just return the value of the condition:
(define is1?
(lambda (tuple)
(and (list? tuple) ; you must ask this first!
(= 2 (length tuple))
(= 1 (- (cadr tuple) (car tuple))))))
Upvotes: 3