Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare odd and even numbers in a list in scheme

Tags:

scheme

I'm trying make an iterative procedure which compare every odd and every even elements in a list. Every odd number should be odd and every even should be even. First number must be odd. Output should be like this:

(odd-even-args? 1 2 3 4 5) --> #t
(odd-even-args? 1 2 4 4 5) --> #f
(odd-even-args? 1 0 1) --> #t

I tried to compare two element with this: (and (odd? (car lst)) (even? (cadr lst)), but I don't know how to continue with (cddr lst).

like image 820
Ats Avatar asked Mar 23 '23 13:03

Ats


1 Answers

Here's one possibility: traverse all the list, asking if each element satisfies the appropriate predicate (either even? or odd?) and alternate between the predicates:

(define (odd-even-args? . lst)
  (let loop ((lst lst)
             (is-odd? #t))
    (if (null? lst)
        #t
        (and ((if is-odd? odd? even?) (car lst))
             (loop (cdr lst) (not is-odd?))))))

The answer above uses an and with the recursive call in a tail position, so it's iterative - and it's similar to the way you were thinking about the solution. Here's another solution which shows more explicitly that this is indeed an iterative process:

(define (odd-even-args? . lst)
  (let loop ((lst lst)
             (is-odd? #t))
    (cond ((null? lst) #t)
          (((if is-odd? even? odd?) (car lst)) #f)
          (else (loop (cdr lst) (not is-odd?))))))

And yet another solution, using boolean connectors instead of conditional expressions:

(define (odd-even-args? . lst)
  (let loop ((lst lst)
             (is-odd? #t))
    (or (null? lst)
        (and ((if is-odd? odd? even?) (car lst))
             (loop (cdr lst) (not is-odd?))))))
like image 98
Óscar López Avatar answered Apr 01 '23 12:04

Óscar López