LoginSignup
10
5

More than 5 years have passed since last update.

fizzBuzz で Nim と Golang と Haskell を勉強する

Last updated at Posted at 2018-01-17

これまでは、PHP とか Ruby とかを書いてきましたので、まずは Golang, Nim で fizzBuzz してみます。
Haskell は全然勝手がわからなかったので、インストールから書いてみたいともいます。

Golang

go_fizz.go
package main

import (
        "bytes"
        "os"
        "strconv"
)

func main() {
        n := 1000000
        var buffer bytes.Buffer
        for i := 1; i <= n; i++ {
                if i%3 == 0 && i%5 == 0 {
                        buffer.WriteString("FizzBuzz\n")
                } else if i%3 == 0 {
                        buffer.WriteString("Fizz\n")
                } else if i%5 == 0 {
                        buffer.WriteString("Buzz\n")
                } else {
                        buffer.WriteString(strconv.Itoa(i))
                        buffer.WriteString("\n")
                }
        }
        os.Stdout.Write([]byte(buffer.String()))
}
$ go build -o go_fizz ./go_fizz.go
$ time ./go_fizz 1>/dev/null
./go_fizz > /dev/null  0.05s user 0.01s system 100% cpu 0.064 total

0.064 秒

Nim

nim_fizz.nim
let n = 1_000_000
var str = ""
for i in 1..n:
  if i mod 3 == 0 and i mod 5 == 0: str.add "FizzBuzz\n"
  elif i mod 3 == 0: str.add "Fizz\n"
  elif i mod 5 == 0: str.add "Buzz\n"
  else: str.add $i; str.add "\n"
write stdout, str
$ nim c -d:release nim_fizz.nim
$ time ./nim_fizz 1>/dev/null
./nim_fizz > /dev/null  0.05s user 0.01s system 91% cpu 0.061 total

0.061 秒

# 10回くらいまわしてみますか
$ time (for i in `seq 10`;do ./nim_fizz 1>/dev/null; done)
( for i in `seq 10`; do; ./nim_fizz > /dev/null; done; )  0.39s user 0.06s system 93% cpu 0.478 total

Haskell

Haskell はまずはインストールからです。

https://www.haskell.org/platform/mac.html
ドキュメントを辿ると Mac なら homebrew 使えるようなので、簡単です。

$ brew cask install haskell-platform

これだけで、 ghcirunghcghc も使えるようになりました 😀

hs_fizz.hs
main = fizzBuzz 1000000

fizzBuzz :: Integer -> IO()
fizzBuzz num = mapM_ (msg) [1..num]

msg :: Integer -> IO()
msg x
  | x `mod` 3 == 0 && x `mod` 5 == 0 = putStrLn "FizzBuzz"
  | x `mod` 3 == 0 = putStrLn "Fizz"
  | x `mod` 5 == 0 = putStrLn "Buzz"
  | otherwise = print x
$ ghc -o hs_fizz hs_fizz.hs
$ time ./hs_fizz 1>/dev/null
./hs_fizz > /dev/null  0.60s user 0.01s system 97% cpu 0.631 total

0.631 秒

ということで、僕の書いた、Haskell が Nim と Go と比べて 10倍くらい遅くなりました。

勉強しなくては、なりません。

以上、ありがとうございました。

追記1

ぼくに Nim を教えてくれた人が書いたもの。

fizz.nim
var
  str = ""
  i = uint(0)
while uint(1_000_000) > i:
  i.inc
  if   i mod 15 == 0: str.add("FizzBuzz\n")
  elif i mod  3 == 0: str.add("Fizz\n")
  elif i mod  5 == 0: str.add("Buzz\n")
  else:
    str.add($i)
    str.add("\n")
stdout.write(str)

追記2

Golang を早くする方法をおしえていただいた。

fizz.go
package main

import (
    "fmt"
    "strconv"
)

func main() {
    n := 10000000
    var m = make([]byte, 0, 10000000*60)
    var fb = "FizzBuzz\n"
    var f = "Fizz\n"
    var b = "Buzz\n"
    for i := 1; i <= n; i++ {
        fizz := i%3 == 0
        buzz := i%5 == 0
        if fizz && buzz {
            m = append(m, fb...)
        } else if fizz {
            m = append(m, f...)
        } else if buzz {
            m = append(m, b...)
        } else {
            m = append(m, strconv.FormatInt(int64(i), 10)...)
            m = append(m, "\n"...)
        }
    }
    fmt.Print(string(m))
}
10
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
5