Racket count occurrences using `map` - scheme

Write a Racket function count-occurrences that consumes two lists of symbols and produces a list of
natural numbers measuring how many times items in the first list occur in the second list. For example:
(count-occurrences (list 'a 'b 'a 'q) (list 'r 'a 'b 'e 'b 'g))
=> (list 1 2 1 0)
I've been struggling with this question - how do I use map to do it, since for this question it's specified we can't use recursion.
My original idea was to do the following:
(define (count-occurrences los1 los2)
(map
(length (filter (lambda (x) (symbol=? x (first los1))) los2))
los1))
but using length here can only get us the number 'a occurred, instead of going into recursion. and for abstract functions there can only be one argument for the inside function, so I'm totally lost.

If ... x ... is an open formula, i.e. an expression which references an unbound variable x, wrapping it in a lambda form makes it a function in x, like so:
(lambda (x) ... x ... )
where x becomes bound by that lambda form; a parameter to this so called lambda function, which is to say, an anonymous function introduced by a lambda form.
So, the solution for your troubles is quite simple: recognize that
(length
(filter (lambda (x)
(symbol=? x (first los1)))
los2))
should actually be
(length
(filter (lambda (x)
(symbol=? x y))
los2))
where y refers to each of the elements of los1 in turn, not just the first one; and that it is then an open formula in y – that is to say, y is unbound, free, there. So we must capture it, and make it bound, by ... yes, enclosing this expression in a lambda form, thereby making it a function in y! Like so:
(lambda (y)
(length
(filter (lambda (x)
(symbol=? x y))
los2)))
And this is what gets mapped over los1.
With this simple tweak, your code becomes a correct, working function definition.

Does this fit your requirements and restrictions?
(define (count-occurrences lst1 lst2)
(map (lambda (e1)
(count (lambda (e2) (eq? e1 e2))
lst2))
lst1))

A good way to keep track of keys and values is with a hash-table. While it is possible to write count-occurrences using map and passing a lambda, being explicit may make it easier to see what is going on.
;;; list list -> list
;;;
(define (count-occurrences keys values)
;; Create data structure
(define ht (make-hash))
;; Initialize data structure with keys
;; Set the value of each key to zero
;; Since we have not started counting
(for ([k keys])
(hash-set! ht k 0))
;; Iterate over values and
;; Increment hash table if
;; When value is a key
(for ([v values])
(if (hash-has-key? ht v)
(hash-set! ht v (+ (hash-ref ht v) 1))
null))
;; Iterate over keys and
;; Create list of values
(for/list ([k keys])
(hash-ref ht k)))
Since recursion is prohibited, explicitly looping may make for more maintainable/readable code than an implicit loop. Besides, the variations of for are worth knowing. Hash tables have the advantage that duplicate keys read the same value and there is no need to track the same key twice.
One of the engineering advantages of using for rather than map is that it is easier to reason about the running time. The running time for this code is 2m + n where m is keys and n is values. Solutions using map will typically be m * n. There's nothing inherently wrong with that. But it is worth recognizing.

Related

How to use the built-in function filter with lambda in Scheme programming?

"Implement unique, which takes in a list s and returns a new list containing the same elements as s with duplicates removed."
scm> (unique '(1 2 1 3 2 3 1))
(1 2 3)
scm> (unique '(a b c a a b b c))
(a b c)
What I've tried so far is:
(define (unique s)
(cond
((null? s) nil)
(else (cons (car s)(filter ?)
This question required to use the built-in filter function. The general format of filter function is (filter predicate lst), and I was stuck on the predicate part. I am thinking it should be a lambda function. Also, what should I do to solve this question recursively?
(filter predicate list) returns a new list obtained by eliminating all the elements of the list that does not satisfy the predicate. So if you get the first element of the list, to eliminate its duplicates, if they exists, you could simply eliminate from the rest of the list all the elements equal to it, something like:
(filter
(lambda (x) (not (eqv? x (first lst)))) ; what to maintain: all the elements different from (first lst)
(rest lst)) ; the list from which to eleminate it
for instance:
(filter (lambda (x) (not (eqv? x 1))) '(2 1 3 2 1 4))
produces (2 3 2 1 4), eliminating all the occurrences of 1.
Then if you cons the first element with the list resulting from the filter, you are sure that there is only a “copy” of that element in the resulting list.
The last step needed to write your function is to repeat recursively this process. In general, when you have to apply a recursive process, you have to find a terminal case, in which the result of the function can be immediately given (as the empty list for lists), and the general case, in which you express the solution assuming that you have already available the function for a “smaller” input (for instance a list with a lesser number of elements).
Consider this definition:
define (unique s)
(if (null? s)
'()
(cons (first s)
(filter
(lambda (x) (not (eq? x (first s))))
(unique (rest s))))))
(rest s) is a list which has shorter than s. So you can apply unique to it and find a list without duplicates. If, from this list, you remove the duplicates of the first element with filter, and then cons this element at the beginning of the result, you have a list without any duplicate.
And this is a possibile solution to your problem.

Frequency List in Scheme [duplicate]

This is extremely easy if I can use an array in imperative language or map (tree-structure) in C++ for example. In scheme, I have no idea how to start this idea? Can anyone help me on this?
Thanks,
Your question wasn't very specific about what's being counted. I will presume you want to create some sort of frequency table of the elements. There are several ways to go about this. (If you're using Racket, scroll down to the bottom for my preferred solution.)
Portable, pure-functional, but verbose and slow
This approach uses an association list (alist) to hold the elements and their counts. For each item in the incoming list, it looks up the item in the alist, and increments the value of it exists, or initialises it to 1 if it doesn't.
(define (bagify lst)
(define (exclude alist key)
(fold (lambda (ass result)
(if (equal? (car ass) key)
result
(cons ass result)))
'() alist))
(fold (lambda (key bag)
(cond ((assoc key bag)
=> (lambda (old)
(let ((new (cons key (+ (cdr old) 1))))
(cons new (exclude bag key)))))
(else (let ((new (cons key 1)))
(cons new bag)))))
'() lst))
The incrementing is the interesting part. In order to be pure-functional, we can't actually change any element of the alist, but instead have to exclude the association being changed, then add that association (with the new value) to the result. For example, if you had the following alist:
((foo . 1) (bar . 2) (baz . 2))
and wanted to add 1 to baz's value, you create a new alist that excludes baz:
((foo . 1) (bar . 2))
then add baz's new value back on:
((baz . 3) (foo . 1) (bar . 2))
The second step is what the exclude function does, and is probably the most complicated part of the function.
Portable, succinct, fast, but non-functional
A much more straightforward way is to use a hash table (from SRFI 69), then update it piecemeal for each element of the list. Since we're updating the hash table directly, it's not pure-functional.
(define (bagify lst)
(let ((ht (make-hash-table)))
(define (process key)
(hash-table-update/default! ht key (lambda (x) (+ x 1)) 0))
(for-each process lst)
(hash-table->alist ht)))
Pure-functional, succinct, fast, but non-portable
This approach uses Racket-specific hash tables (which are different from SRFI 69's ones), which do support a pure-functional workflow. As another benefit, this version is also the most succinct of the three.
(define (bagify lst)
(foldl (lambda (key ht)
(hash-update ht key add1 0))
#hash() lst))
You can even use a for comprehension for this:
(define (bagify lst)
(for/fold ((ht #hash()))
((key (in-list lst)))
(hash-update ht key add1 0)))
This is more a sign of the shortcomings of the portable SRFI 69 hashing library, than any particular failing of Scheme for doing pure-functional tasks. With the right library, this task can be implemented easily and functionally.
In Racket, you could do
(count even? '(1 2 3 4))
But more seriously, doing this with lists in Scheme is much easier that what you mention. A list is either empty, or a pair holding the first item and the rest. Follow that definition in code and you'll get it to "write itself out".
Here's a hint for a start, based on HtDP (which is a good book to go through to learn about these things). Start with just the function "header" -- it should receive a predicate and a list:
(define (count what list)
...)
Add the types for the inputs -- what is some value, and list is a list of stuff:
;; count : Any List -> Int
(define (count what list)
...)
Now, given the type of list, and the definition of list as either an empty list or a pair of two things, we need to check which kind of list it is:
;; count : Any List -> Int
(define (count what list)
(cond [(null? list) ...]
[else ...]))
The first case should be obvious: how many what items are in the empty list?
For the second case, you know that it's a non-empty list, therefore you have two pieces of information: its head (which you get using first or car) and its tail (which you get with rest or cdr):
;; count : Any List -> Int
(define (count what list)
(cond [(null? list) ...]
[else ... (first list) ...
... (rest list) ...]))
All you need now is to figure out how to combine these two pieces of information to get the code. One last bit of information that makes it very straightforward is: since the tail of a (non-empty) list is itself a list, then you can use count to count stuff in it. Therefore, you can further conclude that you should use (count what (rest list)) in there.
In functional programming languages like Scheme you have to think a bit differently and exploit the way lists are being constructed. Instead of iterating over a list by incrementing an index, you go through the list recursively. You can remove the head of the list with car (single element), you can get the tail with cdr (a list itself) and you can glue together a head and its tail with cons. The outline of your function would be like this:
You have to "hand-down" the element you're searching for and the current count to each call of the function
If you hit the empty list, you're done with the list an you can output the result
If the car of the list equals the element you're looking for, call the function recursively with the cdr of the list and the counter + 1
If not, call the function recursively with the cdr of the list and the same counter value as before
In Scheme you generally use association lists as an O(n) poor-man's hashtable/dictionary. The only remaining issue for you would be how to update the associated element.

Continuation Passing Style In Common Lisp?

In an effort to find a simple example of CPS which doesn't give me a headache , I came across this Scheme code (Hand typed, so parens may not match) :
(define fact-cps
(lambda(n k)
(cond
((zero? n) (k 1))
(else
(fact-cps (- n 1)
(lambda(v)
(k (* v n))))))))
(define fact
(lambda(n)
(fact-cps n (lambda(v)v)))) ;; (for giggles try (lambda(v)(* v 2)))
(fact 5) => 120
Great, but Scheme isn't Common Lisp, so I took a shot at it:
(defun not-factorial-cps(n k v)
(declare (notinline not-factorial-cps)) ;; needed in clisp to show the trace
(cond
((zerop n) (k v))
((not-factorial-cps (1- n) ((lambda()(setq v (k (* v n))))) v))))
;; so not that simple...
(defun factorial(n)
(not-factorial-cps n (lambda(v)v) 1))
(setf (symbol-function 'k) (lambda(v)v))
(factorial 5) => 120
As you can see, I'm having some problems, so although this works, this has to be wrong. I think all I've accomplished is a convoluted way to do accumulator passing style. So other than going back to the drawing board with this, I had some questions: Where exactly in the Scheme example is the initial value for v coming from? Is it required that lambda expressions only be used? Wouldn't a named function accomplish more since you could maintain the state of each continuation in a data structure which can be manipulated as needed? Is there in particular style/way of continuation passing style in Common Lisp with or without all the macros? Thanks.
The problem with your code is that you call the anonymous function when recurring instead of passing the continuation like in the Scheme example. The Scheme code can easily be made into Common Lisp:
(defun fact-cps (n &optional (k #'values))
(if (zerop n)
(funcall k 1)
(fact-cps (- n 1)
(lambda (v)
(funcall k (* v n))))))
(fact-cps 10) ; ==> 3628800
Since the code didn't use several terms or the implicit progn i switched to if since I think it's slightly more readable. Other than that and the use of funcall because of the LISP-2 nature of Common Lisp it's the identical code to your Scheme version.
Here's an example of something you cannot do tail recursively without either mutation or CPS:
(defun fmapcar (fun lst &optional (k #'values))
(if (not lst)
(funcall k lst)
(let ((r (funcall fun (car lst))))
(fmapcar fun
(cdr lst)
(lambda (x)
(funcall k (cons r x)))))))
(fmapcar #'fact-cps '(0 1 2 3 4 5)) ; ==> (1 1 2 6 24 120)
EDIT
Where exactly in the Scheme example is the initial value for v coming
from?
For every recursion the function makes a function that calls the previous continuation with the value from this iteration with the value from the next iteration, which comes as an argument v. In my fmapcar if you do (fmapcar #'list '(1 2 3)) it turns into
;; base case calls the stacked lambdas with NIL as argument
((lambda (x) ; third iteration
((lambda (x) ; second iteration
((lambda (x) ; first iteration
(values (cons (list 1) x)))
(cons (list 2) x)))
(cons (list 3) x))
NIL)
Now, in the first iteration the continuation is values and we wrap that in a lambda together with consing the first element with the tail that is not computed yet. The next iteration we make another lambda where we call the previous continuation with this iterations consing with the tail that is not computed yet.. At the end we call this function with the empty list and it calls all the nested functions from end to the beginning making the resulting list in the correct order even though the iterations were in oposite order from how you cons a list together.
Is it required that lambda expressions only be used? Wouldn't a named
function accomplish more since you could maintain the state of each
continuation in a data structure which can be manipulated as needed?
I use a named function (values) to start it off, however every iteration of fact-cps has it's own free variable n and k which is unique for that iteration. That is the data structure used and for it to be a named function you'd need to use flet or labels in the very same scope as the anonymous lambda functions are made. Since you are applying previous continuation in your new closure you need to build a new one every time.
Is there in particular style/way of continuation passing style in
Common Lisp with or without all the macros?
It's the same except for the dual namespace. You need to either funcall or apply. Other than that you do it as in any other language.

Scheme,level intermediate student, find min without recursion

How can I write a function using abstract list functions (foldr, map, and filter) without recursion that consumes a list of numbers (list a1 a2 a3 ...) and produces a new list removing the minimum number from the original list?
The recursion code is:
(define (find-min lst)
(cond
[(empty? (rest lst)) (first lst)]
[else
(local [(define min-rest (find-min (rest lst)))]
(cond
[(< (first lst) min-rest) (first lst)]
[else min-rest]))]))
A fold applies a 2-argument function against a given value and the car of a list uses the result against the successive cars or the cdrs or the list. this is what we want.
Whereas map returns a new list by doing something with each element of a list.
And filter returns a smaller or equal list based on some predicate.
Now just to formulate a function that can choose the lessor of two arguments
(define (the-lessor x y)
(if (< x y)
x
y))
From there implementation is straightforward.
(define (min L) (fold the-lessor (car L) (cdr L)))
Since this looks like a homework question, I'm not going to provide all the code, but hopefully push you in the right direction.
From the HTDP book, we see that "The Intermediate Student language adds local bindings and higher-order functions." The trick here is probably going to using "local bindings".
Some assumptions:
(remove-min-from-list '()) => not allowed: input list must be non-empty
(remove-min-from-list '(1)) => '()
(remove-min-from-list '(1 2 3 1 2 3)) => '(2 3 2 3) ; all instances of 1 were removed
Somehow, we need to find the minimum value of the list. Call this function min-of-list. What are its inputs and outputs? It's input is a list of numbers and its output is a number. Of the abstract list functions, which ones allow us to turn a list of numbers into a number? (And not another list.) This looks like foldl/foldr to me.
(define (min-of-list lst)
(foldr some-function some-base lst))
Since you already showed that you could write min-of-list recursively, let's move on. See #WorBlux's answer for hints there.
How would we use this in our next function remove-min-from-list? What are the inputs and outputs of remove-min-from-list? It takes a list of numbers and returns a list of numbers. Okay, that looks like map or filter. However, the input list is potentially shorter than that output list, so filter and not map.
(define (remove-min-from-list lst)
....
(filter some-predicate list))
What does some-predicate look like? It needs to return #f for the minimum value of the list.
Let's pull this all together and use local to write one function:
(define (remove-min-from-list lst)
(local [(define min-value ...)
(define (should-stay-in-list? number) ...min-value ...)]
(filter should-stay-in-list? lst)))
The key here, is that the definition for should-stay-in-list? can refer to min-value because min-value came before it in the local definitions block and that the filter later on can use should-stay-in-list? because it is in the body of the local.
(define (comparator n) (local [(define (compare v) (not (equal? v n)))] compare))
(define (without-min list) (filter (comparator (foldr min (foldr max 0 list) list)) list))

Count occurrence of element in a list in Scheme?

This is extremely easy if I can use an array in imperative language or map (tree-structure) in C++ for example. In scheme, I have no idea how to start this idea? Can anyone help me on this?
Thanks,
Your question wasn't very specific about what's being counted. I will presume you want to create some sort of frequency table of the elements. There are several ways to go about this. (If you're using Racket, scroll down to the bottom for my preferred solution.)
Portable, pure-functional, but verbose and slow
This approach uses an association list (alist) to hold the elements and their counts. For each item in the incoming list, it looks up the item in the alist, and increments the value of it exists, or initialises it to 1 if it doesn't.
(define (bagify lst)
(define (exclude alist key)
(fold (lambda (ass result)
(if (equal? (car ass) key)
result
(cons ass result)))
'() alist))
(fold (lambda (key bag)
(cond ((assoc key bag)
=> (lambda (old)
(let ((new (cons key (+ (cdr old) 1))))
(cons new (exclude bag key)))))
(else (let ((new (cons key 1)))
(cons new bag)))))
'() lst))
The incrementing is the interesting part. In order to be pure-functional, we can't actually change any element of the alist, but instead have to exclude the association being changed, then add that association (with the new value) to the result. For example, if you had the following alist:
((foo . 1) (bar . 2) (baz . 2))
and wanted to add 1 to baz's value, you create a new alist that excludes baz:
((foo . 1) (bar . 2))
then add baz's new value back on:
((baz . 3) (foo . 1) (bar . 2))
The second step is what the exclude function does, and is probably the most complicated part of the function.
Portable, succinct, fast, but non-functional
A much more straightforward way is to use a hash table (from SRFI 69), then update it piecemeal for each element of the list. Since we're updating the hash table directly, it's not pure-functional.
(define (bagify lst)
(let ((ht (make-hash-table)))
(define (process key)
(hash-table-update/default! ht key (lambda (x) (+ x 1)) 0))
(for-each process lst)
(hash-table->alist ht)))
Pure-functional, succinct, fast, but non-portable
This approach uses Racket-specific hash tables (which are different from SRFI 69's ones), which do support a pure-functional workflow. As another benefit, this version is also the most succinct of the three.
(define (bagify lst)
(foldl (lambda (key ht)
(hash-update ht key add1 0))
#hash() lst))
You can even use a for comprehension for this:
(define (bagify lst)
(for/fold ((ht #hash()))
((key (in-list lst)))
(hash-update ht key add1 0)))
This is more a sign of the shortcomings of the portable SRFI 69 hashing library, than any particular failing of Scheme for doing pure-functional tasks. With the right library, this task can be implemented easily and functionally.
In Racket, you could do
(count even? '(1 2 3 4))
But more seriously, doing this with lists in Scheme is much easier that what you mention. A list is either empty, or a pair holding the first item and the rest. Follow that definition in code and you'll get it to "write itself out".
Here's a hint for a start, based on HtDP (which is a good book to go through to learn about these things). Start with just the function "header" -- it should receive a predicate and a list:
(define (count what list)
...)
Add the types for the inputs -- what is some value, and list is a list of stuff:
;; count : Any List -> Int
(define (count what list)
...)
Now, given the type of list, and the definition of list as either an empty list or a pair of two things, we need to check which kind of list it is:
;; count : Any List -> Int
(define (count what list)
(cond [(null? list) ...]
[else ...]))
The first case should be obvious: how many what items are in the empty list?
For the second case, you know that it's a non-empty list, therefore you have two pieces of information: its head (which you get using first or car) and its tail (which you get with rest or cdr):
;; count : Any List -> Int
(define (count what list)
(cond [(null? list) ...]
[else ... (first list) ...
... (rest list) ...]))
All you need now is to figure out how to combine these two pieces of information to get the code. One last bit of information that makes it very straightforward is: since the tail of a (non-empty) list is itself a list, then you can use count to count stuff in it. Therefore, you can further conclude that you should use (count what (rest list)) in there.
In functional programming languages like Scheme you have to think a bit differently and exploit the way lists are being constructed. Instead of iterating over a list by incrementing an index, you go through the list recursively. You can remove the head of the list with car (single element), you can get the tail with cdr (a list itself) and you can glue together a head and its tail with cons. The outline of your function would be like this:
You have to "hand-down" the element you're searching for and the current count to each call of the function
If you hit the empty list, you're done with the list an you can output the result
If the car of the list equals the element you're looking for, call the function recursively with the cdr of the list and the counter + 1
If not, call the function recursively with the cdr of the list and the same counter value as before
In Scheme you generally use association lists as an O(n) poor-man's hashtable/dictionary. The only remaining issue for you would be how to update the associated element.

Resources