#前置き
『FizzBuzzを1byteで実装する』という記事を読んだので、それを参考として、しばらくぶりに Fortran でFizzBuzz をやってみました。
https://qiita.com/ymg_aq/items/b8e5d26035180bc8797e
以前やった FizzBuzz は長めw
『4桁までしかできない FizzBuzz』
https://qiita.com/cure_honey/items/d5b23f75365b2d610692
#今回のアイデア
今回のアイデアは、FORMAT 指定子の絶対位置タブを使って、数字を書き出した後に t1 で書きだし位置をカラム1に戻して、もしその後に文字列があれば上書きして書き出すというものです。
ここで部分文字列は 'text'(1:0) などのように終端位置が開始位置より前にあると、空白文字ではなく NULL 文字列になるという性質と組み合わせます。NULL の場合数字が上書きされずに残ります。
これらによって、数字と文字の切り替えを実現します。
##ソースコード Fortran2008
###案1 75文字
print'(g0,t1a)',(i,'Fizz'(5**mod(i,3):)//'Buzz'(5**mod(i,5):),i=1,100);end
format 指定子の解釈が処理系によってブレがあるのですが、gfortran なら (g0t1a) と続けても大丈夫です。1文字減ります。intel fortran は g0 の後に , が無いと駄目です。g0 は i0 でも大丈夫です。
###案2 76文字
do 1 i=1,100;1 print'(g0,t1,2a)',i,pack(['Fizz','Buzz'],0==mod(i,[3,5]));end
全配列操作を使って mod の反復を無くしてみました。pack 関数を使ったため do loop にする必要が出てしまいました。gfortran の場合 行番号ラベルのあと空白が必要です。intel fortran は空白が要らないので1文字減ります。
###案3 78文字
print'(g0,t1a)',(i,'FizzBuzz'(5-4*2**mod(-i,3):4+4*2**mod(-i,5)),i=1,100);end
文字列 'FizzBuzz' を分割せずに始点と終点を変える形にしてみました。関数をもっと簡潔に出来るかもしれません。
以上、今朝布団の中で更に考えてみましたが、この辺で煮詰まりました。
##実行結果
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
31
32
Fizz
34
Buzz
Fizz
37
38
Fizz
Buzz
41
Fizz
43
44
FizzBuzz
46
47
Fizz
49
Buzz
Fizz
52
53
Fizz
Buzz
56
Fizz
58
59
FizzBuzz
61
62
Fizz
64
Buzz
Fizz
67
68
Fizz
Buzz
71
Fizz
73
74
FizzBuzz
76
77
Fizz
79
Buzz
Fizz
82
83
Fizz
Buzz
86
Fizz
88
89
FizzBuzz
91
92
Fizz
94
Buzz
Fizz
97
98
Fizz
Buzz
続行するには何かキーを押してください . . .