CSc 398 Mid-Term Examination Wednesday 15 March 2000 >>>>>>>>>>>>>>>>>SUGGESTED ANSWERS<<<<<<<<<<<<<<<<<<<<<<<<< 1. The original fibonacci sequence is 1,1,2,3,5,8,..., where the next number is the sum of the previous two entries. In general, a sequence starting with any two positive numbers is fibonacci if a given entry is the sum of the previous two entries. Write a class Fibonacci which is a subclass of OrderedCollection, which responds to the message "new" by creating an instance whose initial values are 1 and 1, which responds to the message "x1:n x2:m" by creating an instance whose intial values are n and m, whose instances always have two entries, and whose instances respond to the messages "next" (which returns the next entry in the given fibonacci sequence) and "ratio" (which returns the ratio of the two current entries as a Float). (The ratio of consecutive entries in the fibonacci sequence converges to the golden mean, a concept invented by the Greeks). OrderedCollection subclass: #Fibonacci instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' ! !Fibonacci class methods ! new |temp| temp:=super new. temp add:1; add:1. ^temp! x1:n x2:m ^(super new) add:n; add:m; yourself! ! !Fibonacci methods ! next self addLast:(self first + self last); removeFirst. ^self last! ratio ^(self first/self last) asFloat! ! 2. Write an instance method for ReadStream called "toNoBlank:aWritestream". This method should assume that the ReadStream is streaming over an instance of some collection of characters (perhaps a String), and that aWriteStream is an instance of WriteStream. The ReadStream should store on aWriteStream all the elements of the collection over which it is streaming, except the the blank characters. The method should return the resulting collection. (Hint: the blank character is $ , where $ indicates a Character.) !ReadStream methods ! toNoBlank:aStream |temp| self reset. [self atEnd] whileFalse:[ temp:=self next. temp~=$ ifTrue:[aStream nextPut:temp]. ]. ^aStream contents! ! 3. Write method(s) for the appropriate class(es) so that whenever a number is sent the binary message "<0 ifTrue:[mult:=self] ifFalse:[mult:=1/self]. temp:=1. 1 to:n abs do:[:i| temp:=temp*mult]. ^temp 4. Suppose we have a class Random whose instances respond to the message next by returning a (pseudo)random number between 0 and 1. Discuss why the specific output of the code below is unpredicatble. Also discuss what the typical output would be. S:=0. T:=0. X:=OrderedCollection new. Rand:=Random new. Sblock:= [ [S+T<20] whileTrue: [S:=S+1. X add:(Array with:'S' with:S). Rand next <0.3 ifTrue:[Processor yield] ] ]. Tblock:= [ [S+T<20] whileTrue: [T:=T+1. X add:(Array with:'T' with:T). Rand next <0.7 ifTrue:[Processor yield] ] ]. [ Sblock forkAt:5. Tblock forkAt:5] forkAt:6. X Two process are forked and are both yielding, depending upon a random number. Roughly speaking, on each loop, Sblock yields 30% of the time and Tblock yields 70% of the time. Because the Sblock is forked first, it always executes its loop at least once before yielding. Thus, the first entry in X is always ('S' 1). Although it is possible for the rest of X to contain any mixture of pairs of the form ('T' x) and ('S' x), we would expect around 70% of the entries to be 70% ('S' x) and 30% ('T' x), that is about 14 ('S' x) and 6 ('T' x). When I tried this I got 13 and 7.