Comparing odd and even numbers in a list in a pattern

I am trying to do an iterative procedure that compares all odd and even even items in a list. Each odd number must be odd, and each even must be even. The first number must be odd. The result 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 elements with this: (and (odd? (car lst)) (even? (cadr lst)) , but I don't know how to proceed with (cddr lst) .

+4
source share
5 answers

There is one possibility: to go through the entire list, asking whether each element satisfies the corresponding predicate (either even? Or odd? ) And alternates 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 and with a recursive call at the tail position, so it is iterative - and it looks like you thought of a solution. Here's another solution that more clearly shows that this is a truly 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 another solution using logical 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?)))))) 
+5
source

Another option (maybe not a good one).

 (define (odd-even-args? . args) (define (iter lst) (cond ((null? lst) #t) ((null? (cdr lst)) (odd? (car lst))) ((and (odd? (car lst)) (even? (cadr lst))) (iter (cddr lst))) (else #f))) (iter args)) 
+2
source
 (define (range start end) (if (>= start end) nil (cons start (range (+ start 1) end))) (define (odd-even-args? . args) (apply and (map (lambda (value index) (eqv? (even? index) (even? value))) args (range 1 (+ 1 (length args)))))) 
0
source

Why not create a general case as a function of a higher order and realize an odd-even one? as a special case? so you can also implement even-odd ?, or square? -tan ?, or simple? karmic? pretty easy.

 (define (predx?-predy? predx predy) (lambda L (let loop ((lst L) (pred?1 predx) (pred?2 predy)) (if (null? lst) #t (and (pred?1 (car lst)) (loop (cdr lst) pred?2 pred?1)))))) ;;flip preds each recursion (define odd-even? (predx?-predy? odd? even?)) (define even-odd? (predx?-predy? even? odd?)) (define square-tan (predx?-predy? square? tan?)) (define prime?-Carmichael? (predx?-predy? prime? (lambda (x) (and (not (prime? x)) (fermat-prime? x))))) 
0
source

As an exercise, I wrote a version using SRFI-1 and a fold:

 (define (odd-even-args? . xs) (first (fold (lambda (x data) (let ((result (first data)) (count (second data))) (list (and ((if (odd? count) odd? even?) x) result) (+ 1 count)))) '(#t 1) xs))) 
0
source

Source: https://habr.com/ru/post/1486421/


All Articles