McNuggets problem: Difference between revisions
→Python - List monad in parallel to comprehension: Pylinted, tidied, updated output, added {Works with} tag
No edit summary |
(→Python - List monad in parallel to comprehension: Pylinted, tidied, updated output, added {Works with} tag) |
||
Line 855:
Note that the innermost function wraps its results in a (potentially empty) list. The resulting list of lists, some empty, is then flattened by the concatenation component of '''bind'''.
{{Works with|Python|3.7}}
<lang python>'''mcNuggets list monad'''
Line 860 ⟶ 862:
# mcNuggetsByListMonad :: Int -> Set Int
def mcNuggetsByListMonad(limit):
'''McNugget numbers up to limit.'''
lambda x:
lambda y:
bind(box(20))(
lambda v=sum([x, y, z]): (
[] if v > limit else [v]
# Which, for comparison, is equivalent to:
# mcNuggetsByComprehension :: Int -> Set Int
def mcNuggetsByComprehension(limit):
'''McNuggets numbers up to limit'''
box = size(limit)
return {
v for v in (
sum([x, y, z])
for x in box(6)
for y in box(9)
for z in box(20)
) if v <= limit
}
# size :: Int -> Int -> [Int]
def size(limit):
'''Multiples of n up to limit.'''
return lambda n: enumFromThenTo(0)(n)(limit)
# TEST -----------------------------------------------------------
def main():
'''List monad and set comprehension - parallel routes'''
def test(limit):
def go(nuggets):
ys = list(dropwhile(
lambda x: x in nuggets,
enumFromThenTo(limit)(limit - 1)(1)
))
return str(ys[0]) if ys else (
'No unreachable targets in this range.'
)
return lambda nuggets: go(nuggets)
def fName(f):
return f.__name__
limit = 100
print(
fTable(main.__doc__ + ':\n')(fName)(test(limit))(
lambda f: f(limit)
)([mcNuggetsByListMonad, mcNuggetsByComprehension])
)
# GENERIC ABSTRACTIONS ------------------------------------
# bind (>>=) :: [a] -> (a -> [b]) -> [b]
Line 911 ⟶ 937:
Two computations sequentially composed,
with any value produced by the first
passed as an argument to the second.
'''
return lambda f: list(
chain.from_iterable(
Line 921 ⟶ 948:
# enumFromThenTo :: Int -> Int -> Int -> [Int]
def enumFromThenTo(m):
'''
with a step defined by nxt - m.
'''
def
d = nxt - m
return range(m, n - 1 if d < 0 else 1 + n, d)
return lambda nxt: lambda n: list(go(nxt, n))
# FORMATTING ----------------------------------------------
# fTable :: String -> (a -> String) ->
# (b -> String) -> (a -> b) -> [a] -> String
def fTable(s):
'''Heading -> x display function -> fx display function ->
f -> xs -> tabular string.
'''
def go(xShow, fxShow, f, xs):
ys = [xShow(x) for x in xs]
w = max(map(len, ys))
return s + '\n' + '\n'.join(map(
lambda x, y: y.rjust(w, ' ') + ' -> ' + fxShow(f(x)),
xs, ys
))
return lambda xShow: lambda fxShow: lambda f: lambda xs: go(
xShow, fxShow, f, xs
)
# MAIN ---
if __name__ == '__main__':
main()</lang>
{{Out}}
<pre>
List monad and set comprehension - parallel routes:
mcNuggetsByListMonad -> 43
mcNuggetsByComprehension -> 43</pre>
=={{header|REXX}}==
|