From: Ian Kelly on 15 Jun 2010 12:26 On Tue, Jun 15, 2010 at 6:21 AM, Alain Ketterlin 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 15 Jun 2010 14:41 superpollo 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 15 Jun 2010 14:48 Paul Rubin ha scritto:> superpollo 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 15 Jun 2010 20:13 On Tue, Jun 15, 2010 at 8:49 AM, superpollo 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 16 Jun 2010 06:35 On Jun 15, 1:49 pm, superpollo 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 First  |  Prev  |  Next  |  Last