From: Ian Kelly on
On Tue, Jun 15, 2010 at 6:21 AM, Alain Ketterlin
<alain(a)dpt-info.u-strasbg.fr> wrote:
> You compute i**2 too many times (7/5 times more than necessary) and
> twice too many modulos. I suggest:
>
> c = { 0:1, 1:1, 2:1, 3:-1, 4:-1 }
> #or, why not: c = lambda i : +1 if (i%5) < 3 else -1
>
> s = 0
> for i in range(1,2011):
>    s += c[(i-1)%5]*(i**2)
> print s

In fact, most of them are unnecessary:

from itertools import izip, cycle

def squares(start, stop):
square = start * start
step = start * 2 + 1
for root in xrange(start, stop):
yield square
square += step
step += 2

print sum(sign * square for sign, square in izip(cycle([1,1,1,-1,-1]),
squares(1, 2011)))

Now, anybody know how to make that version a one-liner without making
it go quadratic in run-time?

Cheers,
Ian
From: Paul Rubin on
superpollo <utente(a)esempio.net> writes:
> goal (from e.c.m.): evaluate
> 1^2+2^2+3^2-4^2-5^2+6^2+7^2+8^2-9^2-10^2+...-2010^2, where each three
> consecutive + must be followed by two - (^ meaning ** in this context)

print sum([-1,1,1,1,-1][i%5]*i**2 for i in xrange(1,2011))
From: superpollo on
Paul Rubin ha scritto:
> superpollo <utente(a)esempio.net> writes:
>> goal (from e.c.m.): evaluate
>> 1^2+2^2+3^2-4^2-5^2+6^2+7^2+8^2-9^2-10^2+...-2010^2, where each three
>> consecutive + must be followed by two - (^ meaning ** in this context)
>
> print sum([-1,1,1,1,-1][i%5]*i**2 for i in xrange(1,2011))

beautiful.

thx
From: Ignacio Mondino on
On Tue, Jun 15, 2010 at 8:49 AM, superpollo <utente(a)esempio.net> wrote:
> goal (from e.c.m.): evaluate
> 1^2+2^2+3^2-4^2-5^2+6^2+7^2+8^2-9^2-10^2+...-2010^2, where each three
> consecutive + must be followed by two - (^ meaning ** in this context)
>
> my solution:
>
>>>> s = 0
>>>> for i in range(1, 2011):
> ...     s += i**2
> ...     if not (i+1)%5:
> ...         s -= 2*i**2
> ...     if not i%5:
> ...         s -= 2*i**2
> ...
>>>> print s
> 536926141
>>>>
>
> bye

I think This one is pretty, clean, using the standard library.
pretty pythonic.

def sign_and_sqr(n):
""" return a numbers square a change the sign accordingly
if n % 5 == 0 or (n + 1) % 5 == 0:
return (n ** 2) * -1
else:
return n ** 2

result = sum([sign_and_sqr(x) for x in range(0,2011)])
print result

ok, the function has two exits, but im lazy at the moment :)


--
---------------------------------------------------------------------------

Ignacio Mondino
Don't Panic
From: Alessandro [AkiRoss] Re on
On Jun 15, 1:49 pm, superpollo <ute...(a)esempio.net> wrote:
> goal (from e.c.m.): evaluate
> 1^2+2^2+3^2-4^2-5^2+6^2+7^2+8^2-9^2-10^2+...-2010^2, where each three
> consecutive + must be followed by two - (^ meaning ** in this context)


My functional approach :)

from operator import add
from functools import reduce

def square(l):
return (v**2 for v in l)

def sign(l, s):
i = 0
for v in l:
yield s[i % len(s)] * v
i += 1

print reduce(add, sign(square(xrange(1, 2011)), [1, 1, 1, -1, -1]))

(536926141)

~Aki