bashでFizzBuzzやってみた。

bashの設定を調べていたはずが、いつのまにかFizzBuzzを書いていたのでさらします。

#!/bin/bash

if [ $# -ne 1 ] ;then
    echo "You have to give 1 argument. : ./`basename $0` num"
    exit 1
fi

nums={1..$1}
nums=`eval echo $nums`

# Before refactoring
for num in $nums ;do
    if [ $((num % 3)) -eq 0 ]; then
        if [ $((num % 5)) -eq 0 ]; then
            echo "FizzBuzz"
        else
            echo "Fizz"
        fi
    else
        if [ $((num % 5)) -eq 0 ]; then
            echo "Buzz"
        else
            echo $num
        fi
    fi
done

なんだこれは。。。

        if [ $((num % 5)) -eq 0 ]; then

というコードが重複しているので 15を使って、分岐と一緒に取り除いてみます。

#!/bin/bash

(中略)

# After refactoring
# 先に15と比較するのは一致する確率が3に比べて低いので少し嫌
for num in $nums ;do 
    if [ $((num % 15)) -eq 0 ]; then
        echo "FizzBuzz"
    elif [ $((num % 3)) -eq 0 ]; then
        echo "Fizz"
    elif [ $((num % 5)) -eq 0 ]; then
        echo "Buzz"
    else
        echo $num
    fi  
done

ここで少し考えました。

  • FizzBuzzの問題文にない15という数字が出てくる。これは、3と5をかけるという演算をコードでなく人間がやってしまっている。これぐらいならいいが、業務システムで唐突に出現する、「どうしてこんな処理がっこに書かれているのか?」というのは、こういうことなんじゃないか、と。
  • 元の分岐だらけのコードの方がFizzBuzzの問題文どおりに書かれていて、実はこっちの方が読みやすいんじゃないかと。

というわけで、特にオチはありませんので、他の方の解答例をいくつか載せてお茶を濁します。ちょっとしたテクニックがシェルスクリプトならではという感じがして面白いですね。15をリテラルで使っている方もいますね。

時代遅れひとりFizzBuzz祭り /bin/sh編 | 新・日々録 by TRASH BOX@Eel
http://d.hatena.ne.jp/eel3/20100531/1275307408

FizzBuzz問題の解答例 bash編 | よしいずの雑記帳
http://yoshiiz.blog129.fc2.com/blog-entry-107.html

bashFizzBuzz | blog.paz-para.com
http://blog.paz-para.com/?p=1813

UNIXシェル入門 (エッセンシャルソフトウェアガイドブック)

UNIXシェル入門 (エッセンシャルソフトウェアガイドブック)