2008年12月4日木曜日

MS-DOSバッチファイルでFizzBuzz

昨日の記事:VBScript で FizzBuzz の続編。
FizzBuzz、今度はDOSバッチファイルで作ってみた。
単純にやってみたかっただけなので、コードを短くする工夫とかはまあ置いておこう。
 
 

FizzBuzzをDOSバッチでやる際に、とりあえず剰余(mod)が取れるのかよく分からなかったので3の倍数、5の倍数を判断するカウンタをつくることにして書いてみた。
記事書く前に、本で算術演算子を調べたら、mod 取れるみたい…
100を3で割った余りなら、
> set /a hoge=100%3
でOKだった。まぁコレはコレでありかな。。

 

ちょっと引っかかったのが遅延展開、forの中で普通に変数 %hoge% って使うと、forの中でいくら中身をいじろうと、for に入る前の変数の中身が展開されちゃう。
setlocalで 遅延展開有効 にして、!hoge! って使えばfor内でもその時点の変数内容が展開される。
あとは特に工夫も無く。
[sourcecode language='sh']
@echo off

REM // 遅延展開有効
setlocal enabledelayedexpansion

REM // ウインドウタイトル変更
TITLE FizzBuzz

REM // カウントダウン用の変数
set SAN=3
set GO=5

REM // 繰り返し
for /l %%I in (1,1,100) do (

rem // 表示用の変数、空っぽ比較用も
set STRING=
set STRING_FLG=

rem // 3と5のカウンターが0ならリセット
if !SAN!==0 (set SAN=3)
if !GO!==0 (set GO=5)

rem // 3と5のカウンターを一つ減らす
set /a SAN=!SAN!-1
set /a GO=!GO!-1

rem // 3のカウンターが0なら表示用にFizz追加
if !SAN!==0 (set STRING=Fizz)

rem // 5のカウンターが0なら表示用にBuzz追加
if !GO!==0 (set STRING=!string!Buzz)

rem // ここでFizzもBuzzも入ってなければループ数字追加
if !STRING!==!STRING_FLG! (set STRING=!STRING!%%I)

rem // 現在の数と、FizzBuzzの結果を出力
echo %%I !STRING!
)
pause
endlocal
[/sourcecode]


実行結果。
[caption id="attachment_1099" align="alignnone" width="428" caption="画像:FizzBuzz"]画像:FizzBuzz[/caption]
 

デキター。
 

剰余の計算処理もちゃんと調べてればもう少しスマートだったが、まあ結果オーライという事にしよう。
set のヘルプに一応ヒントらしきものはあったが見逃した。
setの詳しい解説があった。