6

The most elegant implementation of FizzBuzz

 4 years ago
source link: https://blog.klipse.tech/clojure/2020/09/11/fizbuzz-clj.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

The most elegant implementation of FizzBuzz

Sep 11, 2020 • Yehonathan Sharvit

What is FizzBuzz?

The FizzBuzz test is an interview question designed to help filter out the 99.5% of programming job candidates who can’t seem to program their way out of a wet paper bag. The text of the programming assignment is as follows:

Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”

There are a lot of ways to write the FizzBuzz program. See for instance the one using Clojure pattern matching. Today, I’d like to share with you the most elegant implementation of FizzBuzz I’ve ever seen. It’s elegant because it doesn’t make use of any imperative constructs (like if statements), but only functional programming constructs (like infinite lazy sequences and function composition).

Pure

This implementation was developed by Dierk Konig and Kevlin Henney presented a Haskell version of it - in his amazing talk Declarative Thinking, Declarative Practice.

In this article, we are going to present an interactive version of Kevlin’s code in Clojure.

The elegant code

Take a look at this marvel: no if statements - only 3 infinite lazy sequences and function composition.

This is exactly what we call - Purely Functional:

xxxxxxxxxx
;loaded from gist: https://gist.github.com/viebel/b133efde8669d6c0630ee6895c1797c6
(defn choice [a b]
  (clojure.string/join (or (seq a) (seq b))))
(defn fizzbuzz [n]
  (let [fizzes (cycle ["" "" "Fizz"])
        buzzes (cycle ["" "" "" "" "Buzz"])
        words (map str fizzes buzzes)
        numbers (map str (rest (range)))]
    (take n (map max words numbers))))
the evaluation will appear here (soon)...

And it works like a charm:

xxxxxxxxxx
(fizzbuzz 19)
xxxxxxxxxx
the evaluation will appear here (soon)...

Feel free to modify 19 - the code snippets are live and interactive powered by the Klipse plugin:

  1. Live: The code is executed in your browser
  2. Interactive: You can modify the code and it is evaluated as you type

If you are a bit skeptic (yet) about the elegance of this implementation, you might want to read Dierk Konig’s article: he explains in details the pragmatic advantages of his code.

Further details

You probably wonder what is this choice function and why does max do when it receives 2 strings?

Well, ClojureScript runs on top of JavaScript - and in JavaScript, strings are comparable:

xxxxxxxxxx
(> "Fizz" "")
xxxxxxxxxx
the evaluation will appear here (soon)...
xxxxxxxxxx
(max "Fizz" "")
xxxxxxxxxx
the evaluation will appear here (soon)...

But that is an ugly trick - that doesn’t work in Clojure. So it’s much better to use the choice function - that returns the first non-empty string of the two it receives:

xxxxxxxxxx
(choice "abc" "")
xxxxxxxxxx
the evaluation will appear here (soon)...

And it works also:

(fizzbuzz-clean 15)
If you enjoy this kind of interactive articles would you consider a (small) donation? on Patreon or at least giving a star⭐ for the Klispe repo on Github?

to stay up-to-date with the coolest interactive articles around the world.

Discover more cool interactive articles about javascript, clojure[script], python, ruby, scheme, c++ and even brainfuck!

Give Klipse a Github star to express how much you appreciate Code Interactivity.

Subscribe to the Klipse newsletter:

Feel free to email me [email protected] for getting practical tips and tricks in writing your first interactive blog post.


Recommend

  • 48

    Posted on September 23, 2018 by Sol The famous FizzBuzz interview question asks to print all numbers from 1 to 100. If a number is divisible with 3 print

  • 26

    Recently, I have given a workshop about language features introduced in C++14 and C++17. Since a major part of those features includes constexpr things, I gave my trainees the task to port “FizzBuzz” to comp...

  • 61
    • Github github.com 5 years ago
    • Cache

    FizzBuzz purely in Rust's trait system

    trait_eval We all know Rust's trait system is Turing complete, so tell me, why aren't we exploiting this??? Who needs const-fn when we've got a crate like this?! Honestly...

  • 18
    • insights.thoughtworks.cn 5 years ago
    • Cache

    FizzBuzz与写代码的“一万”个细节

    技术是由一万个细节组成的,哪怕一个这么简单的题目,也有如此多的点。我也不敢说自己是什么高手,起码写了许多年代码,也就把自己写代码的思维展示给大家,希望对有心人有所帮助。 非初学者向,虽然题是个简单的题,但要求读者...

  • 26

    FizzBuzz与写代码的“一万”个细节 2020年6月20日 by 仝键

  • 12
    • blog.ielliott.io 4 years ago
    • Cache

    The Programming Thought Process: Fizzbuzz

    The Programming Thought Process: Fizzbuzz 04 March 2015 With so many programming languages and frameworks at our disposal, it is too easy to believe that knowledge of many tools is the defining characteristic of a go...

  • 14
    • greyli.com 4 years ago
    • Cache

    FizzBuzz问题

    FizzBuzz问题 发表回复 之前在Medium上看到一篇文章,作者提到了FizzBuzz的问题,问题是这样的: 在1到100的数字中,能被3整除的变为“Fizz”,能被5整除的变...

  • 14
    • rachelbythebay.com 4 years ago
    • Cache

    FizzBuzz handled 8-bit style

    FizzBuzz handled 8-bit style Much has been said about using FizzBuzz as a screening tool for programming interviews. The theory is basically that you can hand someone...

  • 5
    • ryxcommar.com 4 years ago
    • Cache

    FizzBuzz, Redux

    FizzBuzz, Redux – r y x, rSkip to content r y x, r the only blog o...

  • 4
    • tech.marksblogg.com 3 years ago
    • Cache

    The Fastest FizzBuzz Implementation

    Mark Litwintschik I have 15 years of consulting & hands-on build experience with clients in the UK, USA, Sweden, Ireland & Germany. Past cl...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK