[plt-scheme] Processing lists

From: Stephen Bloch (sbloch at adelphi.edu)
Date: Thu Mar 5 22:20:22 EST 2009

On Mar 5, 2009, at 9:30 PM, aditya shukla wrote:

> Thanks for the help guys , I did it like this.
>
> ;question in a given list find out how many times  a symbol occurs  
> in the list.
> ;contract : fun-with-lists s-list * symbol -> number
> ;purpose : this function takes an s-list and a symbol as input and  
> finds out how many times the symbol occurs in the list.
> ;examples 'a -> () =0 , ('a) =1 , ('b) = 0 , ('b 'c 'a 'a) = 2 ,  
> ('b 'c 'd) =0
> ;template (define fun-with-lists (lambda s-list sym) (cond [(empty?  
> s-list)] [ else (first s-list) fun-with-lists(rest s-list])))
> (define fun-with-lists (lambda (s-list sym )
>                          (cond
>                            [(empty? s-list) 0]
>                            [else (+( more-fun-with-lists(first s- 
> list) sym) ( fun-with-lists(rest s-list) sym))])))
>
> ;contract more-fun with lists (symbol * symbol -> number)
> ;purpose : this function returns 1 if the (first s-list) = sym  
> otherwise 0
> (define more-fun-with-lists (lambda (sym1 sym2)
>                               (cond
>                                 [(symbol=? sym1 sym2) 1]
>                                 [else 0])))
>
> Earlier i was thinking of having  a counter which i would increment  
> whenever an occurrence is found  .Any suggestions on how to think  
> in more of a functional paradigm.

You've got it.  If you prefer, you could put the "(cond  
[(symbol=? ..." directly inside fun-with-lists rather than writing a  
separate function for it, but what you've done is fine too.

Here's one of my favorite exercises along these lines.

The town of Schemeville needs a new computerized voting system. In an  
early version of the system, we assume there are exactly 4 voters  
(we’ll see later how to handle an arbitrary number of voters).
Develop a function count-votes-4 that takes in five strings. The  
first is the name of a candidate, and the other four are votes which  
might or might not be for that candidate. The function should return  
how many of the votes are for the specified candidate. For example,

(check-expect
(count-votes-4 "Anne" "Bob" "Charlie" "Bob" "Hortense") 0)
; since there are no votes for Anne
(check-expect
(count-votes-4 "Anne" "Bob" "Anne" "Phil" "Charlie") 1)
(check-expect
(count-votes-4 "Anne" "Anne" "Bob" "Anne" "Mary") 2)
(check-expect
(count-votes-4 "Bob" "Anne" "Bob" "Charlie" "Bob") 2)

Students with previous experience in imperative languages try to do  
this with a counter initialized to zero, and four conditionals that  
each increment it.  The functional approach is more similar to what  
you wrote above, and is shorter and simpler.

Stephen Bloch
sbloch at adelphi.edu

Posted on the users mailing list.