[Tutor] Re: Creatively solving math problems -----help
Andrei
project5 at redrival.net
Fri Sep 12 05:14:19 EDT 2003
Lloyd Kvam wrote:
> One further optimization:
> x % 6 == 1 implies that x % 3 ==1 and x % 2 == 1 (the factors of the
> modulus
> must also result in 1 (asserted without proof))
Seems perfectly OK to me.
> so
> for y in range(2, 7):
> could become
> for y in (4,5,6):
>
> Danny's one liner:
> [ x for x in range(20000) if [x%i for i in range(2,8)]==[1]*5+[0] ]
> shows the mod values that we want. [1]*5+[0] might be easier to read as
> [1,1,1,1,1,0]
> though counting 1's isn't great either.
Actually, it was my oneliner. [1]*5 was indeed to avoid typing the wrong number
of 1's - and it's marginally shorter too! Danny's solution is far more excentric
- and certainly no oneliner :). Nevertheless, I think a solution with explicit
loops is preferred in this sutuation. Funny how the whole discussion turned into
an optimization when all Conrad needed was the % operator.
Anyway, it's possible to save a bit of time in the list comprehension too using
the suggestions provided (not checking 2&3 because 6 already checks them and
only evaluating if x%7==0) *wink*. I've done some tests and it seems there's a
way to add to the spared time: replace the range() and [1]*4 with their
hand-written counterparts. Time for the benchmarks:
>>> import timeit as t
>>> a = t.Timer("[ x for x in range(20000) if [x%i for i in
range(2,8)]==[1]*5+[0] ]")
>>> b = t.Timer("[ x for x in range(20000) if not x%7 if [x%i for i in
(4,5,6)]==[1,1,1] ]")
>>> c = t.Timer("[ x for x in xrange(20000) if not x%7 if not x%6-1 if not
x%5-1 if not x%4-1 ]")
>>> [ min(X.repeat(30,1)) for X in [a,b,c] ]
[0.17663669544572258, 0.022738923522410914, 0.0077345025697468373]
^-- best result for a ^-- best for b ^-- best for c (lower=better)
Just to be on the safe side, test if all lists are the same (up to 100k instead
of 20k):
>>> [ x for x in range(100000) if [x%i for i in range(2,8)]==[1]*5+[0] ]==[ x
for x in range(100000) if not x%7 if [x%i for i in (4,5,6)]==[1,1,1] ]==[ x for
x in xrange(100000) if not x%7 if not x%6-1 if not x%5-1 if not x%4-1 ]
True
And the winner is, at nearly 23 times the speed of the original oneliner...
[ x for x in xrange(20000) if not x%7 if not x%6-1 if not x%5-1 if not x%4-1 ]
Well, that was fun.
Andrei
=====
Mail address in header catches spam. Real contact info (decode with rot13):
cebwrpg5 at bcrenznvy.pbz. Fcnz-serr! Cyrnfr qb abg hfr va choyvp cbfgf. V ernq gur
yvfg, fb gurer'f ab arrq gb PP.
More information about the Tutor
mailing list