Rebol3 Code Examplex
Combinations with repetitions
Generate all k-element combinations with repetitions.
Rebol [
title: "Rosetta code: Combinations with repetitions"
file: %Combinations_with_repetitions.r3
url: https://rosettacode.org/wiki/Combinations_with_repetitions
]
combinations: function [
"Generate all k-element combinations with repetitions."
k [integer!] "Number of elements per combination."
items [integer! block!] "Maximum value or source values to combine."
/flat "Return a flat list instead of a block of combinations."
][
n: either block? items [length? items][items]
;; Start with the lowest combination: [1 1 ...]
blk: array/initial k 1
blk: collect [
forever [
;; Return current combination.
either flat [
keep blk
][ keep/only copy blk ]
;; Find the rightmost value that can be increased.
i: k
while [
i > 0
blk/:i = n
][
-- i
]
if i = 0 [break]
;; Increase this position and repeat it to the right.
value: blk/:i + 1
while [i <= k] [
blk/:i: value
++ i
]
]
]
if block? items [
;; Replace indexes with actual values from the source block.
either flat [
forall blk [
change/only blk items/(blk/1)
]
][
foreach c blk [
forall c [
change/only c items/(c/1)
]
]
]
]
blk
]
probe combinations 2 3
probe combinations 2 [iced jam plain]
probe new-line/skip combinations/flat 2 [iced jam plain] on 2
print [
"^/Number of combinations for k=3, n=10:"
as-green (length? combinations/flat 3 10) / 3
]Output:
[[1 1] [1 2] [1 3] [2 2] [2 3] [3 3]]
[[iced iced] [iced jam] [iced plain] [jam jam] [jam plain] [plain plain]]
[
iced iced
iced jam
iced plain
jam jam
jam plain
plain plain
]
Number of combinations for k=3, n=10: 220