-
Notifications
You must be signed in to change notification settings - Fork 0
/
ex_2_20.clj
50 lines (48 loc) · 1.66 KB
/
ex_2_20.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
(ns sicp.chapter-2.part-2.ex-2-20
(:require
[sicp.chapter-2.part-2.book-2-2 :as b22]
[sicp.misc :as m]))
; Exercise 2.20
;
; The procedures +, *, and list take arbitrary numbers of arguments.
; One way to define such procedures is to use define with dotted-tail notation.
; In a procedure definition, a parameter list that has a dot before the last parameter name
; indicates that, when the procedure is called, the initial parameters (if any) will
; have as values the initial arguments, as usual, but the final parameter’s value will be
; a list of any remaining arguments.
;
; For instance, given the definition
; (define (f x y . z) ⟨body⟩)
; the procedure f can be called with two or more arguments.
;
; If we evaluate
; (f 1 2 3 4 5 6)
; then in the body of f, x will be 1, y will be 2, and z will be the list (3 4 5 6).
;
; Given the definition
; (define (g . w) ⟨body⟩)
; the procedure g can be called with zero or more arguments.
;
; If we evaluate
; (g 1 2 3 4 5 6)
; then in the body of g, w will be the list (1 2 3 4 5 6).
;
; Use this notation to write a procedure same-parity that takes one or more integers and returns
; a list of all the arguments that have the same even-odd parity as the first argument.
;
; For example,
; (same-parity 1 2 3 4 5 6 7)
; (1 3 5 7)
;
; (same-parity 2 3 4 5 6 7)
; (2 4 6)
(defn same-parity
[base & check-list]
(letfn [(iter
[rest result]
(if (m/list-empty? rest)
result
(if (= (mod (m/car rest) 2) (mod base 2))
(iter (m/cdr rest) (b22/append result (list (m/car rest))))
(iter (m/cdr rest) result))))]
(iter check-list (list base))))