Hello.
I have made a handler for generating combinations with repetitions, for completion, since we then have all kinds of handlers here. You’ll have to allow for every element being chosen as many times as there are rooms in your subset.
set comboList to {}
set donuts to {"iced", "jam", "plain", "something completely different"}
set chosen to {0, 0, 0, 0}
# the number of items in the list chosen, must coincide with the n_chosen parameter.
choose(comboList, chosen, 1, 4, 1, 3)
--> 15 (combinations
listprint(comboList)
(*
"{\"iced\", \"iced\", \"iced\", \"iced\"}
{\"iced\", \"iced\", \"iced\", \"jam\"}
{\"iced\", \"iced\", \"iced\", \"plain\"}
{\"iced\", \"iced\", \"jam\", \"jam\"}
{\"iced\", \"iced\", \"jam\", \"plain\"}
{\"iced\", \"iced\", \"plain\", \"plain\"}
{\"iced\", \"jam\", \"jam\", \"jam\"}
{\"iced\", \"jam\", \"jam\", \"plain\"}
{\"iced\", \"jam\", \"plain\", \"plain\"}
{\"iced\", \"plain\", \"plain\", \"plain\"}
{\"jam\", \"jam\", \"jam\", \"jam\"}
{\"jam\", \"jam\", \"jam\", \"plain\"}
{\"jam\", \"jam\", \"plain\", \"plain\"}
{\"jam\", \"plain\", \"plain\", \"plain\"}
{\"plain\", \"plain\", \"plain\", \"plain\"}"
*)
(*
The calculation for the number of combinations with repetitions are:
C( maxtypes+n_chosen-1,n_chosen) or C(n+r-1,r) with other variable names.
*)
log C(3 + 4 - 1, 4)
--> 15
on choose(combinations, got, n_chosen, len, atw, maxtypes)
global donuts
set tcount to 0
if n_chosen = (len + 1) then
# log "n_chosen = len "
if got = 0 then return 1
set lineout to {}
repeat with i from 1 to len
set end of lineout to item (item i of got) of donuts
end repeat
copy lineout to end of combinations
return 1
end if
repeat with i from atw to maxtypes
if (got ≠0) then
set item n_chosen of got to i
set tcount to tcount + choose(combinations, got, (n_chosen + 1), len, i, maxtypes)
end if
end repeat
return tcount
end choose
on listprint(theL)
try
text 0 of theL
on error e
set ofs to offset of "{" in e
set tmp to text (ofs + 1) thru -3 of e
tell (a reference to text item delimiters)
set astid to contents of it
set contents of it to "}, "
set newl to text items of tmp
set contents of it to "}" & return
set newt to newl as text
set contents of it to astid
end tell
return newt
end try
end listprint
on C(n, r)
# Counts the number of r-combinations in a set of n elements.
# it is also called the binomial coeffecient.
if n = 0 or n < r or r < 0 then error "C: argument error"
return (factorial(n) div (factorial(r) * (factorial(n - r))))
end C
on factorial(n)
if n > 170 then error "Factorial: n too large."
# Result greater than 1.797693E+308!
if n < 0 then error "Factorial: n not positive."
set a to 1
repeat with i from 1 to n
set a to a * i
end repeat
return a
end factorial