Skip to content

Instantly share code, notes, and snippets.

@JunichiIto
Created December 13, 2016 01:40
Show Gist options
  • Save JunichiIto/324653160ea6278a19ce61fbdb611921 to your computer and use it in GitHub Desktop.
Save JunichiIto/324653160ea6278a19ce61fbdb611921 to your computer and use it in GitHub Desktop.
Rubyで書く変なFizzBuzz (Strange FizzBuzz function in Ruby)
fizz_buzz = -> (n) do
f = -> (cond, ans, nxt, n) { n % cond == 0 ? ans : nxt.(n) }.curry
patterns = [[n, n.to_s], [5, 'Buzz'], [3, 'Fizz'], [15, 'Fizz Buzz']]
patterns.inject(nil) { |nxt, (cond, ans)| f.(cond, ans, nxt) }.(n)
end
(1..20).map(&fizz_buzz)
=begin
[
[ 0] "1",
[ 1] "2",
[ 2] "Fizz",
[ 3] "4",
[ 4] "Buzz",
[ 5] "Fizz",
[ 6] "7",
[ 7] "8",
[ 8] "Fizz",
[ 9] "Buzz",
[10] "11",
[11] "Fizz",
[12] "13",
[13] "14",
[14] "Fizz Buzz",
[15] "16",
[16] "17",
[17] "Fizz",
[18] "19",
[19] "Buzz"
]
=end
@tkawa
Copy link

tkawa commented Dec 13, 2016

patterns はほとんど形が同じなので fizz_buzz の外に出せるんじゃないかなと思って、できるだけ関数を使う関数型の気持ち(?)で書き換えてみました。(本当は関数型よくわかってない)
わかりやすくなっているかどうかは不明です。。

mod_zero = ->(m, n) { n % m == 0 }.curry
always = ->(m, n) { m }.curry
f = -> (cond, ans, nxt, n) { cond.(n) ? ans.(n) : nxt.(n) }.curry
patterns = [
  [always.(true), :to_s.to_proc],
  [mod_zero.(5), always.('Buzz')],
  [mod_zero.(3), always.('Fizz')],
  [mod_zero.(15), always.('Fizz Buzz')]
]
fizz_buzz = patterns.inject(nil) { |nxt, (cond, ans)| f.(cond, ans, nxt) }

@akihitofujiwara
Copy link

akihitofujiwara commented Dec 14, 2016

rubyでこんなん書けるんですね。。すごい。
yuroyoroって人がrubyで関数型頑張ってるの見たことあります。

誰も期待していないLiveScriptでのFizzBuzzを。

無駄の多い実装ですが面白い方向性として。。

map = (f, xs)--> [f x for x in xs]
always = (x, y)--> x
when_ = (f, g, x)--> if f x then g x else x
fizz = when_ (% 3) >> (is 0), (always \Fizz)
buzz = when_ (% 5) >> (is 0), (always \Buzz)
fizzbuzz = when_ (% 15) >> (is 0), (always \FizzBuzz)

[1 to 30] |> map fizzbuzz >> buzz >> fizz

@tkawa
Copy link

tkawa commented Dec 15, 2016

関数合成使いたい!  LiveScriptうらやましい。。
もう1個書いてみました。

adder = ->(m, n) { n + m }.curry
id = ->(n) { n }
blanker = ->(n) { '' }
fizz_blanker = [id, id, blanker].cycle
buzz_blanker = [id, id, id, id, blanker].cycle
fizzer = [id, id, adder.('Fizz')].cycle
buzzer = [id, id, id, id, adder.('Buzz')].cycle
stringizer = [:to_s.to_proc].cycle

(1..20).zip(fizz_blanker, buzz_blanker, fizzer, buzzer, stringizer).map { |a| a.reduce { |n, f| f.(n) } }

ちょっとだけ関数型勉強したいと思って [翻訳] Elixirで書く関数型FizzBuzz - Qiita を読んでRubyにしてみた感じです。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment