I'm really new to smalltalk and still trying to figure out the basic stuff. Below is a simple program I wrote. It is supposed to print "a" if the number can be divided by 5, "b" if it can be divided by 3, and "ab" if it can be divided by 5 and 3. In any other case, the program just prints the number itself. It certainly works like this, but I feel that the code isn't very pretty - I would like to avoid the third "if", but I'm really not sure how. How would you refactor this?
1 to: 100 do: [ :i |
(i % 5 == 0)
ifTrue: [ Transcript show: 'a' ].
(i % 3 == 0)
ifTrue: [ Transcript show: 'b' ].
((i % 3 == 0) or: (i % 5 == 0))
ifFalse: [ Transcript show: i ].
Transcript cr.
].
Thanks in advance for your help!
Smells like a Fizz Buzz problem! :-)
One approach in Smalltalk (Pharo) I've seen that I like is to use a dictionary with the Fizz and/or Buzz words as values and the booleans for whether it's divisible by 3 and 5 as keys. Once you have that, you simply look up the value for each index between 1 and 100. Oh, and don't bother dividing and checking whether the remainder is zero yourself - it's Smalltalk, so a number should know whether it's divisible by another number.
| fizzbuzz |
fizzbuzz := Dictionary
with: #(true true)->'FizzBuzz'
with: #(true false)->'Fizz'
with: #(false true)->'Buzz'.
1 to: 100 do: [ :eachIndex |
Transcript
show: (fizzbuzz
at: {eachIndex isDivisibleBy: 3. eachIndex isDivisibleBy: 5}
ifAbsent: [ eachIndex ]);
cr]
Have a look at some of the other examples as well, sometimes the different approaches can be quite educational. I'll leave it to you to adapt the code to your 'a'/'b'/'ab' example.