# [Tutor] A fun puzzle

Dick Moores rdm at rcblue.com
Thu Aug 23 16:52:41 CEST 2007

```At 07:34 PM 8/22/2007, Kent Johnson wrote:
>FWIW here is my fastest solution:
>
>01 from itertools import chain
>02 def compute():
>03      str_=str; int_=int; slice_=slice(None, None, -1)
>04     for x in chain(xrange(1, 1000001, 10), xrange(2, 1000001, 10),
>05 xrange(3, 1000001, 10), xrange(4, 1000001, 10), xrange(5, 1000001, 10),
>06 xrange(6, 1000001, 10), xrange(7, 1000001, 10), xrange(8, 1000001, 10),
>07 xrange(9, 1000001, 10)):
>08          rev = int_(str_(x)[slice_])
>09          if rev>=x: continue
>10         if not x % rev:
>11              print x,
>12 compute()

Kent, thanks for showing us itertools.chain(). By using it you keep x
from being assigned an integer divisible by 10 (thereby faster),
which of course means no need for

if n % 10 == 0:
continue

Again faster.
And at first I thought your use of str_, int_, and slice_ were pretty
weird; instead of your line 08, why not just use the straightforward

rev = int(str(x)[::-1])

but on upon testing I see they all make their respective
contributions to speed.

But I don't understand why. Why is your line 08 faster than "rev =
int(str(x)[::-1])"?

BTW I also thought that

for x in chain(xrange(1, 1000001, 10), xrange(2, 1000001, 10),
xrange(3, 1000001, 10), xrange(4, 1000001, 10), xrange(5, 1000001, 10),
xrange(6, 1000001, 10), xrange(7, 1000001, 10), xrange(8, 1000001, 10),
xrange(9, 1000001, 10)):
pass

MUST take longer than

for x in xrange(1000000):
pass

because there appears to be so much more going on, but their timings
are essentially identical.

Dick Moores
XP, Python 2.5, editor is Ulipad

======================================