]
If you replace
a, a1 = 10L*(a%b), 10L*(a1%b1)
with
a, a1 = 12L*(a%b), 12L*(a1%b1)
and
sys.stdout.write(`int(d)`)
with
sys.stdout.write('%X'%d`)
Typo, sorry ----------------^
that back-tick should not be there ;-/
and run it, I think it will do what you want, even though I haven't worked through exactly
what it's doing, though it's pretty. (For confidence I just tried it and decoded the result
far enough to match math.pi exactly ;-)
(the %X formats hex, but for single digits that's fine for base 12, giving A for 10 and B for 11.
If you want bases >16 you'll have to use something like '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'[digitvalue])
BTW, I would make this into a base-parameterized generator, something like
... base = long(base)
... k, a, b, a1, b1 = 2L, 4L, 1L, 12L, 4L
... while ndigits:
... # 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 d == d1:
... yield int(d)
... if ndigits is not True:
... ndigits -= 1
... if ndigits == 0: break
... a, a1 = base*(a%b), base*(a1%b1)
... d, d1 = a/b, a1/b1
... ... assert base>=2 and base <= len(digchars) and ndigits>=0
... for d in pigen(base, ndigits):
... yield digchars[d]
[ I just realized the original had tabs, so the above is fixed and pasted after the below ]
... ...
314159265358979323846264338327950288419716939937510582097494>>> ...
... )
314159265358979323846264338327950288419716939937510582097494 ...
314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211
706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895
493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360
726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138
414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272
489122793818301194912983367336244065664308602139494639522473719070217986094370277053921717629317
675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014
654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999
837297804995105973173281609631859502445945534690830264252230825334468503526193118817101000313783
875288658753320838142061717766914730359825349042875546873115956286388235378759375195778185778053
217122680661300192787661119590921642019893809525720106548586327886593615338182796823030195203530
185296899577362259941389124972177528347913151557485724245415069595082953311686172785588907509838
175463746493931925506040092770167113900984882401285836160356370766010471018194295559619894676783
74494482553797747268471040475346462080466842590694912933136770289891521047521Traceback (most rec
ent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in pidigits
File "<stdin>", line 16, in pigen
KeyboardInterrupt
To make a file for your friend,
That didn't take very long. No line breaks though. You can do that quick and dirty with
>>> open('pi12by60.txt','w').write( ... ''.join(c+'\n'[
![Frown :( :(](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
i+1)%60==0] for i,c in enumerate(pidigits(12, 3003)))+'\n')
>>>
(adding the last EOL since we know 3003%60 =!0 ;-)
You could speed up the initial burst a lot, but after a while the data passing overhead is not
a significant part of the whole time.
Hm, ... that first digit still needs to be fixed for base <4 ;-)
Regards,
Bengt Richter