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?

Dan Oberlam
8,0492 gold badges33 silver badges74 bronze badges
asked Sep 11, 2020 at 17:27
\$\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.)

answered Sep 11, 2020 at 17:58
\$\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.
answered Sep 11, 2020 at 18:18
\$\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!

answered Sep 11, 2020 at 18:36
\$\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

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.