プログラミング Elixir を読んでいます。

- 作者: Dave Thomas,笹田耕一,鳥井雪
- 出版社/メーカー: オーム社
- 発売日: 2016/08/19
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (3件) を見る
Elixir
プログラミング Elixir の第5章で FizzBuzz を書く練習問題が出てきます。
# $ elixir fizz_buzz.exs fizzBuzz3 = fn 0, 0, _ -> "FizzBuzz" 0, _, _ -> "Fizz" _, 0, _ -> "Buzz" _, _, n -> "#{n}" end fizzBuzz = fn n -> fizzBuzz3.(rem(n, 3), rem(n, 5), n) end fizzBuzzSeries = fn first, last -> first..last |> Enum.map(fizzBuzz) end fizzBuzzSeries.(1, 20) |> Enum.join("\n") |> IO.puts
Erlang
VM は同じでもシンタクスが違うので見た目が結構違って見えます。
% $ erlc fizz_buzz.erl % $ erl -run fizz_buzz main -module(fizz_buzz). -export([main/0]). fizz_buzz(0, 0, _) -> "FizzBuzz"; fizz_buzz(0, _, _) -> "Fizz"; fizz_buzz(_, 0, _) -> "Buzz"; fizz_buzz(_, _, N) -> integer_to_list(N). fizz_buzz(N) -> fizz_buzz(N rem 3, N rem 5, N). fizz_buzz_series(First, Last) -> [fizz_buzz(N) || N <- lists:seq(First, Last)]. main() -> lists:map(fun(S) -> io:format("~s~n", [S]) end, fizz_buzz_series(1, 20)), erlang:halt(0).
Haskell
Haskell で書いてもほぼ同じ。
-- $ ghc --make fizz_buzz -- $ ./fizz_buzz fizzBuzz3 0 0 _ = "FizzBuzz" fizzBuzz3 0 _ _ = "Fizz" fizzBuzz3 _ 0 _ = "Buzz" fizzBuzz3 _ _ n = show n fizzBuzz n = fizzBuzz3 (n `mod` 3) (n `mod` 5) n fizzBuzzeSeries = [ fizzBuzz n | n <- [1..20]] main = putStrLn $ unlines fizzBuzzeSeries
Prolog
関数でなく述語で表現するのでまた違った印象。
% $ gprolog --consult-file fizz_buzz.pro --entry-goal main fizz_buzz(0, 0, _, "FizzBuzz") :- !. fizz_buzz(0, _, _, "Fizz") :- !. fizz_buzz(_, 0, _, "Buzz") :- !. fizz_buzz(_, _, N, S) :- number_codes(N, S), !. fizz_buzz(N, S) :- N3 is N rem 3, N5 is N rem 5, fizz_buzz(N3, N5, N, S). fizz_buzz_series(First, Last, FBS) :- findall(FB, (between(First, Last, N), fizz_buzz(N, FB)), FBS). puts(S) :- format("~s~n", [S]). main :- fizz_buzz_series(1, 20, FBS), maplist(puts, FBS), halt.
Ruby
Ruby はメソッドのレベルでのパタンマッチの機能が今はないので、case
を使ってそれっぽく書いてみる。
# $ ruby fizz_buzz.rb def fizz_buzz3(n3, n5, n) case [n3, n5, n] when [0, 0, n] then 'FizzBuzz' when [0, n5, n] then 'Fizz' when [n3, 0, n] then 'Buzz' else "#{n}" end end def fizz_buzz(n) fizz_buzz3(n % 3, n % 5, n) end def fizz_buzz_series(first, last) (first..last).map {|n| fizz_buzz(n) } end puts fizz_buzz_series(1, 20).join("\n")
C++ Template Metaprograming
パタンマッチングは、C++ にはないけれども C++ Template では使える。コード量が多いのが難点。
// $ g++ --std=c++11 -o fizz_buzz fizz_buzz.cpp // $ ./fizz_buzz #include <string> #include <iostream> #include <algorithm> template<int N1, int N2, int N3> struct FizzBuzz3 { static const std::string value; }; template<int N3> struct FizzBuzz3<0, 0, N3> { static const std::string value; }; template<int N2, int N3> struct FizzBuzz3<0, N2, N3> { static const std::string value; }; template<int N1, int N3> struct FizzBuzz3<N1, 0, N3> { static const std::string value; }; template<int N1, int N2, int N3> const std::string FizzBuzz3<N1, N2, N3>::value = std::to_string(N3); template<int N3> const std::string FizzBuzz3<0, 0, N3>::value = "FizzBuzz"; template<int N2, int N3> const std::string FizzBuzz3<0, N2, N3>::value = "Fizz"; template<int N1, int N3> const std::string FizzBuzz3<N1, 0, N3>::value = "Buzz"; template<int N> struct FizzBuzz { static const std::string value; }; template<int N> const std::string FizzBuzz<N>::value = FizzBuzz3<N % 3, N % 5, N>::value; struct Nil; template<template<int> class T, int First, int Last> struct Range { typedef T<First> Head; typedef Range<T, First + 1, Last> Tail; }; template<template<int> class T, int Last> struct Range<T, Last, Last> { typedef T<Last> Head; typedef Nil Tail; }; template<int First, int Last> using FizzBuzzSeries = Range<FizzBuzz, First, Last>; template<typename R> void puts_range() { std::cout << R::Head::value << std::endl; puts_range<typename R::Tail>(); } template<> void puts_range<Nil>() {}; int main(int, char* []) { puts_range<FizzBuzzSeries<1, 20> >(); return 0; }
いつか読むはずっと読まない:バイク乗りがバイクになる(なりません)
一年半ほど前からクロスバイクに乗るようになりました。十ン年まともに運動などしたことがなかった人間が面白いぐらいにのめり込んでいます。
以前だったらアンテナにさえかからなかっただろう本書、今は描写の一つ一つに反応してしまっています。

- 作者: 米津一成
- 出版社/メーカー: 徳間書店
- 発売日: 2015/03/06
- メディア: 文庫
- この商品を含むブログ (3件) を見る