среда, 26 января 2011 г.

FizzBuzz

Прочитал тут про задачку, которую дают "тру" программистам при собеседовании: надо написать программу, которая выводит на экран числа от 1 до 100. При этом вместо чисел, кратных трем, программа должна выводить слово «Fizz», а вместо чисел, кратных пяти — слово «Buzz». Если число кратно и 3, и 5, то программа должна выводить слово «FizzBuzz»

Я не тру програмист :), поэтому решил бы так:

unit FizzBuzz;

interface

uses
  windows, sysutils;

type
  EFizzBuzzLessZero = class (Exception);
  EFizzBuzzTooBig = class (Exception);

  TFizzBuzz = class
  const
    MAX_VAL = 100;
  private
    FCount: integer;
  public
    constructor Create (const ACount: integer);

    function Execute: HResult;
  end;

implementation

{ TFizzBuzz }

constructor TFizzBuzz.Create(const ACount: integer);
begin
  FCount := ACount;
end;

function TFizzBuzz.Execute: HResult;
type
  TNumberType = (ntUsual, ntFizz, ntBuzz, ntComplex);
var
  x: integer;
  r: TNumberType;
begin
  try
    if FCount <= 0 then
      raise EFizzBuzzLessZero.Create('Invalid argument')
    else if FCount > MAX_VAL then
      raise EFizzBuzzTooBig.Create('Invalid argument')
    else begin
      for x := 1 to FCount do
      begin
        r := ntUsual;
        if x mod 3 = 0 then
          r := ntFizz;
        if (x mod 5) = 0 then
          if r = ntFizz then
            r := ntComplex else
            r := ntBuzz;

        case r of
          ntUsual: Writeln(x);
          ntFizz: Writeln('Fizz');
          ntBuzz: Writeln('Buzz');
          ntComplex: Writeln('FizzBuzz');
        end;
      end;
    end;

    Result := S_OK;
  except
    on e: EFizzBuzzLessZero do
    begin
      Writeln('Value cannot be less or equal to zero!');
      Result := E_INVALIDARG;
    end;
    on e: EFizzBuzzTooBig do
    begin
      Writeln('Too big value to calculating!');
      Result := E_INVALIDARG;
    end;
    on e: Exception do
    begin
      Writeln('Unexpected error in Execute (', e.Message, ')');
      Result := E_FAIL;
    end;
  end;
end;

end.

И

program Project1;

{$APPTYPE CONSOLE}

uses
  windows,
  SysUtils,
  FizzBuzz in 'FizzBuzz.pas';

var
  fb: TFizzBuzz;
begin
  try
    if ParamCount < 1 then
      raise Exception.Create('Not enought parameters');

    fb := TFizzBuzz.Create(StrToIntDef(ParamStr(1), 100));
    try
      if Failed(fb.Execute) then
        raise Exception.Create('Something wrong with calculating FIZZBUZZ..');
    finally
      fb.Free;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Только что-то мне кажется, тут не в лоб ожидается решение, результат:

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

наводит на то, что закономерность надо “обыграть”

Хотя для жизни – пока я буду искать эту закономерность, я мог бы в лоб все сделать и дальше чем-то заняться.. Ну не художник вот я, не художник :-/

Комментариев нет:

Отправить комментарий