Department numbers: Difference between revisions
Content added Content deleted
(Added Algol W) |
(→{{header|Python}}: Updated bind, pylinted for Python 3, added subheaders.) |
||
Line 1,935: | Line 1,935: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
===Procedural=== |
|||
<lang python>from itertools import permutations |
<lang python>from itertools import permutations |
||
Line 1,966: | Line 1,967: | ||
14: 6 5 1 </pre> |
14: 6 5 1 </pre> |
||
===Composition of pure functions=== |
|||
Expressing the options directly and declaratively in terms of a ''bind'' operator, without importing ''permutations'': |
|||
{{Works with|Python|3}} |
|||
<lang python>'''Department numbers''' |
|||
from itertools import (chain) |
|||
from operator import ( |
from operator import (ne) |
||
# options :: Int -> Int -> Int -> [(Int, Int, Int)] |
# options :: Int -> Int -> Int -> [(Int, Int, Int)] |
||
def options(lo, hi, total): |
def options(lo, hi, total): |
||
'''Eligible integer triples.''' |
|||
ds = |
ds = enumFromTo(lo)(hi) |
||
⚫ | |||
return bind(filter(even, ds))( |
|||
lambda x: bind(filter(curry(ne)(x), ds))( |
|||
lambda y: bind([total - (x + y)])( |
lambda y: bind([total - (x + y)])( |
||
lambda z: [(x, y, z)] if ( |
lambda z: [(x, y, z)] if ( |
||
z != y and |
z != y and lo <= z <= hi |
||
) else [] |
) else [] |
||
) |
) |
||
Line 1,987: | Line 1,992: | ||
# TEST ---------------------------------------------------- |
# TEST ---------------------------------------------------- |
||
# main :: IO () |
# main :: IO () |
||
def main(): |
def main(): |
||
'''Test''' |
|||
xs = options(1, 7, 12) |
xs = options(1, 7, 12) |
||
print |
print(('Police', 'Sanitation', 'Fire')) |
||
for tpl in xs: |
for tpl in xs: |
||
print |
print(tpl) |
||
print |
print('\nNo. of options: ' + str(len(xs))) |
||
# GENERIC |
# GENERIC ABSTRACTIONS ------------------------------------ |
||
# bind (>>=) :: [a] -> (a -> [b]) -> [b] |
# bind (>>=) :: [a] -> (a -> [b]) -> [b] |
||
def bind(xs): |
def bind(xs): |
||
'''List monad injection operator. |
|||
⚫ | |||
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( |
|||
map(f, xs) |
|||
) |
|||
) |
|||
# curry :: ((a, b) -> c) -> a -> b -> c |
|||
⚫ | |||
def curry(f): |
|||
'''A curried function derived |
|||
from an uncurried function.''' |
|||
⚫ | |||
# enumFromTo :: (Int, Int) -> [Int] |
|||
def enumFromTo(m): |
|||
'''Integer enumeration from m to n.''' |
|||
⚫ | |||
# even :: Int -> Bool |
|||
def even(x): |
|||
'''True if x is an integer |
|||
multiple of two.''' |
|||
return 0 == x % 2 |
|||
if __name__ == '__main__': |
|||
⚫ | |||
{{Out}} |
{{Out}} |
||
<pre>('Police', 'Sanitation', 'Fire') |
<pre>('Police', 'Sanitation', 'Fire') |