Reputation: 11
I'm new to scheme and trying to learn functions. I want to create a function where I can count all occurrences of the atom "a" in an argument. This is what I have written so far. I'm not sure what to write in the third condition. Please help out.
(define (count-a arg)
(COND
((null? arg) 0)
((eq? arg 'a) 1)
((list? arg) ( ___ + ( ___ count-a arg)))
(else 0)
))
This is the output i want:
(count-a 'a) 1
(count-a 'aa) 0
(count-a '(a)) 1
(count-a '(ab c) 0
(count-a '(a (b c) (c (d a) a) (((a b))))) 5
Upvotes: 1
Views: 145
Reputation: 256
Welcome to Stack Overflow!
Solution:
(define (count-a arg)
(cond ((null? arg) 0)
((not (pair? arg))
(if (equal? arg 'a)
1
0))
;; At this point we know arg is a pair, and we recurse.
(else (+ (count-a (car arg)) (count-a (cdr arg))))))
Test:
Here are the tests you specified, compressed into a single line.
;; Chibi-Scheme REPL - other implementations might look different.
> (map count-a '(a aa (a) (ab c) (a (b c) (c (d a) a) (((a b))))))
(1 0 1 0 4)
You didn't say what you want to happen if arg
is a dotted pair. But let's check it out just for fun.
> (map count-a '((ab . '()) (ab . a) (a . a)))
(0 1 2)
So when I run your last test on my code, it yields 4 where you expected 5. I maintain that my code is correct and your test specification is incorrect, as there are only four instances of 'a
in the argument of count-a
.
Discussion:
You specified in your headline that the thing the count-a
function will be counting is an atom. So you have to check whether arg
is an atom or not. Since Scheme doesn't have an atom?
function, I'll assume that an atom is anything that's not '()
and not a pair. (This is consistent with the atom function of Common Lisp, as well as other Lisp dialects.)
Since your code already deals with arg
being '()
, we only have to deal with arg
being, or not being a pair.
If arg
is not a pair and (equal? arg 'a)
, then (count-a arg)
equals 1. Else, it equals 0.
If arg
is a pair, we can recurse into car arg)
and (cdr arg)
, however deeply nested arg
may be, and increase our count whenever we find an atom that equals a
.
Hope that helps.
Upvotes: 1
Reputation: 48745
(___ + ( ___ count-a arg))
doesn't seem right to me. Remember Scheme is a prefix language. It's (+ 1 2 3)
instead of 1 + 2 + 3
.
In the third one you have two lists parts. eg. '(a a)
so you need to call count-a
on the car
and on the cdr
of the list and add the results together. eg. (count-a '(a a))
should give the same result as (+ (count-a 'a) (count-a '(a))
Good luck
Upvotes: 2