/* Lanterm problem in Picat. http://rosettacode.org/wiki/Lantern_Problem """ There are some groups of lantern hanging on the ceil. Each group contais one or more lanterns. Each time you can fetch one lantern. Now you need to get all these lanterns down, but you can only fetch the one in the bottom of the group. The qustion is how many ways are there to do this. For example, there are some lanterns hanging like this: 🏮 🏮 🏮 🏮 🏮 🏮 Number these lanterns: 1 2 4 3 5 6 You can take like this: [6,3,5,2,4,1] or [3,1,6,5,2,4] But not: [6,3,2,4,5,1] because at that time 5 is under 4. There are 60 ways to take them down. Task Input: First an integer (n): the number of groups. Then n integers: the number of lanterns each group has. Output: An integer: the number of sequences. For example, the input of the example above could be: 3 1 2 3 And the output is: 60 Optional task Output all the sequences using this format: [a,b,c,…] [b,a,c,…] …… """ This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ % import v3_utils. % import util. % import cp. /* [1] = 1 [1,2] = 3 [1,2,3] = 60 [1,2,3,4] = 12600 [1,2,3,4,5] = 37837800 [1,2,3,4,5,6] = 2053230379200 [1,2,3,4,5,6,7] = 2431106898187968000 [1,2,3,4,5,6,7,8] = 73566121315513295589120000 https://oeis.org/search?q=1%2C3%2C60%2C12600%2C37837800&language=english&go=Search 1, 1, 3, 60, 12600, 37837800, 2053230379200, 2431106898187968000, 73566121315513295589120000, 65191584694745586153436251091200000, 1906765806522767212441719098019963758016000000, 2048024348726152339387799085049745725891853852479488000000 Multinomial coefficients (0, 1, ..., n)! = C(n+1,2)!/(0!*1!*2!*...*n!). */ main => go2. go => run_lantern(). /* This generates the OEIS sequence https://oeis.org/A022915 60 [1] = 1 [1,2] = 3 [1,2,3] = 60 [1,2,3,4] = 12600 [1,2,3,4,5] = 37837800 [1,2,3,4,5,6] = 2053230379200 [1,2,3,4,5,6,7] = 2431106898187968000 [1,2,3,4,5,6,7,8] = 73566121315513295589120000 */ go2 => A = [1,2,3], println(lantern(A)), foreach(N in 1..8) println(1..N=lantern(1..N)) end, nl. run_lantern() => N = read_int(), A = [], foreach(_ in 1..N) A := A ++ [read_int()] end, println(A), println(lantern(A)), nl. % {{trans|Python}} table lantern(A) = Res => Arr = copy_term(A), Res = 0, foreach(I in 1..Arr.len) if Arr[I] != 0 then Arr[I] := Arr[I] - 1, Res := Res + lantern(Arr), Arr[I] := Arr[I] + 1 end end, if Res == 0 then Res := 1 end.