1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 """This module contains general-purpose algorithms and data structures."""
20
21 __author__ = "Adam Sindelar <adamsh@google.com>"
22
23
25 """Yields decimals of Euler's number, using continued fractions.
26
27 This is used to generate random looking, but deterministic series of digits
28 for testing purposes. Unlike PRNGs, the output is always guaranteed to be
29 the same and is implementation-independent.
30
31 For explanation of how this works see (for example) here:
32 http://mathworld.wolfram.com/eContinuedFraction.html
33 """
34
35 def e_continued_fraction():
36 """Continued fraction for Euler's.
37
38 This is the series 1, 0, 1, 1, 2, 1, 1, 4...
39 """
40 yield 1
41 k = 0
42 while True:
43 yield k
44 k += 2
45 yield 1
46 yield 1
47
48 def yield_digits(p, q):
49 while p > 0:
50 if p > q:
51 d = p // q
52 p = p - q * d
53 else:
54 d = (10 * p) // q
55 p = 10 * p - q * d
56
57 yield d
58
59 def z(fraction, a=1, b=0, c=0, d=1):
60 for x in fraction:
61 while a > 0 and b > 0 and c > 0 and d > 0:
62
63
64 t = a // c
65 t_ = b // d
66 if t != t_:
67 break
68
69 yield t
70 a = (10 * (a - c * t))
71 b = (10 * (b - d * t))
72 a, b = x * a + b, a
73 c, d = x * c + d, c
74
75 for digit in yield_digits(a, c):
76 yield digit
77
78 return z(e_continued_fraction())
79