Tcl・R・Golang・RustなどでFizzBuzzやった時のメモ・感想
学部のとある講義に参加させてもらった際にいろいろな言語でFizzBuzzを書くことをしていた。
本稿はその時のメモや感想。
(別の回ではPostScriptで書いてたとか…)
扱った言語は以下。
- Tcl
- R
- Golang
- Rust
- ZSH
- SQLite3
- Ruby
ZSHやSQLite3、Ruby以外は全て初めて触った。
上記の3つの言語は書き方に工夫されていたが、琴線に触れたのは、
SQLite3だけだったのでそちらだけ記載。
Tcl
インストール
$ apt install tcl-dev/stable
サンプルコード
#!/usr/bin/tclsh
for {set i 1} {$i <= 40} {incr i} {
if {$i%15==0} {
puts FizzBuzz
} elseif {$i%5==0} {
puts Buzz
} elseif ($i%3==0) {
puts Fizz
} else {
puts $i
}
}
初っ端がTclなのはだいぶハードルが高かった。
基本文字列型しかなく、文字列を書くのにクォートなしでも良いのが特徴的。
ブランクを入れる時はクォートが必要。クォートが{}とかいうのが…(-_-;)
演算をする際はexprを使う必要があるようだが、
ifの条件式の場合はexprなしでも良いようだった(バージョンによる?)。
{}と{}の間にブランクがないと構文エラーとかになるのも慣れなかった。
R
FizzBuzz書くぐらいならシンプルだった。
インストール
$ apt install r-base/stable
サンプルコード
#!/usr/bin/Rscript
for (i in 1:40) {
if (i%%15==0){
print("FizzBuzz")
}else if (i%%5==0){
print("Buzz")
}else if (i%%3==0){
print("Fizz")
}else{
print(i)
}
}
上記のコードでは全行に[1]が出るのが特徴だった。
なんでも入力や出力のデータ数が頭につくらしい。
以下のように対話的にscan()を実行すると分かりやすかったが。
> scan()
1: 1 2 3
4: 4 5 6 7 8
9: 9 10
11:
Read 10 items
[1] 1 2 3 4 5 6 7 8 9 10
Golang
インストール
$ wget https://redirector.gvt1.com/edgedl/go/go1.9.2.linux-amd64.tar.gz
$ tar -C /usr/local -xzf go1.9.2.linux-amd64.tar.gz
実行方法
$ /usr/local/go/bin/go run fizzbuzz.go
ビルドしてから実行する場合は以下。
$ /usr/local/go/bin/go build fizzbuzz.go
$ ./fizzbuzz
他のサブコマンドは、cleanとfmtを試した。
cleanはmakeやmvnのclean的な用途で、fmtはインデントの修正。
(スタイルが統一されるのは個人的には好感が持てた)
サンプルコード
以下のページを参考にするだけでイケた。
package main
import (
"fmt"
)
func main() {
var i int = 0
for i = 1; i < 40; i++ {
if i%15 == 0 {
fmt.Println("FizzBuzz")
} else if i%5 == 0 {
fmt.Println("Buzz")
} else if i%3 == 0 {
fmt.Println("Fizz")
} else {
fmt.Println(i)
}
}
}
以前本で読んで型を後ろに書くのは知ってたので、
それほど抵抗はなかった。
ビルドした際にライブラリなどが取り込まれたのは結構びっくりしたところ。
ぐぐったらこんな記事見つかった。
チャンネルとか触ると難しい? 名前しか知らないが。
Rust
インストール
$ curl https://sh.rustup.rs -sSf | sh
プロジェクトセットアップ
$ USER=yhornisse $HOME/.cargo/bin/cargo new hello
rootでやってUSERが空だとエラーになった。
$ USER=yhornisse $HOME/.cargo/bin/cargo run src/main.rs
サンプルコード
fn main() {
for i in 1..40 {
if (i%15==0){
println!("FizzBuzz");
}else if (i%3==0){
println!("Fizz");
}else if (i%5==0){
println!("Buzz");
}else{
println!("{}", i);
}
}
}
FizzBuzzレベルなら比較的簡単だったが、いろいろやろうとするとなかなか厄介だった。
特に所有権周りは、ぱっと見て分かるようなものではなかった。
また、変数定義(let)のデフォルトは定数らしく、
可変(mutable)にするにはmutを指定する必要があるとか。
(変数定義と言っていいか微妙だが)
let mut i = 0;
SQL (SQLite3)
サンプルコード
講義の中では手続き型っぽくない書き方も出たが、
そちらは自分の琴線に触れなかった。
それよりもWITHを使った再帰が衝撃的だったのでそちらを記載。
WITH num AS (
SELECT 1 AS n
UNION ALL
SELECT n+1 FROM num WHERE n < 40
)
SELECT
CASE
WHEN n%15==0 THEN
'FizzBuzz'
WHEN n%5==0 THEN
'Buzz'
WHEN n%3==0 THEN
'Fizz'
ELSE
n
END
FROM
num
ORDER BY '0' & n /* SQLiteだと全て文字列なので */