Pythagorean quadruples: Difference between revisions

Content added Content deleted
m (added underlining.)
Line 1,569: Line 1,569:
{{Trans|JavaScript}}
{{Trans|JavaScript}}
{{Trans|AppleScript}}
{{Trans|AppleScript}}
<lang Python>from itertools import (islice)
<lang Python>'''Pythagorean Quadruples'''


from itertools import islice, takewhile



# main :: IO ()
# unrepresentables :: () -> [Int]
def main():
def unrepresentables():
print (
'''A non-finite stream of powers of two which can
takeWhileGen(lambda x: 2200 > x)(
mergeInOrder(powersOfTwo())(
not be represented as a Pythagorean quadruple.
'''
map(lambda x: 5 * x, powersOfTwo())
)
return merge(
)
powersOfTwo()
)(
5 * x for x in powersOfTwo()
)
)


Line 1,585: Line 1,588:
# powersOfTwo :: Gen [Int]
# powersOfTwo :: Gen [Int]
def powersOfTwo():
def powersOfTwo():
'''A non-finite stream of successive powers of two.
'''
return iterate(lambda x: 2 * x)(1)
return iterate(lambda x: 2 * x)(1)




# ------------------------- TEST -------------------------
# mergeInOrder :: Gen [Int] -> Gen [Int] -> Gen [Int]
# main :: IO ()
def mergeInOrder(ga):
def go(ma, mb):
def main():
'''For positive integers up to 2,200 (inclusive)
a = ma
b = mb
'''
def p(x):
while not a['Nothing'] and not b['Nothing']:
ta = a['Just']
return 2200 >= x
tb = b['Just']
if ta[0] < tb[0]:
yield(ta[0])
a = uncons(ta[1])
else:
yield(tb[0])
b = uncons(tb[1])


print(
return lambda gb: go(uncons(ga), uncons(gb))
list(
takewhile(p, unrepresentables())
)
)




# GENERIC ABSTRACTIONS ------------------------------------
# ----------------------- GENERIC ------------------------



# iterate :: (a -> a) -> a -> Gen [a]
# iterate :: (a -> a) -> a -> Gen [a]
def iterate(f):
def iterate(f):
'''An infinite list of repeated
applications of f to x.
'''
def go(x):
def go(x):
v = x
v = x
while True:
while True:
yield(v)
yield v
v = f(v)
v = f(v)
return lambda x: go(x)
return go




# Just :: a -> Maybe a
# merge :: Gen [Int] -> Gen [Int] -> Gen [Int]
def Just(x):
def merge(ga):
'''An ordered stream of values drawn from two
return {'type': 'Maybe', 'Nothing': False, 'Just': x}
other ordered streams.

'''

def go(gb):
# Nothing :: Maybe a
def Nothing():
def f(ma, mb):
a, b = ma, mb
return {'type': 'Maybe', 'Nothing': True}
while a and b:
ta, tb = a, b
if ta[0] < tb[0]:
yield ta[0]
a = uncons(ta[1])
else:
yield tb[0]
b = uncons(tb[1])
return f(uncons(ga), uncons(gb))
return go




Line 1,632: Line 1,646:
# take :: Int -> String -> String
# take :: Int -> String -> String
def take(n):
def take(n):
return lambda xs: (
'''The prefix of xs of length n,
xs[0:n]
or xs itself if n > length xs.
'''
if isinstance(xs, list)
else list(islice(xs, n))
)


# takeWhileGen :: (a -> Bool) -> Gen [a] -> [a]
def takeWhileGen(p):
def go(xs):
def go(xs):
vs = []
return (
v = next(xs)
xs[0:n]
while (None is not v and p(v)):
if isinstance(xs, (list, tuple))
vs.append(v)
else list(islice(xs, n))
v = next(xs)
)
return vs
return go
return lambda xs: go(xs)




# uncons :: [a] -> Maybe (a, [a])
# uncons :: [a] -> Maybe (a, [a])
def uncons(xs):
def uncons(xs):
'''The deconstruction of a non-empty list
(or generator stream) into two parts:
a head value, and the remaining values.
'''
if isinstance(xs, list):
if isinstance(xs, list):
return Just((xs[0], xs[1:])) if 0 < len(xs) else Nothing()
return (xs[0], xs[1:]) if xs else None
else:
else:
nxt = take(1)(xs)
nxt = take(1)(xs)
return Just((nxt[0], xs)) if 0 < len(nxt) else Nothing()
return (nxt[0], xs) if nxt else None




# MAIN ---
# MAIN ---
if __name__ == '__main__':
main()</lang>
main()</lang>
{{Out}}
{{Out}}
<pre>[1, 2, 4, 5, 8, 10, 16, 20, 32, 40, 64, 80, 128, 160, 256, 320, 512, 640, 1024, 1280, 2048]</pre>
<pre>[1, 2, 4, 5, 8, 10, 16, 20, 32, 40, 64, 80, 128, 160, 256, 320, 512, 640, 1024, 1280, 2048]</pre>