why 'lambda' and 'reduce'?

Bengt Richter bokr at oz.net
Fri Jun 13 18:28:47 EDT 2003


On Thu, 12 Jun 2003 13:46:45 -0400, "John Roth" <johnroth at ameritech.net> wrote:

>
>"Manuel Garcia" <news at manuelmgarcia.com> wrote in message
>news:arnfevstdtqohla2l39717ch56saip8qce at 4ax.com...
>> If anyone ever asks for what good are 'lambda' and 'reduce', show them
>> this...
>>
>> print (lambda p:p[0]+'.'+p[1:])(
>>     str((lambda(x,y,t,a):2L*x*x//a)(
>>         (lambda F:(lambda S:reduce(
>>             lambda(x,y,t,a),_:((x+y)//2L,
>>                 S((x*y)//F),2L*t,
>>                 (a-(t*(((x+y)//2L)**2-
>>                        (S((x*y)//F))**2))//F)),
>>             [0]*13,(F,(F*F)//S(2L*F),2L,F//2L)))(
>>                 lambda n:reduce(lambda x,_:(
>>                     x-x//2L+(n*F)//(2L*x)),
>>                 [0]*15,
>>                 n//2L)))(10L**(5010))))[:5000])
>>
>> You have to be a bit patient with this one...
>
>One thing is perfectly clear. Unless someone paid
>me to do it, I wouldn't look at it. And part of
>the agreement would be to refactor it into something
>at least marginally readable.
>
I just thought to dig this up and turn it into a generator.
Something to check against ;-)

====< pigen.py >====================================
#! /usr/bin/env python
from __future__ import generators

def pigen(n):
    """
    Generate n successive digits of pi.
    
    The algorithm, using Python's 'long' integers ("bignums"), works
    with continued fractions, and was conceived by Lambert Meertens.
    
    See also the ABC Programmer's Handbook, by Geurts, Meertens & Pemberton,
    published by Prentice-Hall (UK) Ltd., 1990. 
    """    
    k, a, b, a1, b1 = 2L, 4L, 1L, 12L, 4L
    while n>0:
        # Next approximation
        p, q, k = k*k, 2L*k+1L, k+1L
        a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1
        # Print common digits
        d, d1 = a/b, a1/b1
        while n>0 and d == d1:
            yield d
            n -= 1
            a, a1 = 10L*(a%b), 10L*(a1%b1)
            d, d1 = a/b, a1/b1

if __name__ == '__main__':
    import sys
    try:
        ndigits = int(sys.argv[1])
        for digit in pigen(ndigits):
            sys.stdout.write('%d'%digit)
        print
    except Exception,e:
        print '%s: %s' % (e.__class__.__name__, e)
        print
        print 'Usage: [python] pigen.py ndigits'
====================================================
[15:31] C:\pywk\pi>pigen.py 500
314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211
706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895
493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360
726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138
414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272
48912279381830119491

... and so forth ;-)

Regards,
Bengt Richter




More information about the Python-list mailing list