RosettaCodeData/Task/Averages-Simple-moving-average/Delphi/averages-simple-moving-aver...

84 lines
1.6 KiB
ObjectPascal

program Simple_moving_average;
{$APPTYPE CONSOLE}
type
TMovingAverage = record
private
buffer: TArray<Double>;
head: Integer;
Capacity: Integer;
Count: Integer;
sum, fValue: Double;
public
constructor Create(aCapacity: Integer);
function Add(Value: Double): Double;
procedure Reset;
property Value: Double read fValue;
end;
{ TMovingAverage }
function TMovingAverage.Add(Value: Double): Double;
begin
head := (head + 1) mod Capacity;
sum := sum + Value - buffer[head];
buffer[head] := Value;
if count < capacity then
begin
inc(Count);
fValue := sum / count;
exit(fValue);
end;
fValue := sum / Capacity;
Result := fValue;
end;
constructor TMovingAverage.Create(aCapacity: Integer);
begin
Capacity := aCapacity;
SetLength(buffer, aCapacity);
Reset;
end;
procedure TMovingAverage.Reset;
var
i: integer;
begin
head := -1;
Count := 0;
sum := 0;
fValue := 0;
for i := 0 to High(buffer) do
buffer[i] := 0;
end;
var
avg3, avg5: TMovingAverage;
i: Integer;
begin
avg3 := TMovingAverage.Create(3);
avg5 := TMovingAverage.Create(5);
for i := 1 to 5 do
begin
write('Inserting ', i, ' into avg3 ', avg3.Add(i): 0: 4);
writeln(' Inserting ', i, ' into avg5 ', avg5.Add(i): 0: 4);
end;
for i := 5 downto 1 do
begin
write('Inserting ', i, ' into avg3 ', avg3.Add(i): 0: 4);
writeln(' Inserting ', i, ' into avg5 ', avg5.Add(i): 0: 4);
end;
avg3.Reset;
for i := 1 to 100000000 do
avg3.Add(i);
writeln('100''000''000 insertions ', avg3.Value: 0: 4);
Readln;
end.