Object Pascal で FizzBuzz


FizzBuzz

「FizzBuzz をどれだけ短く書けるか」というブームが定期的にやってきます。
今まで作った FizzBuzz は

program FizzBuzz;
uses
  System.SysUtils;
var
  i: Integer;
  Values: array [0.. 3] of String = ('', 'Fizz', 'Buzz', 'FizzBuzz');
begin
  for i := 1 to 100 do 
  begin
    Values[0] := i.ToString;
    Writeln(Values[Ord(i mod 3 = 0) or (Ord(i mod 5 = 0) shl 1)]);
  end;
end.

こんなのや

program FizzBuzz;
uses
  System.SysUtils;
var
  i: Integer;
  S: array [0.. 2] of String = ('', 'Fizz', 'Buzz');
begin
  for i := 1 to 100 do
    Writeln(S[Ord(i mod 3 = 0)] + S[Ord(i mod 5 = 0) shl 1], i.ToString.Substring(0, (i mod 3) * (i mod 5) * $ff));
end.

こんなのがあります。

今回は DEKO さんの

このツイートによって、またブームが来ました。

Delphi で恐らく一番短い Fizz Buzz

今のところ、一番短いはず!
97 バイト!

var i:Byte;begin for i:=1to 100do Writeln(i,^m,Copy('Fizz',i mod 3*9)+Copy('Buzz',i mod 5*9))end.

清書すると

var
  i: Byte;
begin
  for i := 1 to 100 do
    Writeln(i, ^m, Copy('Fizz', i mod 3 * 9) + Copy('Buzz', i mod 5 * 9))
end.

こんな感じ。

コード中の ^m は、コントロールコードを書く古い書き方です。
^m = #13 = CR です。
キャリッジリターンで先頭まで戻るのがポイント。

なお、'Fizz' の所を 'Fizz ' にすると "Fizz Buzz" と間にスペースを入れられます。
そうすると 98 バイトになります。

Val バージョン

また、試行錯誤の最中に Val を使うと計算しなくて済むことに気がつきました。
Delphi だと Copy の第三引数は省略できるのですが、Ideone / FreePascal でも動くように第三引数も書きました。
Ideone 上のコードはこちら

program FizzBuzz;
var
  S: String;
  i, R, C: Integer;
begin
  for i := 1 to 100 do
  begin
    Str(i, S);
    S := S + Copy('Fizz', i mod 3 * 9, 4) + Copy('Buzz', i mod 5 * 9, 4);
    Val(S, R, C);
    Writeln(Copy(S, C, 8));
  end;
end.

まとめ

Val とか Str とか ^ 記法とか、古の技術がコードゴルフには役に立つのだ…
そして、FizzBuzz は永遠のテーマ…

求む!挑戦者!