Multiplication tables: Difference between revisions

→‎{{header|Python}}: Compositional variant, separating assembly from render
(→‎{{header|Haskell}}: A coarse-grained variant)
(→‎{{header|Python}}: Compositional variant, separating assembly from render)
Line 3,804:
Declaring a file type of UTF-8 and adding a u to all string literals to transform them into Unicode literals would make the above work in Python 2.X.
<small>(As would using ASCII minus, plus, and pipe characters: "-", "+", "|"; instead of the non-ASCII chars used to draw a frame)</small>.
 
 
Or, separating model from view, and composing from generic functions:
 
<lang python>from itertools import (groupby)
from functools import (reduce)
from operator import (le, mul)
 
 
# table :: Int -> [(Int, [Int])]
def table(n):
return list(
map(
fmapTuple(lambda x: list(map(uncurry(mul), x))),
groupby(
filter(
uncurry(le),
joinFn(cartesianProduct)(
enumFromTo(1)(n)
)
),
fst
)
)
)
 
 
# showTable :: [(Int, [Int])] -> String
def showTable(xs):
mx = xs[-1]
colW = 1 + len(str(mx[1][-1]))
tab = ' ' * (colW)
padIndex = justifyRight(1 + len(str(fst(mx))))(' ')
padCol = justifyRight(colW)(' ')
 
return unlines(
map(
lambda x: padIndex(str(fst(x))) + ':' +
tab * (fst(x) - 1) + concatMap(
lambda n: padCol(str(n))
)(
snd(x)
),
xs
)
)
 
 
# main IO ()
def main():
print (
showTable(
table(12)
)
)
 
 
# GENERIC FUNCTIONS -------------------------------------
 
# apList (<*>) :: [(a -> b)] -> [a] -> [b]
def apList(fs):
return lambda xs: reduce(
lambda a, f: a + reduce(
lambda a, x: a + [f(x)], xs, []
), fs, []
)
 
 
# bindFn :: (a -> b) -> (b -> c) -> a -> c
def bindFn(m):
return lambda mf: lambda x: mf(lambda y: m(x)(y))(x)
 
 
# cartesianProduct :: [a] -> [b] -> [(a, b)]
def cartesianProduct(xs):
return lambda ys: apList(
map(lambda x: lambda y: (x, y), xs)
)(ys)
 
 
# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
return lambda xs: (
xs if not xs else reduce(
lambda a, b: a + b, map(f, xs), '')
)
 
 
# enumFromTo :: Int -> Int -> [Int]
def enumFromTo(m):
return lambda n: list(range(m, 1 + n))
 
 
# fmapTuple (<$>) :: (a -> b) -> (a, a) -> (a, b)
def fmapTuple(f):
return lambda tpl: (fst(tpl), f(snd(tpl)))
 
 
# fst :: (a, b) -> a
def fst(tpl):
return tpl[0]
 
 
# join :: Monad m => m (m a) -> m a
def joinFn(f):
return bindFn(f)(lambda x: x)
 
 
# justifyRight :: Int -> Char -> String -> String
def justifyRight(n):
return lambda cFiller: lambda s: (
((n * cFiller) + s)[-n:]
)
 
 
# last :: [a] -> a
def last(xs):
return xs[-1:]
 
 
# snd :: (a, b) -> b
def snd(tpl):
return tpl[1]
 
 
# uncurry :: (a -> b -> c) -> ((a, b) -> c)
def uncurry(f):
return lambda xy: f(fst(xy), snd(xy))
 
 
# unlines :: [String] -> String
def unlines(xs):
return '\n'.join(xs)
 
 
# MAIN ---
main()</lang>
{{Out}}
<pre> 1: 1 2 3 4 5 6 7 8 9 10 11 12
2: 4 6 8 10 12 14 16 18 20 22 24
3: 9 12 15 18 21 24 27 30 33 36
4: 16 20 24 28 32 36 40 44 48
5: 25 30 35 40 45 50 55 60
6: 36 42 48 54 60 66 72
7: 49 56 63 70 77 84
8: 64 72 80 88 96
9: 81 90 99 108
10: 100 110 120
11: 121 132
12: 144</pre>
 
=={{header|R}}==
9,658

edits