2
\$\begingroup\$

I need to calculate the value for the following function:

$$f(n) = -1 + 2 - 3 + ... + -1^n$$

The time limit to calculate a given value of \$n\$ is less than 1 second. My approach does not meet that requirement at large sizes, for example \$f(1000000000)\$.

My code:

program A486;
uses wincrt, sysutils;

var
    n: LongInt;

function f(n : LongInt): LongInt;
var
    i : LongInt;
    //Result : LongInt;
begin
    Result:= 0;
    for i:= 1 to n do 
        if i mod 2 = 0 then
            Result += i
        else
            Result -= i;
    //f:= Result;           
end;

begin
    readln(n);
    writeln(f(n));
    //readkey()
end. 

Is there a better way I can do this?

\$\endgroup\$

3 Answers 3

1
\$\begingroup\$

Seems trivial. Pair them, each pair is worth -1.

f(1000) =  1 - 2  +  3 - 4  + ... +  999 - 1000
        = (1 - 2) + (3 - 4) + ... + (999 - 1000)
        =   -1        -1    + ... +     -1
        = -500

Odd n left as exercise for the reader.

(I wrote this when the question title still said "1 − 2 + 3 − 4 + · · ·", can't be bothered to switch all signs now.)

\$\endgroup\$
0
0
\$\begingroup\$

According to the help of Mr Andreas, i have come up with this code, which was helpful, but it gave a runtime error, in this test : 1000000000000000, I have to disapprove the answer as it wasn't the best performance. But i still greatly thank you for your attention.

code :

program A486;
uses wincrt, sysutils;

var
    n: LongInt;

function f(n : LongInt): LongInt;
var
    {Result,} SumOdd, SumEven : LongInt;
begin
    Result:=0; SumOdd:=0; SumEven:=0; 
    if n mod 2 = 0 then
    begin   
        SumOdd:=( n*(n div 2) ) div 2;
        SumEven:=((2+n)*(n div 2) ) div 2;
        Result:= SumOdd - SumEven;
    end else 
        begin
            SumOdd:=( (n+1)*(n div 2 + 1) ) div 2;
            SumEven:=((n+1)*(n div 2) ) div 2;
            Result:= SumOdd - SumEven;              
        end;    
    //f:= Result;   
end;

begin
    readln(n);
    writeln(f(n));
    //readkey()
end.
\$\endgroup\$
0
\$\begingroup\$

As far as we discussed it, this is the most efficient answer found:

program A486;
uses wincrt, sysutils;

var
    n: LongInt;

function f(n : LongInt): LongInt;
//var
    //Result : LongInt;
begin
    Result:=0; 
    if n mod 2 = 0 then
        Result:= n div 2
    else 
        Result:= (n div 2) - n;

    //f:= Result;   
end;

begin
    readln(n);
    writeln(f(n));
    //readkey()
end. 

thanks for everyone helped!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ It might not speed up your code but you could rewrite that whole if statement as -1^(n % 2) * ceiling(n / 2) The pattern to your problem is that results go -1, 1, -2, 2, -3, 3, ... -roundUp(n / 2), roudUp(n / 2). Odd numbers mod 2 are always 1 and even numbers mod 2 are 0 so -1^(n mod 2) will keep alternating the negative sign for you and roundUp(n / 2) gives you the int value at each step \$\endgroup\$ Commented Sep 11, 2020 at 22:31
  • 1
    \$\begingroup\$ how about Result := (n shr 1) - n * (n and 1);? \$\endgroup\$ Commented Sep 22, 2020 at 17:41

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.