Homework #8

Due Dec 4



(1)  Concurrency. Implement a ticket selling program with multiple ticket sellers. There will be multiple threads of execution that are independently selling the tickets to the new holiday blockbuster movie. There is  one shared database variable that represents the tickets available to sell. Assume all tickets are equal and the only real issue is that you do not sell more tickets than there are seats. Each thread of execution will take a random amount of time to sell a seat, thus ensuring a random order of the threads of execution. Each sale will be from 1 to 3 tickets (chosen randomly each time) While a particular seller is selling, all other sellers must be excluded from access to the shared database variable. When all of the tickets are gone, each seller should terminate with a message indicating how many tickets were sold by that seller... obviously these messages should add up to the total number of available tickets.

(2) Streams. First, some experimentation.

(3) The following procedure returns a list of all the distinct symbols in a given list of symbols. That is, each symbol appears only once in the result list, no matter how many times it appeared in the argument list.

(define (remove-duplicates lst)
  (cond ((null? lst) null)
        ((not (memq (car lst) (cdr lst)))
         (cons (car lst) (remove-duplicates (cdr lst))))
        (else (remove-duplicates (cdr lst)))))

Remove-duplicates checks to see whether the car of the list is an element of the cdr of the list. If so, it ignores the car and returns the result of removing duplicates from the cdr. Otherwise it conses the car onto this result. Remove-duplicates uses the procedure memq from Section 2.3.1, which tests whether a given symbol is in a given list. Memq returns the part of the list beginning with the designated symbol, or false if the symbol is not in the list:

(define (memq item x)
  (cond ((null? x) #f)
        ((eq? item (car x)) x)
        (else (memq item (cdr x)))))

Louis Reasoner suggests that in order to make remove-duplicates work with streams instead of list, all we have to do is modify remove-duplicates and memq by changing cons to cons-stream, car to stream-car, cdr to stream-cdr, and null? to stream-null?. Explain what is wrong with Louis's suggestion.

(4) Complete the following CORRECT definition of a procedure that removes duplicates from a stream.
You might want to test it using the ideas in problem 2 above.

(define (remove-duplicates stream)
  (if (stream-null? stream)
      the-empty-stream
      (cons-stream <first-element>
                   (stream-filter <predicate> <stream-to-filter>))))
 

EXTRA CREDIT
(5) Do problem 3.50 from the book (generalized version of stream-map). Demonstrate it working.

(6) The Monkey Bridge: Implement a true concurrent programming solution to the following problem: A group of 10 monkeys start randomly on the left or right side of a huge canyon. There is a single rope spanning the canyon. Each monkey, at a random time, decides to cross to the other side of the bridge. This takes the monkey some small random amount of time. However, if a monkey crossing to the west is on the rope bridge at the same time as a monkey crossing to the east, they cannot pass (are deadlocked). Have the monkeys use the serializer technique to ensure that they make it across safely.