The Collection Way of Life

Exercise 4.1

Open the protocol browser on the class String, search for the method allButFirst: implemented in SequenceableCollection. Read its comment in its source code.

'Hello My Friend' allButFirst: 6
⇒ 'My Friend'

Exercise 4.2

(-80 to: 50) asArray

Exercise 4.3

(1 to: 100) difference: (25 to: 75)
⇒ #(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
22 23 24 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
92 93 94 95 96 97 98 99 100) 

Exercise 4.4

(-20 to: 45) select: [:z | z odd]

Exercise 4.5

((101 to: 200) select: [:n | n isPrime]) size
⇒ 21 

Exercise 4.6

(1 to: 100) select:[:n | n isDivisibleBy: 7]
⇒ #(7 14 21 28 35 42 49 56 63 70 77 84 91 98) 

Exercise 4.7

This solution, based on set operations and multiple use of the #select: message, is mostly compatible with the knowledge acquired at this point of the book.

| primeNumbers nonPrimeNumbers |
primeNumbers := (1 to: 100) select: [:n | n isPrime].
nonPrimeNumbers := (1 to: 100) difference: primeNumbers.
nonPrimeNumbers select: [:n | n odd]
⇒ #(1 9 15 21 25 27 33 35 39 45 49 51 55 57 63 65 69 75
77 81 85 87 91 93 95 99) 

A shorter solution with logical operations we have not discussed so far:

(1 to: 100) select:[:n | n isPrime not and: [n odd]]

Exercise 4.8

'Zpv!bsf!b!cptt' collect: [:c |
   (c asciiValue - 1) asCharacter]
⇒ 'You are a boss' 

Exercise 4.9

($A to: $Z) collect: [:c |
   (c asciiValue - 65 + 3 \\ 26 + 65) asCharacter]

Each character from A to Z is referenced by the c block parameter and converted to its Ascii value30: c asciiValue. It is shifted of 65, so the A character counts as 0 and Z as 25 in the alphabet list. To apply the Caesar cipher, we send the message + 3 to the previous result.

We are almost good, only the characters X, Y, Z will overflow the alphabet, indeed these characters will be ciphered as 26, 27, 28. To fix that we send \\ 26 to the previous result, it is an old trick of programming: the reminder of the Euclidean division by 26 frames the value between 0 and 2531.

Finally we shift back of 65 before converting from the Ascii value to the character.

Exercise 4.10

In the solution of Exercise 4.9, we just need to replace the characters interval with a string:

'SMALLTALKEXPRESSION' collect: [:c |
   (c asciiValue - 65 + 3 \\ 26 + 65) asCharacter]
⇒ 'VPDOOWDONHASUHVVLRQ' 

Exercise 4.11

  'DOHDMDFWDHVW' collect: [:c |
    (c asciiValue - 65 - 3 \\ 26 + 65) asCharacter]
⇒ 'ALEAJACTAEST'

Exercise 4.12

The appropriate message is #first:, defined in the parent class SequenceableCollection. You need to use the protocol or hierarchy browser on Array to discover it:

array1 first: 2
⇒ #(2 'Apple') 

Exercise 4.13

You could simply do a thumb:

array1 at: 1 put: 'kiwi'.
array1 at: 2 put: 'kiwi'.
array1 at: 3 put: 'kiwi'.
array1 at: 4 put: 'kiwi'.

Or even a bit less thumb:

1 to: array1 size do: [:index |
   array1 at: index put: 'kiwi']

But if you search for carefully the Array protocol, you can just do:

array1 atAllPut: 'kiwi'.

Exercise 4.14

In the OrderedCollection protocol search for the method add:after:.

coll1 := {2 . 'Apple' . 2@1 . 1/3 } asOrderedCollection .		
coll1 add: 'Orange' after: 'Apple'; yourself.
⇒  an OrderedCollection(2 'Apple' 'Orange' 2@1 1/3) 

Exercise 4.15

Set  new
   addAll: 'buenos días';
   addAll: 'bonjour';
   yourself.
⇒  a Set($e $j $o $a $u $b $  $í $r $d $n $s) 

Exercise 4.16

colors keysDo: [:key |
   colors at: key put: key asString capitalized].
colors
⇒ a Dictionary(#blue->'Blue' #green->'Green' #red->'Red'
#yellow->'Yellow' ) 

Exercise 4.17

When the game starts there is no fired torpedoes, therefore torpedoes is an empty OrderedCollection, instantiated with the #new class message.

In the other hand, the ships is an Array containing only two elements, the player ships. We use the #with:with class message to instantiate and populate the array with two ships created in the argument message.

For the readability, we split the code in several lines with the appropriate indentation.

   torpedoes := OrderedCollection new.
   ships := Array 
      with: SpaceShip new
      with: SpaceShip new.

Exercise 4.18

SpaceWar>>stepAt: msSinceLast
  ships do: [:each | each update: msSinceLast / 1000 ].
  ships do: [:each | each unpush ].
  torpedoes do: [:each | each update: msSinceLast / 1000 ].

Footnotes

(30)

https://en.wikipedia.org/wiki/ASCII

(31)

It generalizes to the mathematics field of modular arithmetic, https://www.wikiwand.com/en/Modular_arithmetic