Live data from Hacker News

FizzBuzz in ten languages

iolivia.me

81–90 of 103 posts

Re: FizzBuzz in ten languages

#81
post #75
post #63

Earlier quoted context omitted.

Maybe I'm missing something, but how is that any more readable than: for val in xrange(1, 100): if val % 15 == 0: print "FizzBuzz" elif val % 5 == 0: print "Buzz" elif val % 3 == 0: print "Fizz" else: print val

I agree with you. Pattern matching is detrimental to readability in this case. Everybody can understand your example above. The pattern matching one leaves me a little O_o (pun intended) despite I'm using pattern matching everyday in Elixir. Sometimes boring code beats clever code.

I think that’s more a matter of familiarity than of readability proper. The same argument could have been made against Arabic numerals, against the use of “=“ for assignment and “==“ for equality (“=“ had been used in mathematics for equality for ¿centuries?), etc.

One could also argue that, by using the knowledge that “is divisible by 3 and 5” is equivalent to “is divisible by 15”, the code using %15 is cleverer than the example that just follows the problem description.

Re: FizzBuzz in ten languages

#82

Fast. Faster. Fastest. The FizzBuzz Gold Standard. Lookup pre-calculated ("hard coded") constants. Don't over-engineer :-): def fizzbuzz [1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", "Buzz", 11, "Fizz", 13, 14, "FizzBuzz", 16, 17, "Fizz", 19, "Buzz", "Fizz", 22, 23, "Fizz", "Buzz", 26, "Fizz", 28, 29, "FizzBuzz", 31, 32, "Fizz", 34, "Buzz", "Fizz", 37, 38, "Fizz", "Buzz", 41, "Fizz", 43, 44, "FizzBuzz", 46, 47, "Fi…

Fast? Yes. The Gold Standard?

Pshaw.

This thread is utterly incomplete without Fizz Buzz Enterprise Edition™[1].

If you want to get straight to the good parts of it, just look at the Factories folder[2].

[1]https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...

[2]https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...

Re: FizzBuzz in ten languages

#83
post #80

Fast. Faster. Fastest. The FizzBuzz Gold Standard. Lookup pre-calculated ("hard coded") constants. Don't over-engineer :-): def fizzbuzz [1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", "Buzz", 11, "Fizz", 13, 14, "FizzBuzz", 16, 17, "Fizz", 19, "Buzz", "Fizz", 22, 23, "Fizz", "Buzz", 26, "Fizz", 28, 29, "FizzBuzz", 31, 32, "Fizz", 34, "Buzz", "Fizz", 37, 38, "Fizz", "Buzz", 41, "Fizz", 43, 44, "FizzBuzz", 46, 47, "Fi…

Plus a program to produce the pre-calculated data, to avoid typos. :-)

Why not both at the same time. All you need is a language with compile-time execution:

    auto fizzbuzz(size_t n) {
        return iota(n)
            .map!((i) {
                if ((i % 15) == 0) {
                    return "FizzBuzz";
                } else if ((i % 3) == 0) {
                    return "Fizz";
                } else if ((i % 5) == 0) {
                    return "Buzz";
                } else {
                    return i.to!string;
                }
            });
    }

    void main() {
        // enum here forces compile-time execution
        enum fizzbuzz100 = fizzbuzz(100).join("\n");
        writeln(fizzbuzz100);
    }

Re: FizzBuzz in ten languages

#84

Fast. Faster. Fastest. The FizzBuzz Gold Standard. Lookup pre-calculated ("hard coded") constants. Don't over-engineer :-): def fizzbuzz [1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", "Buzz", 11, "Fizz", 13, 14, "FizzBuzz", 16, 17, "Fizz", 19, "Buzz", "Fizz", 22, 23, "Fizz", "Buzz", 26, "Fizz", 28, 29, "FizzBuzz", 31, 32, "Fizz", 34, "Buzz", "Fizz", 37, 38, "Fizz", "Buzz", 41, "Fizz", 43, 44, "FizzBuzz", 46, 47, "Fi…

Fastest? We need benchmarks to show that. I can see this being slower than traditional approaches on systems with slow memory, tiny CPU caches, and compilers that don’t do constant string folding.

You can also replace the array by a single string. That may or may not be faster, depending on CPU and language implementation. I think it likely is (rationale: the code writing the array to stdout either does multiple write calls, or builds up the string in memory and then does what the code writing the string does. The code writing the array need not load the string, but it needs to store the array, and that won’t be much smaller, even when it shares strings)

Re: FizzBuzz in ten languages

#86
post #22

I've been looking for an example that shows how pattern matching can make code much both compact and readable. I think this does nicely. Here's an example in Scala: (1 to 100).map(i => (i % 3, i % 5) match { case (0, 0) => "FizzBuzz" case (0, _) => "Fizz" case (_, 0) => "Buzz" case _ => s"$i" }).foreach(println) Compare that to the rest of the examples on the page. The only one that comes close in either readability…

The Haskell example is quite similar to the Scala/Rust example as well. I guess you could rewrite the Haskell version to match your Scala version pretty closely as well if you prefer doing the tuple construction and then matching on the tuple, like in your Scala version, instead of doing it directly inside the pattern match. Something like this, with the caveat that I haven't done any proper coding in Haskell in year…

The step in the composition chain breaking down the integers into ordered pairs of the remainders is classy. Well done. For added points we now need an ADT to represent the different possible results of the computation :)

Re: FizzBuzz in ten languages

#87
The Prolog version is fine, but the nested conditionals make it harder to read and may cause confusion about scope (for example, it's not necessary to enclose "divBy3(X),divBy5(X)" in parentheses, as on line 6 in the article).

Here's an alternative version, that avoids nested conditionals and also doesn't use the cut ("!") to control backtracking:

  fizzbuzz(X,'Fizz'):-
  	0 is mod(X,3).
  fizzbuzz(X,'Buzz'):-
  	0 is mod(X,5).
  fizzbuzz(X,X):-
  	\+ fizzbuzz(X,'Fizz')
  	,\+ fizzbuzz(X,'Buzz').
  
  print_fizzbuzz(N,M):-
  	N > M.
  print_fizzbuzz(N,M):-
  	N =
This one uses Prolog's nondeterminsm to generate either Fizz, Buzz, both, or neither as apropriate and collects them all with forall/2 (yes, Prolog does have for-loops; of a sort), then adds a newline to the output.

Call it like this:

  ?- print_fizzbuzz(1,100).
And have a Happy New Year.

Re: FizzBuzz in ten languages

#88

Fast. Faster. Fastest. The FizzBuzz Gold Standard. Lookup pre-calculated ("hard coded") constants. Don't over-engineer :-): def fizzbuzz [1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", "Buzz", 11, "Fizz", 13, 14, "FizzBuzz", 16, 17, "Fizz", 19, "Buzz", "Fizz", 22, 23, "Fizz", "Buzz", 26, "Fizz", 28, 29, "FizzBuzz", 31, 32, "Fizz", 34, "Buzz", "Fizz", 37, 38, "Fizz", "Buzz", 41, "Fizz", 43, 44, "FizzBuzz", 46, 47, "Fi…

In racket I would probably use a wheel for a more general solution:

    (define wheel '(#f #f "fizz" #f "buzz" "fizz" #f #f "fizz" "buzz" #f "fizz" #f #f "fizzbuzz"))

    (for ((fb? (in-cycle wheel)) (i (in-range 1 101)))
      (displayln (or fb? i)))

It would be more elegant in a lazy language, but it is probably quite fast since it doesn't need any division (?? My assumption here might be wrong). I typed this out on my phone, so it might not work, and racket isn't my daily driver.

Edit: My initial assumption was correct, but the in-cycle sequence creator has a very large overhead. The final solution for racket (Ugly, because mlist doesn't have any nice things included): https://pastebin.com/aB2BLY1U

The mutable list solution (as one would write it in scheme) is more than twice as fast as the remainder one, and I expect it to be for other languages as well.

Re: FizzBuzz in ten languages

#89
How about machine-learning the Prolog version, using Inductive Logic Programming and Metagol [1]?

Here's one way to do it:

  % e.g. place in metagol/examples/
  :-['../metagol'].
  
  % Second-order inductive bias.
  metarule([P,Q],([P,A,A]:-[[Q,A]])).
  metarule([P,Q,B,C],([P,A,B]:-[[Q,A,C]])).
  
  % Learning primitives.
  prim(positive_integer/1).
  prim(exact_division/2).
  
  % Primitives' definitions.
  positive_integer(N):-
  	between(1,inf,N).
  
  exact_division(X,Y):-
  	positive_integer(X)
  	,divisor(Y)
  	,0 is X mod Y.
  
  divisor(3).
  divisor(5).
  divisor(15).
  
  
  % Training setup.
  learn_fizzbuzz:-
  	% Positive examples
  	Pos = [fizzbuzz(1,1)
  	      ,fizzbuzz(2,2)
  	      ,fizzbuzz(3,fizz)
  	      ,fizzbuzz(5,buzz)
  	      ,fizzbuzz(15,fizzbuzz)
  	      ]
  	% Negative examples
  	,Neg = [fizzbuzz(1,fizz)
  	       ,fizzbuzz(1,buzz)
  	       ,fizzbuzz(3,fizzbuzz)
  	       ,fizzbuzz(5,fizzbuzz)
  	       ]
  	% Train with metagol
  	,learn(Pos,Neg).
We can put that in a file, consult it and call learn_fizzbuzz at the Prolog repl:

  ?- learn_fizzbuzz.
  % learning fizzbuzz/2
  % clauses: 1
  % clauses: 2
  % clauses: 3
  % clauses: 4
  fizzbuzz(A,fizzbuzz):-exact_division(A,15).
  fizzbuzz(A,buzz):-exact_division(A,5).
  fizzbuzz(A,fizz):-exact_division(A,3).
  fizzbuzz(A,A):-positive_integer(A).
  true .

  
This will give us the fizzbuzz/2 function, mapping each integer N to {fizz,buzz,fizzbuzz,N}. Then we can simply loop over it:

  print_fizzbuzz(N):-
  	forall(between(1,N,I)
  	      ,(fizzbuzz(I,FBN)
  	       ,writeln(FBN)
  	       )
  	      ).
Note we learned a general version of fizzbuzz from only 5 positive and 4 negative examples. Just don't tell Joel Grus [2].

_______

[1] https://github.com/metagol/metagol

[2] http://joelgrus.com/2016/05/23/fizz-buzz-in-tensorflow/

Re: FizzBuzz in ten languages

#90

Earlier quoted context omitted.

That looks so much like Elixir. for x IO.puts("FizzBuzz") [0, _] -> IO.puts("Fizz") [_, 0] -> IO.puts("Buzz") _ -> x end end

Any language that has pattern matching looks similar. Much nicer than if/else/switch.

Indeed both of those look so much like ML which predates them by a few decades.
Post reply on HN