9
$\begingroup$

Here is Fizz buzz

Write a program that prints the integers from 1 to 100. But for multiples of 3 print "Fizz" instead of the number and for the multiples of 5 print "Buzz". For numbers which are multiples of both 3 and 5 print "FizzBuzz".

I found the python version is much shorter, so I decided to write a short one, I have wrote several version

Table[If[# != {}, Row@#, n] &@({Fizz}[[Sign[n~Mod~3] + 1 ;;]]~Join~{Buzz}[[Sign[n~Mod~5] + 1 ;;]]), {n, 100}]

StringJoin@{If[#~Mod~3 == 0, "Fizz", ""], If[#~Mod~5 == 0, "Buzz", ""]} /. "" -> # & /@ Range@100

d = Divisible; Range@100 /. {_?(#~d~15 &) -> FizzBuzz, _?(#~d~3 &) -> Fizz, _?(#~d~5 &) -> Buzz}

Can you show a more shorter one?

$\endgroup$
6
  • 3
    $\begingroup$ Related meta: meta.mathematica.stackexchange.com/q/136/5 $\endgroup$
    – rm -rf
    Commented Jan 30, 2013 at 16:56
  • 2
    $\begingroup$ @chyanog As rm -rf linked, code-golf challenges are generally frowned upon in this forum. I do however think you could make a slight edit of your question and instead of asking for specific versions of fizz-buzz ask for general techniques that can be applied within Mathematica in code-golf settings. I personally would like to see such a question answered. $\endgroup$
    – jVincent
    Commented Jan 30, 2013 at 17:33
  • $\begingroup$ I understand "shorter" in terms of lexemes rather than characters. This would eliminate trivial moves like d=Divisible (which merely replaces one symbol by another) designed solely to shrink the character count without changing how the code actually works, and helps focus the mind on the computation itself. $\endgroup$
    – whuber
    Commented Jan 30, 2013 at 18:51
  • 10
    $\begingroup$ It's still code-golf and a very tired, stale example at that. $\endgroup$
    – m_goldberg
    Commented Jan 30, 2013 at 18:53
  • $\begingroup$ @m_goldberg oh well, I had fun with it anyway. $\endgroup$
    – Mr.Wizard
    Commented Jan 31, 2013 at 10:41

6 Answers 6

24
$\begingroup$

67 63 56 55 (47?) characters

Better:

Row@Pick[{Fizz,Buzz},#~Mod~{3,5},0]/._@{}->#&~Array~100

In the rule-bending spirit of Code Golf, 47 characters:

Pick[Fizz^Buzz,#~Mod~{3,5},0]/. 1->#&~Array~100

Mathematica graphics

$\endgroup$
3
  • 2
    $\begingroup$ Very nice solution! $\endgroup$
    – chyanog
    Commented Jan 31, 2013 at 8:45
  • 1
    $\begingroup$ @chyanog Thanks :D $\endgroup$
    – Mr.Wizard
    Commented Jan 31, 2013 at 8:48
  • $\begingroup$ @Simon I had to post it before you did! ;-) $\endgroup$
    – Mr.Wizard
    Commented Jan 31, 2013 at 11:29
14
$\begingroup$

53 characters

I can't beat Mr Wizard, but anyway:

{#,,fizz,fizzbuzz,buzz}[[#~GCD~15~Mod~11]]&~Array~100
$\endgroup$
2
  • 1
    $\begingroup$ It's just there to convert 15 to 4, without the Mod I would need "fizzbuzz" at position 15 in the list, which is a lot of commas! I could also use modulo 13, or even 15 for the rather nice fizzbuzz[#,,fizz,,buzz][[#~GCD~15~Mod~15]]&~Array~100 $\endgroup$ Commented Jan 31, 2013 at 11:44
  • $\begingroup$ Yes, I figured it out after walking through the code. Again I really like this approach and I wish I could claim that I thought of something similar but I surely did not. $\endgroup$
    – Mr.Wizard
    Commented Jan 31, 2013 at 11:45
11
$\begingroup$

One method of shortening (and obfuscating!) code with repetitive specifications uses a function that writes functions:

w[i_, s_] := f[x_] /; Divisible[x, i] := s

It's now quick work to use w to write the solution, beginning with the default of just echoing the input:

f[x_] := x
LCM[3,5]~w~FizzBuzz; 3~w~Fizz; 5~w~Buzz

(LCM is used to avoid doing any precomputation. Because this case is intended to override the other cases, it must appear first in the list of definitions.) Apply it:

Array[f, 100]
$\endgroup$
4
  • $\begingroup$ This is still longer than the OP's third method, even with 15~w~FizzBuzz and f@x_:=x etc. $\endgroup$
    – Mr.Wizard
    Commented Jan 31, 2013 at 2:04
  • 1
    $\begingroup$ @Mr.Wizard That is correct: I am taking a (now deleted) comment to the question seriously; namely, to respond in terms of general techniques to address such questions. Otherwise, I agree with that comment: there is no place on our site for endless "code golf" solutions. We should also be interested in solutions that generalize well, as in the solution by jVincent--and especially in your elegant solution! $\endgroup$
    – whuber
    Commented Jan 31, 2013 at 3:06
  • $\begingroup$ Okay, I see your perspective. Sorry for being harsh. I guess it would sit better with me if you had demonstrated this method actually making the code shorter. Though I know I am in the minority I actually learn from code-golf, both from the process of working things out and from seeing other answers; since I am a greater fan of the process let me recommend this addition to your answer as a demonstration of efficacy of your method: (f@x_ /; x~Mod~# == 0 = #2) & @@@ {15 | FizzBuzz, 3 | Fizz, 5 | Buzz, 1 | x}. (continued) $\endgroup$
    – Mr.Wizard
    Commented Jan 31, 2013 at 7:50
  • $\begingroup$ Though this uses x dangerously, a common Golf failing, it also shows something useful in the use of |: many users often forget that Apply works with heads besides List. $\endgroup$
    – Mr.Wizard
    Commented Jan 31, 2013 at 7:51
6
$\begingroup$

The problem is essentially to apply a test and provide output according to the test. Often the most straight forward construct in Mathematica is also among the most concise. Though in the name of cutting characters you can substitute call syntax for prefix and infix when it saves characters:

Switch[#~Mod~{3,5},{0,0},FizzBuzz,{0,_},Fizz,{_,0},Buzz,_,#]&~Array~100
$\endgroup$
1
  • $\begingroup$ +1 That is an instructive use of Switch. This solution generalizes readily to more moduli, as in With[{moduli = {2, 3, 5, 7}, names = {Huh, Fizz, Buzz, Whap}}, Switch[Mod[#, moduli], Evaluate[ Sequence @@ Riffle[Tuples[{0, _}, n = Length[moduli]], Tuples[{1, 0}, n] . names /. {Plus -> Alternatives, 0 -> #}]]] ] &~Array~210 $\endgroup$
    – whuber
    Commented Jan 30, 2013 at 21:15
6
$\begingroup$

60 characters, a simple rule-driven solution:

#/.Flatten[{15#->FizzBuzz,3#->Fizz,5#->Buzz}&/@#]&@Range@100

(Nice to see it being interpreted correctly by MMA kernel.)

$\endgroup$
5
  • 1
    $\begingroup$ 59 characters: #/.Join@@({15#->FizzBuzz,3#->Fizz,5#->Buzz}&/@#)&@Range@100 $\endgroup$
    – chyanog
    Commented Aug 5, 2013 at 15:22
  • 1
    $\begingroup$ @chyanog 56: #/.(##&[15#->FizzBuzz,3#->Fizz,5#->Buzz]&)/@#&@Range@100 $\endgroup$
    – Mr.Wizard
    Commented Aug 5, 2013 at 18:14
  • $\begingroup$ @Mr.Wizard, Good job! $\endgroup$
    – chyanog
    Commented Aug 6, 2013 at 14:05
  • $\begingroup$ @Akater Could you explain how your solution works? I'm confused by the multiple uses of #. $\endgroup$ Commented Apr 18, 2018 at 21:38
  • $\begingroup$ @MitchellKaplan 15#, 3#, 5# is interpreted as multiplication, Times[15, #] and so on. I generate rules that replace exact numbers with words and apply them to the list {1, ..., 100} generated in the enveloping function. If you use FrontEnd, you may select the expression you're uncertain about, expand selection with multiple clicks or a keyboard shortcut (don't remember which one already) and convert the selected expressions into FullForm. $\endgroup$
    – akater
    Commented Jul 24, 2018 at 23:05
4
$\begingroup$

Constrained patterns can often be used to find simple literal solutions to some problems.

Range@100 /. {(x_ /; IntegerQ[x/3] && IntegerQ[x/5]) -> "FizzBuzz", 
              (x_ /; IntegerQ[x/3]) -> "Fizz", 
              (x_ /; IntegerQ[x/5]) -> "Buzz"}
$\endgroup$
1
  • 3
    $\begingroup$ This is almost the same as the OP's third solution with #~Divisible~..& replaced by IntegerQ. I like how the reference to 15 has been replaced by a conjunction of criteria, which is closer to the problem statement. $\endgroup$
    – whuber
    Commented Jan 30, 2013 at 19:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.