Permutations with repetitions: Difference between revisions

→‎{{header|Python}}: Added a strict evaluation variant (using replicateM)
(→‎{{header|Python}}: Added a strict evaluation variant (using replicateM))
Line 1,571:
=={{header|Python}}==
 
===Strict evaluation of the whole set===
===Applying itertools.product===
 
To evaluate the whole set of permutations, without the option to make complete evaluation conditional, we can reach for a generic replicateM function for lists:
 
<lang python>from functools import (reduce)
 
 
# MAIN IO ()
def main():
print(
replicateM(2)([1, 2, 3])
)
 
 
# GENERIC FUNCTIONS ---------------------------------------
 
# replicateM :: Int -> [a] -> [[a]]
def replicateM(n):
def loop(f):
def go(x):
return [[]] if 0 >= x else (
liftA2List(lambda a, b: [a] + b)(f)(go(x - 1))
)
return go(n)
return lambda f: loop(f)
 
 
# liftA2List :: (a -> b -> c) -> [a] -> [b] -> [c]
def liftA2List(f):
return lambda xs: lambda ys: concatMap(
lambda x: concatMap(lambda y: [f(x, y)])(ys)
)(xs)
 
 
# concatMap :: (a -> [b]) -> [a] -> [b]
def concatMap(f):
return lambda xs: (
reduce(lambda a, b: a + b, map(f, xs), [])
)
 
 
# MAIN ---
main()</lang>
{{Out}}
<pre>[[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]</pre>
 
 
===Lazy evaluation with a generator===
====Applying itertools.product====
 
<lang python>from itertools import product
Line 1,581 ⟶ 1,629:
if w.lower() == 'crack': break</lang>
 
====Writing a generator====
 
Or, composing our own generator, by wrapping a function '''from''' an index in the range ''0 .. (distinct items to the power of groupSize)'' '''to''' a unique permutation. (Each permutation is equivalent to a 'number' in the base of the size of the set of distinct items, in which each distinct item functions as a 'digit'):
9,655

edits