Objective: Create a program that counts from 1 to 100.
The Trick: For any number divisible by 3 replace it with “Fizz”, any number by 5 with “Buzz” and any by 3 and 5 with “FizzBuzz”.
Lets see everyones approach. Imaginary points to the winners of the following categories: Speed, Length, Strangeness.
So to start it here is mine…
set fbString to ""
repeat with i from 1 to 1000
set fbString to fbString & fizzBuzz(i) & " "
end repeat
on fizzBuzz(i)
if (i mod 3) = 0 then
if (i mod 5) = 0 then
return "FizzBuzz"
else
return "Fizz"
end if
else
if (i mod 5) is 0 then
return "Buzz"
else
return i
end if
end if
end fizzBuzz
Well, James, I couldn’t resist. Here’s a 5-liner (really 6):
set fbString to ""
repeat with i from 1 to 1000
set {mod3, mod5} to {0 ^ (i mod 3), 2 * (0 ^ (i mod 5))}
set fbString to (fbString & (items (1 + mod3 + mod5 - mod3 * mod5) thru (1 + mod3 + mod5 - mod3 * mod5 / 2) of {i, "Fizz", "Buzz"}) as string) & " "
end repeat
set fbString to ""
repeat with i from 1 to 1000
set fbString to (fbString & (items (1 + 0 ^ (i mod 3) + 2 * (0 ^ (i mod 5)) * (1 - (0 ^ (i mod 3)))) thru (1 + 0 ^ (i mod 3) + (0 ^ (i mod 5)) * (2 - (0 ^ (i mod 3)))) of {i, "Fizz", "Buzz"}) as string) & " "
end repeat
Oh no, I just felt like timing these. :o Darn you, James. Thankfully, GetMilliSec doesn’t work on my machine.
Just saving a few characters:
set fbString to ""
repeat with i from 1 to 1000
tell (0 ^ (i mod 3)) to set fbString to fbString & (items (1 + it + 2 * (0 ^ (i mod 5)) * (1 - it)) thru (1 + it + (0 ^ (i mod 5)) * (2 - it)) of {i, "Fizz", "Buzz"}) & " "
end repeat
set fbString to ""
repeat with i from 1 to 1000
tell {modThree:(0 ^ (i mod 3)), modFive:(0 ^ (i mod 5))} to set fbString to fbString & items (1 + (it's modThree) + 2 * (it's modFive) * (1 - (it's modThree))) thru (1 + (it's modThree) + (it's modFive) * (2 - (it's modThree))) of {i, "Fizz", "Buzz"} & " "
end repeat
Using the Extra Suites ES milliseconds command, I timed five of the variations and increased the final string size from 1000 to 5000 to bring out differences better. The following are the execution times (PowerBook G4, average of 5 runs each to adjust for inherent fluctuations):
James’s original script:
2.79 seconds – > the speed winner!
Bruce’s tell (0 ^ (i mod 3)):
2.93 seconds
bmose’s 6-liner:
3.02 seconds
Bruce’s tell {modThree:(0 ^ (i mod 3)), modFive:(0 ^ (i mod 5))}:
3.12 seconds → my favorite for elegance
bmose’s 4-liner:
3.19 seconds → my favorite for pure weirdness
(Oops, sorry James, you have the final say in the judging contest!)