なんとなく、余剰計算しているのが気に入らなかったので、余剰計算なしのFizzBuzzというものを考えてみた。


まとめたものをGistに上げました。

  • 今回はワンライナーではありません
  • 中間ファイルあり。
  • サブルーチンを使用するためにBATファイルにしないといけませんでした(>_<)
  • ぜんぶコマンドラインでやりたかったよぅ。。。
では、解説をば。
まず、1~100の数列を生成
1
2
for /L %i in (1,1,100) do @echo %i 4 %i>>Seq.txt

実行結果

1
2
3
4
5
6
1 4 1
2 4 2
3 4 3
※中略
99 4 99
100 4 100

※わかりにくいかもしれないけど、2列目はあとで第二ソートキーとして使用します。
次に、3nの数列を生成

1
2
for /L %i in (3,3,100) do @echo %i 3 Fizz>>Fizz.txt

実行結果

1
2
3
4
5
6
3 3 Fizz
6 3 Fizz
9 3 Fizz
※中略
96 3 Fizz
99 3 Fizz

次に、5nの数列を生成
1
2
for /L %i in (5,5,100) do @echo %i 2 Buzz>>Buzz.txt

実行結果

1
2
3
4
5
6
5 2 Buzz
10 2 Buzz
15 2 Buzz
※中略
95 2 Buzz
100 2 Buzz

実は15nの数列も作らなきゃだった
1
2
for /L %i in (15,15,100) do @echo %i 1 FizzBuzz>>FizzBuzz.txt

実行結果

1
2
3
4
5
6
15 1 FizzBuzz
30 1 FizzBuzz
45 1 FizzBuzz
60 1 FizzBuzz
75 1 FizzBuzz
90 1 FizzBuzz

4つのファイルをマージしてソート
1
2
3
4
copy Seq.txt+Fizz.txt+Buzz.txt+FizzBuzz.txt merge.txt /B
for /f "usebackq tokens=1,2,3" %a in ("merge.txt") do @(if %a lss 10 (echo 00%a %b %c) else if %a lss 100 (echo 0%a %b %c) else echo %a %b %c) >>merge.pass.txt
sort merge.pass /O merge.pass.sort.txt

実行結果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
001 4 1
002 4 2
003 3 Fizz
003 4 3
004 4 4
005 2 Buzz
005 4 5
※中略
098 4 98
099 3 Fizz
099 4 99
100 2 Buzz
100 4 100

uniqして仕上げ
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
for /f "usebackq tokens=1,2,3" %a in ("merge.pass.sort.txt") do @(
    call :uniq %a %c) >>out.txt

exit/b

rem subroutine
:uniq
rem %1 … key
rem %2 … data
    if not "%PREV%"=="%1" (
        set PREV=%1
        echo %2
    )
exit /b

実行結果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
※以下略

uniqコマンドを自作していれば、もう少し簡単に出来ます。
素のBATだけでやると、結構無理がある感じ。