Delphi 용 FizzBuzz 컬렉션 만들기

소개



이것은 FizzBuzz Advent Calendar 2017 모두 Delphi Advent Calendar 2017 모두 관계없는 기사입니다 (w

Delphi는 begin ~ end가 있기 때문에 코드를 극단적으로 짧게 쓰는 것은 약하지 않습니다. 코드 골프는 그 근처를 고려하지 않기 때문에 특정 언어가 항상 상위에 오는 경향이 있습니다. FizzBuzz도 예에 들지 않고, Delphi로 보통으로 쓰면 길어집니다...읽기 쉽지만.

그리고 어떤 메소드나 문법이 표준으로 구현되어 있는지에 짧게 쓸 수 있죠. 예를 들어 최소 공배수(LCM)나 삼항 연산자가 구현되어 있으면 짧게 쓸 수 있습니다.

그렇다면 ...

코드



FizzBuzz를 반환하는 컬렉션을 생각해보십시오. 코드는 이런 느낌으로 쓸 수 있으면 좋네요.
procedure TForm1.Button1Click(Sender: TObject);
var
  s: string;
begin
  Memo1.Clear;
  for s in FizzBuzz(100) do
    Memo1.Lines.Append(s);
end;

FizzBuzz가 나열되는 컬렉션을 사용하면 코드가 짧아집니다. 폼은 이런 느낌으로 버튼과 메모만이 붙어 있습니다.



구현은 이렇게 되었습니다. Delphi 2005 이상에서 작동한다고 생각합니다. 아마도 FPC에서도 작동 할 것입니다.

uFizzBuzzCollection.pas
unit uFizzBuzzCollection;

{$IFDEF FPC}
{$modeswitch ADVANCEDRECORDS}
{$ENDIF}

interface

uses
  SysUtils, Types;

type
  TFizzBuzzEnumerator = class;

  TFizzBuzz  = record
  private
    Ffrom: Integer;
    Fthrough: Integer;
  public
    constructor Create(from: Integer; through: Integer);
    function GetEnumerator: TFizzBuzzEnumerator;
  end;

  TFizzBuzzEnumerator = class
    Container: TFizzBuzz;
    Index: Integer;
  public
    constructor Create(AContainer : TFizzBuzz);
    function GetCurrent: string;
    function MoveNext: Boolean;
    property Current: string read GetCurrent;
  end;

  function FizzBuzz(from: Integer; through: Integer): TFizzBuzz; overload
  function FizzBuzz(Count: Integer): TFizzBuzz; overload;

implementation

function FizzBuzz(from, through: Integer): TFizzBuzz;
begin
  Result := TFizzBuzz.Create(from, through);
end;

function FizzBuzz(Count: Integer): TFizzBuzz;
begin
  Result := TFizzBuzz.Create(1, Count);
end;

{ TFizzBuzz }

constructor TFizzBuzz.Create(from, through: Integer);
begin
  Ffrom := from;
  Fthrough := through;
end;

function TFizzBuzz.GetEnumerator: TFizzBuzzEnumerator;
begin
  Result := TFizzBuzzEnumerator.Create(Self);
end;

{ TFizzBuzzEnumerator }

constructor TFizzBuzzEnumerator.Create(AContainer: TFizzBuzz);
begin
  inherited Create;
  Container := AContainer;
  Index := -1;
end;

function TFizzBuzzEnumerator.GetCurrent: string;
var
  v: Integer;
begin
  v := Container.Ffrom + Index;
  if ((v mod 3) +  (v mod 5)) = 0 then
    Result := 'Fizz Buzz'
  else if (v mod 3) = 0 then
    Result := 'Fizz'
  else if (v mod 5) = 0 then
    Result := 'Buzz'
  else
    Result := IntToStr(v);
end;

function TFizzBuzzEnumerator.MoveNext: Boolean;
begin
  result := False;
  if ((Container.Ffrom + Index + 1) > Container.Fthrough) then
    Exit;
  result := True;
  Inc(Index);
end;

end.

제대로 작동합니다!



결론



이제 Delphi에서도 FizzBuzz를 짧게 쓸 수 있게 되었습니다. 음, Delphi는 그 자리에서 변수를 선언할 수 없기 때문에 다른 언어로 FizzBuzz 컬렉션을 구현하면 그다지 의미는 없지만 (w

추가:
Delphi 10.3 Rio에서 변수의 인라인 선언이 가능합니다!
procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Clear;
  for var s in FizzBuzz(100) do
    Memo1.Lines.Append(s);
end;

형 추론도 있으므로 다소는 짧게 쓸 수 있게 되었습니다!

See Also:
  • Delphi 같은 for 루프를 쓰는 법 (거짓말) (DEKO 잡담)
  • for 문을 사용하여 컨테이너 반복 처리 (DocWiki)
  • 좋은 웹페이지 즐겨찾기