Solve hanging lantern problem: Difference between revisions

Added Uiua solution
(→‎fast analytical 1..N count only: replaced with more flexible version, now needs/copes with eg {1,3,3})
(Added Uiua solution)
 
(38 intermediate revisions by 15 users not shown)
Line 1:
{{draft task}}
 
There are some columns of lanterns hanging from the ceiling. If you remove the lanterns one at a time, at each step removing the bottommost lantern from one column, how many legal sequences will let you take all of the lanterns down?
Line 41:
; Optional task:
Output all the sequences using this format:<br>
[a1,b2,c3,…]
[b2,a1,c3,…]
……
 
 
;Related:
=={{header|Commodore BASIC}}==
* [[Permutations_with_some_identical_elements]]
 
 
=={{header|APL}}==
{{trans|Pascal}}
<syntaxhighlight lang="apl">lanterns ← { (!+/⍵) ÷ ×/!⍵ }</syntaxhighlight>
{{Out}}
<pre> lanterns 1 2 3
60
lanterns 1 3 3
140
</pre>
 
Of course, for the simple sequences from 1, we can use iota to generate them instead of typing them out:
 
<pre> lanterns ⍳3 ⍝ same as lanterns 1 2 3
60
lanterns ⍳4
12600
lanterns ⍳5
37837800</pre>
 
=={{header|BASIC}}==
==={{header|BASIC256}}===
{{trans|FreeBASIC}}
The result for n >= 5 is slow to emerge
<syntaxhighlight lang="freebasic">arraybase 1
n = 4
dim a(n)
for i = 1 to a[?]
a[i] = i
print "[ ";
for j = 1 to i
print a[j]; " ";
next j
print "] = "; getLantern(a)
next i
end
 
function getLantern(arr)
res = 0
for i = 1 to arr[?]
if arr[i] <> 0 then
arr[i] -= 1
res += getLantern(arr)
arr[i] += 1
end if
next i
if res = 0 then res = 1
return res
end function</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|Commodore BASIC}}===
{{trans|Python}}
The (1,2,3) example takes about 30 seconds to run on a stock C64; (1,2,3,4) takes about an hour and 40 minutes. Even on a 64 equipped with a 20MHz SuperCPU it takes about 5 minutes.
<langsyntaxhighlight lang="basic">100 PRINT CHR$(147);CHR$(18);"*** HANGING LANTERN PROBLEM ***"
110 INPUT "HOW MANY COLUMNS "; N
120 DIM NL(N-1):T=0
Line 74 ⟶ 129:
410 GOTO 320
420 IF R(SP)=0 THEN R(SP)=1
430 RETURN</langsyntaxhighlight>
 
{{Out}}
Line 86 ⟶ 141:
12600</pre>
 
==={{header|JuliaFreeBASIC}}===
{{trans|Python}}
<lang ruby>""" rosettacode.org /wiki/Lantern_Problem """
<syntaxhighlight lang="freebasic">Function getLantern(arr() As Uinteger) As Ulong
Dim As Ulong res = 0
For i As Ulong = 1 To Ubound(arr)
If arr(i) <> 0 Then
arr(i) -= 1
res += getLantern(arr())
arr(i) += 1
End If
Next i
If res = 0 Then res = 1
Return res
End Function
 
Dim As Uinteger n = 5
using Combinatorics
Dim As Uinteger a(n)
'Dim As Integer a(6) = {1,2,3,4,5,6}
For i As Ulong = 1 To Ubound(a)
a(i) = i
Print "[ ";
For j As Ulong = 1 To i
Print a(j); " ";
Next j
Print "] = "; getLantern(a())
Next i
Sleep</syntaxhighlight>
{{out}}
<pre>[ 1 ] = 1
[ 1 2 ] = 3
[ 1 2 3 ] = 60
[ 1 2 3 4 ] = 12600
[ 1 2 3 4 5 ] = 37837800</pre>
 
==={{header|QBasic}}===
{{works with|QBasic|1.1}}
{{works with|QuickBasic|4.5}}
{{trans|FreeBASIC}}
The result for n >= 5 is slow to emerge
<syntaxhighlight lang="qbasic">FUNCTION getLantern (arr())
res = 0
FOR i = 1 TO UBOUND(arr)
IF arr(i) <> 0 THEN
arr(i) = arr(i) - 1
res = res + getLantern(arr())
arr(i) = arr(i) + 1
END IF
NEXT i
IF res = 0 THEN res = 1
getLantern = res
END FUNCTION
 
n = 4
DIM a(n)
FOR i = 1 TO UBOUND(a)
a(i) = i
PRINT "[";
FOR j = 1 TO i
PRINT a(j); " ";
NEXT j
PRINT "] = "; getLantern(a())
NEXT i
END</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|PureBasic}}===
{{trans|FreeBASIC}}
The result for n >= 5 is slow to emerge
<syntaxhighlight lang="purebasic">;;The result For n >= 5 is slow To emerge
Procedure getLantern(Array arr(1))
res.l = 0
For i.l = 1 To ArraySize(arr(),1)
If arr(i) <> 0
arr(i) - 1
res + getLantern(arr())
arr(i) + 1
EndIf
Next i
If res = 0
res = 1
EndIf
ProcedureReturn res
EndProcedure
 
OpenConsole()
n.i = 4
Dim a.i(n)
For i.l = 1 To ArraySize(a())
a(i) = i
Print("[")
For j.l = 1 To i
Print(Str(a(j)) + " ")
Next j
PrintN("] = " + Str(getLantern(a())))
Next i
Input()
CloseConsole()</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|VBA}}===
 
:''See [[Solve hanging lantern problem#Visual Basic|Visual Basic]]''
 
==={{header|Visual Basic}}===
 
{{works with|Visual Basic|6}}
 
<font color="#FF0000">Note: Integer may overflow if the input number is too big. To solve this problem, simply change Integer to Long or Variant for Decimal. </font>
====Recursive version====
;Main code
<syntaxhighlight lang="vb">
Dim n As Integer, c As Integer
Dim a() As Integer
 
Private Sub Command1_Click()
Dim res As Integer
If c < n Then Label3.Caption = "Please input completely.": Exit Sub
res = getLantern(a())
Label3.Caption = "Result:" + Str(res)
End Sub
 
Private Sub Text1_Change()
If Val(Text1.Text) <> 0 Then
n = Val(Text1.Text)
ReDim a(1 To n) As Integer
End If
End Sub
 
 
Private Sub Text2_KeyPress(KeyAscii As Integer)
If KeyAscii = Asc(vbCr) Then
If Val(Text2.Text) = 0 Then Exit Sub
c = c + 1
If c > n Then Exit Sub
a(c) = Val(Text2.Text)
List1.AddItem Str(a(c))
Text2.Text = ""
End If
End Sub
 
Function getLantern(arr() As Integer) As Integer
Dim res As Integer, i As Integer
For i = 1 To n
If arr(i) <> 0 Then
arr(i) = arr(i) - 1
res = res + getLantern(arr())
arr(i) = arr(i) + 1
End If
Next i
If res = 0 Then res = 1
getLantern = res
End Function</syntaxhighlight>
 
;Form code:
<syntaxhighlight lang="vb">
VERSION 5.00
Begin VB.Form Form1
Caption = "Get Lantern"
ClientHeight = 4410
ClientLeft = 120
ClientTop = 465
ClientWidth = 6150
LinkTopic = "Form1"
ScaleHeight = 4410
ScaleWidth = 6150
StartUpPosition = 3
Begin VB.CommandButton Command1
Caption = "Start"
Height = 495
Left = 2040
TabIndex = 5
Top = 3000
Width = 1935
End
Begin VB.ListBox List1
Height = 1320
Left = 360
TabIndex = 4
Top = 1440
Width = 5175
End
Begin VB.TextBox Text2
Height = 855
Left = 3360
TabIndex = 1
Top = 480
Width = 2175
End
Begin VB.TextBox Text1
Height = 855
Left = 360
TabIndex = 0
Top = 480
Width = 2175
End
Begin VB.Label Label3
Height = 495
Left = 2040
TabIndex = 6
Top = 3720
Width = 2295
End
Begin VB.Label Label2
Caption = "Number Each"
Height = 375
Left = 3960
TabIndex = 3
Top = 120
Width = 1695
End
Begin VB.Label Label1
Caption = "Total"
Height = 255
Left = 960
TabIndex = 2
Top = 120
Width = 1455
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False</syntaxhighlight>
 
====Math solution====
{{trans|Python}}
Reimplemented "getLantern" function above
 
<syntaxhighlight lang="vb">Function getLantern(arr() As Integer) As Integer
Dim tot As Integer, res As Integer
Dim i As Integer
For i = 1 To n
tot = tot + arr(i)
Next i
res = factorial(tot)
For i = 1 To n
res = res / factorial(arr(i))
Next i
getLantern = res
End Function
 
Function factorial(num As Integer) As Integer
Dim i As Integer
factorial = 1
For i = 2 To n
factorial = factorial * i
Next i
End Function</syntaxhighlight>
 
==={{header|Yabasic}}===
{{trans|FreeBASIC}}
The result for n >= 5 is slow to emerge
<syntaxhighlight lang="yabasic">n = 4
dim a(n)
for i = 1 to arraysize(a(),1)
a(i) = i
print "[ ";
for j = 1 to i
print a(j), " ";
next j
print "] = ", getLantern(a())
next i
 
sub getLantern(arr())
local res, i
res = 0
for i = 1 to arraysize(arr(),1)
if arr(i) <> 0 then
arr(i) = arr(i) - 1
res = res + getLantern(arr())
arr(i) = arr(i) + 1
fi
next i
if res = 0 res = 1
return res
end sub</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
_elements = 5
 
local fn GetLantern( arr(_elements) as long ) as long
long i, res = 0
for i = 1 to _elements
if arr(i) != 0
arr(i) = arr(i) - 1
res = res + fn GetLantern( arr(0) )
arr(i) = arr(i) + 1
end if
next
if res = 0 then res = 1
end fn = res
 
long i, j, a(_elements)
for i = 1 to _elements
a(i) = i
print "[";
for j = 1 to i
if j == i then print a(j); else print a(j); ",";
next
print "] = "; fn GetLantern( a(0) )
next
 
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
[1] = 1
[1,2] = 3
[1,2,3] = 60
[1,2,3,4] = 12600
[1,2,3,4,5] = 37837800
</pre>
 
=={{header|J}}==
 
Translation of [[#APL|APL]]:
 
<syntaxhighlight lang="j">lanterns=: {{ (!+/y) % */!y }}<</syntaxhighlight>
 
Example use:
 
<syntaxhighlight lang="j"> lanterns 1 2 3
60
lanterns 1 3 3
140
</syntaxhighlight>
 
Also, a pedantic version where we must manually count how many values we are providing the computer:
 
<syntaxhighlight lang="j">pedantic=: {{
assert. ({. = #@}.) y
lanterns }.y
}}</syntaxhighlight>
 
And, in the spirit of providing unnecessary but perhaps pleasant (for some) overhead, we'll throw in an unnecessary comma between this count and the relevant values:
 
<syntaxhighlight lang="j"> pedantic 3, 1 2 3
60
pedantic 3, 1 3 3
140</syntaxhighlight>
 
If we wanted to impose even more overhead, we could insist that the numbers be read from a file where tabs, spaces and newlines are all treated equivalently. For that, we must specify the file name and implement some parsing:
 
<syntaxhighlight lang="j">yetmoreoverhead=: {{
pedantic ({.~ 1+{.) _ ". rplc&(TAB,' ',LF,' ') fread y
}}</syntaxhighlight>
 
Examples of this approach are left as an exercise for the user (note: do not use commas with this version, unless you modify the code to treat them as whitespace).
 
Finally, enumerating solutions might be approached recursively:
 
<syntaxhighlight lang="j">showlanterns=: {{
arrange=. ($ $ (* +/\)@,) y $&>1
echo 'lantern ids:'
echo rplc&(' 0';' ')"1 ' ',.":|:arrange
echo ''
cols=. <@-.&0"1 arrange
recur=: <@{{
todo=. (#~ ~:&a:) y -.L:0 x
if. #todo do.
next=. {:@> todo
,x <@,S:0 every next recur todo
else.
<x
end.
}}"0 1
echo 'all lantern removal sequences:'
echo >a:-.~ -.&0 each;0 recur cols
}}</syntaxhighlight>
 
Example use:
 
<syntaxhighlight lang="j"> showlanterns 1 2 1
lantern ids:
1 2 4
3
 
all lantern removal sequences:
1 3 2 4
1 3 4 2
1 4 3 2
3 1 2 4
3 1 4 2
3 2 1 4
3 2 4 1
3 4 1 2
3 4 2 1
4 1 3 2
4 3 1 2
4 3 2 1</syntaxhighlight>
 
=={{header|jq}}==
The main focus of this entry is illustrating how cacheing can be added to the naive recursive algorithm.
Some trivial optimizations are also included.
 
With these changes, the algorithm becomes quite performant. For example, the C implementation of jq accurately computes the value for the lantern configuration
[1,2,3,4,5,6,7] in less than a second on a 2.53GHz machine.
 
For lantern configurations with more than 2^53 permutations, the accuracy of the C implementation of jq is insufficient, but the Go implementation (gojq) can be used. For the configuration [1,2,3,4,5,6,7,8], gojq takes just over 4 minutes to produce the correct answer on the same machine.
 
<syntaxhighlight lang=jq>
# Input: an array representing a configuration of one or more lanterns.
# Output: the number of distinct ways to lower them.
def lanterns:
 
def organize: map(select(. > 0)) | sort;
 
# input and output: {cache, count}
def n($array):
($array | organize) as $organized
| ($organized|length) as $length
| if $length == 1 then .count = 1
elif $length == 2 and $organized[0] == 1 then .count = ($organized | add)
else .cache[$organized|tostring] as $n
| if $n then .count = $n
else reduce range(0; $length) as $i ({cache, count: 0, a : $organized};
.a[$i] += -1
| .a as $new
| n($new) as {count: $count, cache: $cache}
| .count += $count
| .cache = ($cache | .[$new | tostring] = $count)
| .a[$i] += 1 )
| {cache, count}
end
end;
. as $a | null | n($a) | .count;
 
"Lantern configuration => number of permutations",
([1,3,3],
[100,2],
(range(2; 10) as $nlanterns
| [range(1; $nlanterns)])
| "\(.) => \(lanterns)" )
</syntaxhighlight>
 
'''Invocation'''
<pre>
gojq -n -rf lanterns.jq
</pre>
{{output}}
<pre>
Lantern configuration => number of permutations
[1,3,3] => 140
[100,2] => 5151
[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
</pre>
 
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">""" rosettacode.org /wiki/Lantern_Problem """
using Combinatorics
function lanternproblem(verbose = true)
println("Input number of columns, then column heights in sequence:")
inputs = [parse(Int, i) for i in split(readline(), r"\s+")]
n = popfirst!(inputs)
println("\nThere are ", multinomial(BigInt.(inputs)...), " ways to take these ", n, " columns down.")
takedownways = unique(permutations(reduce(vcat, [fill(i, m) for (i, m) in enumerate(inputs)])))
println("\nThere are ", length(takedownways), " ways to take these ", n, " columns down.")
 
if verbose
idx, fullmat = 0, zeros(Int, n, maximum(n))
Line 107 ⟶ 623:
show(stdout, "text/plain", map(n -> n > 0 ? "$n " : " ", fullmat))
println("\n")
takedownways = unique(permutations(reduce(vcat, [fill(i, m) for (i, m) in enumerate(inputs)])))
for way in takedownways
print("[")
Line 118 ⟶ 635:
end
end
 
lanternproblem()
lanternproblem()
lanternproblem(false)
</lang>{{out}}
</syntaxhighlight>{{out}}
<pre style="height:64ex;overflow:scroll">
Input number of columns, then column heights in sequence:
Line 342 ⟶ 861:
[7, 6, 5, 4, 3, 1, 2]
[7, 6, 5, 4, 3, 2, 1]
 
Input number of columns, then column heights in sequence:
9 1 2 3 4 5 6 7 8 9
 
There are 65191584694745586153436251091200000 ways to take these 9 columns down.
</pre>
 
=={{header|Nim}}==
Recursive solution.
 
The number of elements in the columns are provided as command arguments.
<syntaxhighlight lang="Nim">import std/[os, strutils]
 
proc sequenceCount(columns: var seq[int]): int =
for icol in 1..columns.high:
if columns[icol] > 0:
dec columns[icol]
inc result, sequenceCount(columns)
inc columns[icol]
if result == 0: result = 1
 
let ncol = paramCount()
if ncol == 0:
quit "Missing parameters.", QuitFailure
var columns = newSeq[int](ncol + 1) # We will ignore the first column.
for i in 1..ncol:
let n = paramStr(i).parseInt()
if n < 0:
quit "Wrong number of lanterns.", QuitFailure
columns[i] = n
 
echo columns.sequenceCount()
</syntaxhighlight>
 
=={{header|Pascal}}==
Line 348 ⟶ 899:
 
This solution avoids recursion and calculates the result mathematically. As noted in the Picat solution, the result is a multinomial coefficient, e.g. with columns of length 3, 6, 4 the result is (3 + 6 + 4)!/(3!*6!*4!).
<langsyntaxhighlight lang="pascal">
program LanternProblem;
uses SysUtils;
Line 430 ⟶ 981:
until false;
end.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 446 ⟶ 997:
</pre>
 
=={{header|PhixPerl}}==
<syntaxhighlight lang="perl">#!/usr/bin/perl
===fast analytical count only===
 
<!--<lang Phix>(phixonline)-->
use strict; # https://rosettacode.org/wiki/Solve_hanging_lantern_problem
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
use warnings;
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
 
<span style="color: #008080;">function</span> <span style="color: #000000;">get_lantern</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
$_ = 'a bc def';
<span style="color: #004080;">mpz</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">z</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_inits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
 
<span style="color: #7060A8;">mpz_fac_ui</span><span style="color: #0000FF;">(</span><span style="color: #000000;">z</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">))</span>
my $answer = '';
<span style="color: #008080;">for</span> <span style="color: #000000;">d</span> <span style="color: #008080;">in</span> <span style="color: #000000;">s</span> <span style="color: #008080;">do</span>
find($_, '');
<span style="color: #7060A8;">mpz_fac_ui</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
print "count = @{[ $answer =~ tr/\n// ]}\n", $answer;
<span style="color: #7060A8;">mpz_fdiv_q</span><span style="color: #0000FF;">(</span><span style="color: #000000;">z</span><span style="color: #0000FF;">,</span><span style="color: #000000;">z</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
sub find
<span style="color: #008080;">return</span> <span style="color: #7060A8;">mpz_get_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">z</span><span style="color: #0000FF;">)</span>
{
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
my ($in, $found) = @_;
find( $` . $', $found . $& ) while $in =~ /\w\b/g;
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span>
$in =~ /\w/ or $answer .= '[' . $found =~ s/\B/,/gr . "]\n";
<span style="color: #004080;">sequence</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
}</syntaxhighlight>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%v = %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">get_lantern</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%v = %s\n"</span><span style="color: #0000FF;">,{{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},</span><span style="color: #000000;">get_lantern</span><span style="color: #0000FF;">({</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">})})</span>
<!--</lang>-->
{{out}}
<pre>
count = 60
{1} = 1
[a,c,b,f,e,d]
{1,2} = 3
[a,c,f,b,e,d]
{1,2,3} = 60
[a,c,f,e,b,d]
{1,2,3,4} = 12600
[a,c,f,e,d,b]
{1,2,3,4,5} = 37837800
[a,f,c,b,e,d]
{1,2,3,4,5,6} = 2053230379200
[a,f,c,e,b,d]
{1,2,3,4,5,6,7} = 2431106898187968000
[a,f,c,e,d,b]
{1,2,3,4,5,6,7,8} = 73566121315513295589120000
[a,f,e,c,b,d]
{1,3,3} = 140
[a,f,e,c,d,b]
[a,f,e,d,c,b]
[c,a,b,f,e,d]
[c,a,f,b,e,d]
[c,a,f,e,b,d]
[c,a,f,e,d,b]
[c,b,a,f,e,d]
[c,b,f,a,e,d]
[c,b,f,e,a,d]
[c,b,f,e,d,a]
[c,f,a,b,e,d]
[c,f,a,e,b,d]
[c,f,a,e,d,b]
[c,f,b,a,e,d]
[c,f,b,e,a,d]
[c,f,b,e,d,a]
[c,f,e,a,b,d]
[c,f,e,a,d,b]
[c,f,e,b,a,d]
[c,f,e,b,d,a]
[c,f,e,d,a,b]
[c,f,e,d,b,a]
[f,a,c,b,e,d]
[f,a,c,e,b,d]
[f,a,c,e,d,b]
[f,a,e,c,b,d]
[f,a,e,c,d,b]
[f,a,e,d,c,b]
[f,c,a,b,e,d]
[f,c,a,e,b,d]
[f,c,a,e,d,b]
[f,c,b,a,e,d]
[f,c,b,e,a,d]
[f,c,b,e,d,a]
[f,c,e,a,b,d]
[f,c,e,a,d,b]
[f,c,e,b,a,d]
[f,c,e,b,d,a]
[f,c,e,d,a,b]
[f,c,e,d,b,a]
[f,e,a,c,b,d]
[f,e,a,c,d,b]
[f,e,a,d,c,b]
[f,e,c,a,b,d]
[f,e,c,a,d,b]
[f,e,c,b,a,d]
[f,e,c,b,d,a]
[f,e,c,d,a,b]
[f,e,c,d,b,a]
[f,e,d,a,c,b]
[f,e,d,c,a,b]
[f,e,d,c,b,a]
</pre>
 
=={{header|Phix}}==
=== full solution ===
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">(),</span> <span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()+</span><span style="color: #000000;">1</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">get_lantern</span><span style="color: #0000FF;">(</span><span style="color: #004080;">mpz</span> <span style="color: #000000;">z</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">bool</span> <span style="color: #000000;">bJustCount</span><span style="color: #0000FF;">=</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">na</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">bJustCount</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">integersequence</span> <span style="color: #000000;">nodel</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getd_indexapply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #0000007060A8;">dlength</span><span style="color: #0000FF;">)</span>
<span style="color: #0080807060A8;">ifmpz_fac_ui</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nodez</span><span style="color: #0000FF;">!,</span><span style="color: #7060A8;">sum</span><span style="color: #0046000000FF;">NULL(</span><span style="color: #000000;">l</span><span style="color: #0080800000FF;">then))</span>
<span style="color: #7060A8004080;">mpz_set_strmpz</span><span style="color: #0000FF;">(</span><span style="color: #000000;">zf</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">getd_by_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">,</span><span style="color: #0000007060A8;">dmpz_init</span><span style="color: #0000FF;">)()</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">d</span> <span style="color: #008080;">returnin</span> <span style="color: #000000;">0l</span> <span style="color: #008080;">do</span>
<span style="color: #0080807060A8;">endmpz_fac_ui</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0080800000FF;">if)</span>
<span style="color: #7060A8;">mpz_fdiv_q</span><span style="color: #0000FF;">(</span><span style="color: #000000;">z</span><span style="color: #0000FF;">,</span><span style="color: #000000;">z</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">na</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #000000;">na</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">))</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">na</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)),</span><span style="color: #008000;">"1"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpz_set_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">z</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">""</span><span style="color: #0000FF;">}</span>
Line 507 ⟶ 1,107:
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">mpz</span> <span style="color: #000000;">z2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_lantern</span><span style="color: #0000FF;">(</span><span style="color: #000000;">z2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #000000004600;">bJustCountfalse</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">na</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">iffor</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">notto</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bJustCountr</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">thendo</span>
<span style="color: #008080000000;">forres</span> <span style="color: #0000000000FF;">k=</span> <span style="color: #0000FF7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1res</span> <span style="color: #0080800000FF;">to,</span> <span style="color: #7060A8000000;">lengthsi</span><span style="color: #0000FF;">(&</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)[</span><span style="color: #000000;">k</span><span style="color: #0080800000FF;">do])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">si</span><span style="color: #0000FF;">&</span><span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">mpz_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">z</span><span style="color: #0000FF;">,</span><span style="color: #000000;">z</span><span style="color: #0000FF;">,</span><span style="color: #000000;">z2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()></span><span style="color: #000000;">t1</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">progress</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"working... dict_size:%d\r"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">dict_size</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)})</span>
<span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()+</span><span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">si</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">mpz_get_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">z</span><span style="color: #0000FF;">),</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
Line 550 ⟶ 1,143:
<span style="color: #008000;">"FGHIJK"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"LMNOPQR"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"STUVWXYZ"</span><span style="color: #0000FF;">},</span>
<span style="color: #000080008000;font-">"abcdefghi"</span><span style="color:italic #0000FF;">-- JS copes fine, but 7 in 3.5s vs 8 in 41.5s,}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
-- - tad too long to stare at a blank screen.
-- (vs desktop with progress & as-completed.)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">JS</span><span style="color: #0000FF;">?</span><span style="color: #000000;">7</span><span style="color: #0000FF;">:</span><span style="color: #000000;">8</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)</span>
<!--</lang>-->
{{out}}
<pre>
1 = 1:
1 = 1:
1
 
1, 23  23 = 3 3:
132,312,321
 
1, 23 23, 456  456 = 60 60:
132654,136254,136524,136542,163254,163524,163542,165324,165342,165432
312654,316254,316524,316542,321654,326154,326514,326541,361254,361524
Line 575 ⟶ 1,165:
651432,653124,653142,653214,653241,653412,653421,654132,654312,654321
 
1, 234, 567 = 140
1, 234, 567 = 140
1234567890, ABCDEFGHIJKLMN, OPQRSTUVWXYZ = 2454860399191200
1234567890, ABCDEFGHIJKLMN, OPQRSTUVWXYZ = 2454860399191200
1 = 1
1 = 1
1, 23 = 3
1, 23 = 3
1, 23, 456 = 60
1, 23, 456 = 60
1, 23, 456, 7890 = 12600
1, 23, 456, 7890 = 12600
1, 23, 456, 7890, ABCDE = 37837800
1, 23, 456, 7890, ABCDE = 37837800
1, 23, 456, 7890, ABCDE, FGHIJK = 2053230379200
1, 23, 456, 7890, ABCDE, FGHIJK = 2053230379200
1, 23, 456, 7890, ABCDE, FGHIJK, LMNOPQR = 2431106898187968000
1, 23, 456, 7890, ABCDE, FGHIJK, LMNOPQR = 2431106898187968000
1, 23, 456, 7890, ABCDE, FGHIJK, LMNOPQR, STUVWXYZ = 73566121315513295589120000
1, 23, 456, 7890, ABCDE, FGHIJK, LMNOPQR, STUVWXYZ = 73566121315513295589120000
1, 23, 456, 7890, ABCDE, FGHIJK, LMNOPQR, STUVWXYZ, abcdefghi = 65191584694745586153436251091200000
"41.4s"
</pre>
 
=={{header|Picat}}==
{{trans|Python}}
<langsyntaxhighlight Picatlang="picat">main =>
run_lantern().
 
Line 616 ⟶ 1,206:
if Res == 0 then
Res := 1
end.</langsyntaxhighlight>
 
Some tests:
<langsyntaxhighlight Picatlang="picat">main =>
A = [1,2,3],
println(lantern(A)),
Line 625 ⟶ 1,215:
println(1..N=lantern(1..N))
end,
nl.</langsyntaxhighlight>
 
{{out}}
Line 642 ⟶ 1,232:
=={{header|Python}}==
===Recursive version===
{{trans|Visual Basic}}
<lang python>
<syntaxhighlight lang="python">
def getLantern(arr):
res = 0
Line 659 ⟶ 1,250:
a.append(int(input()))
print(getLantern(a))
</syntaxhighlight>
</lang>
 
===Math solution===
<langsyntaxhighlight lang="python">
import math
n = int(input())
Line 673 ⟶ 1,265:
res /= math.factorial(a[i])
print(int(res))
</syntaxhighlight>
</lang>
 
===Showing Sequences===
<syntaxhighlight lang="python">def seq(x):
if not any(x):
yield tuple()
 
for i, v in enumerate(x):
if v:
for s in seq(x[:i] + [v - 1] + x[i+1:]):
yield (i+1,) + s
 
# an example
for x in seq([1, 2, 3]):
print(x)</syntaxhighlight>
 
=={{header|Raku}}==
Note: All of these solutions accept the list of column sizes as command-line arguments and infer the number of columns from the number of sizes provided, rather than requiring that a count be supplied as an extra distinct parameter.
{{trans|Julia}}
Rather than take the number of columns as an explicit argument, this program infers the number from the size of the array of columns passed in.
 
===SequenceDirectly ascomputing columnsthe count===
{{trans|Pascal}}
The verbose mode of this version outputs the sequence of columns to remove lanterns from, rather than numbering the lanterns individually as in the description:
 
If all we need is the count, then we can compute that directly:
 
<syntaxhighlight lang="raku" line>unit sub MAIN(*@columns);
 
sub postfix:<!>($n) { [*] 1..$n }
 
say [+](@columns)! / [*](@columns»!);</syntaxhighlight>
 
{{Out}}
<pre>$ raku lanterns.raku 1 2 3
60</pre>
 
===Sequence as column numbers===
{{trans|Julia}}
If we want to list all of the sequences, we have to do some more work. This version outputs the sequences as lists of column numbers (assigned from 1 to N left to right); at each step the bottommost lantern from the numbered column is removed.
 
<syntaxhighlight lang="raku" perl6line>unit sub MAIN(*@columns, :v(:$verbose)=False);
 
my @sequences = @columns
Line 698 ⟶ 1,319:
say +@sequences;
}
</syntaxhighlight>
</lang>
 
{{Out}}
<pre>
<pre>$ raku lanterns.raku 1 2 3
60
$ raku lanterns.raku --verbose 1 2 3
There are 60 possible takedown sequences:
Line 719 ⟶ 1,339:
[3,3,3,2,2,1]</pre>
 
===Sequence as lanternslantern numbers===
ThisIf longerwe versionwant numbersindividually-numbered lanterns in the lanternssequence instead of column numbers, as in the example given in the task description., that requires yet more work:
 
<syntaxhighlight lang="raku" perl6line>unit sub MAIN(*@columns, :v(:$verbose)=False);
 
my @sequences = @columns
Line 755 ⟶ 1,375:
} else {
say +@sequences;
}</langsyntaxhighlight>
 
{{Out}}
<pre>$ raku lanterns.raku -v 1 2 3 4
1 2 4 7
3 5 8
6 9
There are 60 possible takedown sequences:
10
[1,3,2,6,5,4]
There are 12600 possible takedown sequences:
[1,3,6,2,6,5,4,10,9,8,7]
[1,3,2,6,5,102,4,9,8,7]
[1,3,2,6,5,10,9,4,8,7]
[1,3,2,6,5,10,9,8,4,7]
[1,3,2,6,5,10,9,8,7,4]
...
[10,9,8,7,6,5,3,4,1,3,2]
[10,9,8,7,6,5,4,3,41,2,1]
[10,9,8,7,6,5,4,1,3,2,1]</pre>
=={{header|Ruby}}==
[10,9,8,7,6,5,4,3,1,2]
===Directly computing the count===
[10,9,8,7,6,5,4,3,2,1]</pre>
 
Compute the count directly:
=={{header|VBA}}==
<syntaxhighlight lang="ruby" line>Factorial = Hash.new{|h, k| h[k] = k * h[k-1] } # a memoized factorial
Factorial[0] = 1
 
def count_perms_with_reps(ar)
:''See [[Lantern Problem#Visual Basic|Visual Basic]]''
Factorial[ar.sum] / ar.inject{|prod, m| prod * Factorial[m]}
end
 
ar, input = [], ""
=={{header|Visual Basic}}==
puts "Input column heights in sequence (empty line to end input):"
ar << input.to_i until (input=gets) == "\n"
puts "There are #{count_perms_with_reps(ar)} ways to take these #{ar.size} columns down."
</syntaxhighlight>
{{Out}}
<pre>Input column heights in sequence (empty line to end input):
1
2
3
4
5
6
7
8
 
There are 73566121315513295589120000 ways to take these 8 columns down.
{{works with|Visual Basic|6}}
</pre>
 
=={{header|Uiua}}==
;Main code
{{works with|Uiua|0.10.0}}
<lang vb>
<syntaxhighlight lang="Uiua">
Dim n As Integer, c As Integer
Fac ← /×+1⇡
Dim a() As Integer
Lant ← ÷⊃(/(×⊙Fac)|Fac/+)
 
Lant [1 2 3]
Private Sub Command1_Click()
Lant [1 3 3]
Dim res As Integer
Lant [1 3 3 5 7]
If c < n Then Label3.Caption = "Please input completely.": Exit Sub
</syntaxhighlight>
res = getLantern(a())
{{out}}
Label3.Caption = "Result:" + Str(res)
<pre>
End Sub
60
 
140
Private Sub Text1_Change()
5587021440
If Val(Text1.Text) <> 0 Then
</pre>
n = Val(Text1.Text)
ReDim a(1 To n) As Integer
End If
End Sub
 
 
Private Sub Text2_KeyPress(KeyAscii As Integer)
If KeyAscii = Asc(vbCr) Then
If Val(Text2.Text) = 0 Then Exit Sub
c = c + 1
If c > n Then Exit Sub
a(c) = Val(Text2.Text)
List1.AddItem Str(a(c))
Text2.Text = ""
End If
End Sub
 
Function getLantern(arr() As Integer) As Integer
Dim res As Integer
For i = 1 To n
If arr(i) <> 0 Then
arr(i) = arr(i) - 1
res = res + getLantern(arr())
arr(i) = arr(i) + 1
End If
Next i
If res = 0 Then res = 1
getLantern = res
End Function</lang>
 
;Form code:
<lang vb>
VERSION 5.00
Begin VB.Form Form1
Caption = "Get Lantern"
ClientHeight = 4410
ClientLeft = 120
ClientTop = 465
ClientWidth = 6150
LinkTopic = "Form1"
ScaleHeight = 4410
ScaleWidth = 6150
StartUpPosition = 3
Begin VB.CommandButton Command1
Caption = "Start"
Height = 495
Left = 2040
TabIndex = 5
Top = 3000
Width = 1935
End
Begin VB.ListBox List1
Height = 1320
Left = 360
TabIndex = 4
Top = 1440
Width = 5175
End
Begin VB.TextBox Text2
Height = 855
Left = 3360
TabIndex = 1
Top = 480
Width = 2175
End
Begin VB.TextBox Text1
Height = 855
Left = 360
TabIndex = 0
Top = 480
Width = 2175
End
Begin VB.Label Label3
Height = 495
Left = 2040
TabIndex = 6
Top = 3720
Width = 2295
End
Begin VB.Label Label2
Caption = "Number Each"
Height = 375
Left = 3960
TabIndex = 3
Top = 120
Width = 1695
End
Begin VB.Label Label1
Caption = "Total"
Height = 255
Left = 960
TabIndex = 2
Top = 120
Width = 1455
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False</lang>
 
=={{header|Wren}}==
Line 904 ⟶ 1,441:
{{trans|Python}}
The result for n == 5 is slow to emerge.
<langsyntaxhighlight ecmascriptlang="wren">var lantern // recursive function
lantern = Fn.new { |n, a|
var count = 0
Line 924 ⟶ 1,461:
n = n + 1
System.print("%(a) => %(lantern.call(n, a))")
}</langsyntaxhighlight>
 
{{out}}
Line 937 ⟶ 1,474:
===Version 2===
{{libheader|Wren-perm}}
{{libheader|Wren-big}}
Alternatively, using library methods.
<langsyntaxhighlight ecmascriptlang="wren">import "./perm" for Perm
import "./big" for BigInt
 
var listPerms = Fn.new { |a, rowSize|
System.print("Number of permutations for n (<= 5) groups and lanterns per group [1..n]:")
var lows = List.filled(a.count, 0)
var sum = 0
var mlist = []
for (i in 0...a.count) {
sum = sum + a[i]
lows[i] = sum
mlist = mlist + [i+1] * a[i]
}
var n = Perm.countDistinct(sum, a)
System.print("\nList of %(n) permutations for %(a.count) groups and lanterns per group %(a):")
var count = 0
for (p in Perm.listDistinct(mlist)) {
var curr = lows.toList
var perm = List.filled(sum, 0)
for (i in 0...sum) {
perm[i] = curr[p[i]-1]
curr[p[i]-1] = curr[p[i]-1] - 1
}
System.write("%(perm) ")
count = count + 1
if (count % rowSize == 0) System.print()
}
if (count % rowSize != 0) System.print()
}
 
System.print("Number of permutations for the lanterns per group shown:")
var n = 0
for (i in 1..59) {
var a = (1..i).toList
n = n + i
System.print("%(a) => %(PermBigInt.countDistinctmultinomial(n, a))")
}
var a = [1, 3, 3]
 
System.print("\nList%(a) of=> permutations for 3 groups and lanterns per group [1, 2%(BigInt.multinomial(7, 3]:a))")
var lowsa = [110, 314, 612]
System.print("%(a) => %(BigInt.multinomial(36, a))")
for (p in Perm.listDistinct([1, 2, 2, 3, 3, 3])) {
listPerms.call([1, 2, 3], 4)
var curr = lows.toList
listPerms.call([1, 3, 3], 3)</syntaxhighlight>
var perm = List.filled(6, 0)
for (i in 0..5) {
perm[i] = curr[p[i]-1]
curr[p[i]-1] = curr[p[i]-1] - 1
}
System.print(perm)
}</lang>
 
{{out}}
<pre>
Number of permutations for n (<= 5) groups andthe lanterns per group [1..n]shown:
[1] => 1
[1, 2] => 3
Line 968 ⟶ 1,527:
[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
[1, 2, 3, 4, 5, 6, 7, 8, 9] => 65191584694745586153436251091200000
[1, 3, 3] => 140
[10, 14, 12] => 2454860399191200
 
List of 60 permutations for 3 groups and lanterns per group [1, 2, 3]:
[1, 3, 2, 6, 5, 4] [1, 3, 6, 2, 5, 4] [1, 3, 6, 5, 2, 4] [1, 3, 6, 5, 4, 2] [1, 6, 3, 2, 5, 4]
[1, 3, 2, 6, 5, 4]
[1, 6, 3, 5, 2, 4] [1, 6, 3, 5, 4, 2] [1, 6, 5, 3, 2, 4] [1, 6, 5, 3, 4, 2] [1, 6, 5, 4, 3, 2]
[1, 3, 6, 2, 5, 4]
[3, 1, 2, 6, 5, 4] [3, 1, 6, 2, 5, 4] [3, 1, 6, 5, 2, 4] [3, 1, 6, 5, 4, 2] [3, 2, 1, 6, 5, 4]
[1, 3, 6, 5, 2, 4]
[3, 2, 6, 1, 5, 4] [3, 2, 6, 5, 1, 4] [3, 2, 6, 5, 4, 1] [3, 6, 2, 1, 5, 4] [3, 6, 2, 5, 1, 4]
[1, 3, 6, 5, 4, 2]
[3, 6, 2, 5, 4, 1] [3, 6, 1, 2, 5, 4] [3, 6, 1, 5, 2, 4] [3, 6, 1, 5, 4, 2] [3, 6, 5, 1, 2, 4]
[1, 6, 3, 2, 5, 4]
[3, 6, 5, 1, 4, 2] [3, 6, 5, 2, 1, 4] [3, 6, 5, 2, 4, 1] [3, 6, 5, 4, 2, 1] [3, 6, 5, 4, 1, 2]
[1, 6, 3, 5, 2, 4]
[6, 3, 2, 1, 5, 4] [6, 3, 2, 5, 1, 4] [6, 3, 2, 5, 4, 1] [6, 3, 1, 2, 5, 4] [6, 3, 1, 5, 2, 4]
[1, 6, 3, 5, 4, 2]
[6, 3, 1, 5, 4, 2] [6, 3, 5, 1, 2, 4] [6, 3, 5, 1, 4, 2] [6, 3, 5, 2, 1, 4] [6, 3, 5, 2, 4, 1]
[1, 6, 5, 3, 2, 4]
[6, 3, 5, 4, 2, 1] [6, 3, 5, 4, 1, 2] [6, 1, 3, 2, 5, 4] [6, 1, 3, 5, 2, 4] [6, 1, 3, 5, 4, 2]
[1, 6, 5, 3, 4, 2]
[6, 1, 5, 3, 2, 4] [6, 1, 5, 3, 4, 2] [6, 1, 5, 4, 3, 2] [6, 5, 3, 1, 2, 4] [6, 5, 3, 1, 4, 2]
[1, 6, 5, 4, 3, 2]
[6, 5, 3, 2, 1, 4] [6, 5, 3, 2, 4, 1] [6, 5, 3, 4, 2, 1] [6, 5, 3, 4, 1, 2] [6, 5, 1, 3, 2, 4]
[3, 1, 2, 6, 5, 4]
[6, 5, 1, 3, 4, 2] [6, 5, 1, 4, 3, 2] [6, 5, 4, 1, 3, 2] [6, 5, 4, 3, 1, 2] [6, 5, 4, 3, 2, 1]
[3, 1, 6, 2, 5, 4]
 
[3, 1, 6, 5, 2, 4]
List of 140 permutations for 3 groups and lanterns per group [1, 3, 3]:
[3, 1, 6, 5, 4, 2]
[1, 4, 3, 2, 7, 6, 5] [1, 4, 3, 7, 2, 6, 5] [1, 4, 3, 7, 6, 2, 5] [1, 4, 3, 7, 6, 5, 2]
[1, 4, 7, 3, 2, 6, 5] [1, 4, 7, 3, 6, 2, 5] [1, 4, 7, 3, 6, 5, 2] [1, 4, 7, 6, 3, 2, 5]
[1, 4, 7, 6, 3, 5, 2] [1, 4, 7, 6, 5, 3, 2] [1, 7, 4, 3, 2, 6, 5] [1, 7, 4, 3, 6, 2, 5]
[1, 7, 4, 3, 6, 5, 2] [1, 7, 4, 6, 3, 2, 5] [1, 7, 4, 6, 3, 5, 2] [1, 7, 4, 6, 5, 3, 2]
[1, 7, 6, 4, 3, 2, 5] [1, 7, 6, 4, 3, 5, 2] [1, 7, 6, 4, 5, 3, 2] [1, 7, 6, 5, 4, 3, 2]
[4, 1, 3, 2, 7, 6, 5] [4, 1, 3, 7, 2, 6, 5] [4, 1, 3, 7, 6, 2, 5] [4, 1, 3, 7, 6, 5, 2]
[4, 1, 7, 3, 2, 6, 5] [4, 1, 7, 3, 6, 2, 5] [4, 1, 7, 3, 6, 5, 2] [4, 1, 7, 6, 3, 2, 5]
[4, 1, 7, 6, 3, 5, 2] [4, 1, 7, 6, 5, 3, 2] [4, 3, 1, 2, 7, 6, 5] [4, 3, 1, 7, 2, 6, 5]
[3, 6, 1, 2, 5, 4]
[4, 3, 1, 7, 6, 2, 5] [4, 3, 1, 7, 6, 5, 2] [4, 3, 2, 1, 7, 6, 5] [4, 3, 2, 7, 1, 6, 5]
[4, 3, 2, 7, 6, 1, 5] [4, 3, 2, 7, 6, 5, 1] [4, 3, 7, 2, 1, 6, 5] [4, 3, 7, 2, 6, 1, 5]
[4, 3, 7, 2, 6, 5, 1] [4, 3, 7, 1, 2, 6, 5] [4, 3, 7, 1, 6, 2, 5] [4, 3, 7, 1, 6, 5, 2]
[4, 3, 7, 6, 1, 2, 5] [4, 3, 7, 6, 1, 5, 2] [4, 3, 7, 6, 2, 1, 5] [4, 3, 7, 6, 2, 5, 1]
[4, 3, 7, 6, 5, 2, 1] [4, 3, 7, 6, 5, 1, 2] [4, 7, 3, 2, 1, 6, 5] [4, 7, 3, 2, 6, 1, 5]
[4, 7, 3, 2, 6, 5, 1] [4, 7, 3, 1, 2, 6, 5] [4, 7, 3, 1, 6, 2, 5] [4, 7, 3, 1, 6, 5, 2]
[4, 7, 3, 6, 1, 2, 5] [4, 7, 3, 6, 1, 5, 2] [4, 7, 3, 6, 2, 1, 5] [4, 7, 3, 6, 2, 5, 1]
[4, 7, 3, 6, 5, 2, 1] [4, 7, 3, 6, 5, 1, 2] [4, 7, 1, 3, 2, 6, 5] [4, 7, 1, 3, 6, 2, 5]
[4, 7, 1, 3, 6, 5, 2] [4, 7, 1, 6, 3, 2, 5] [4, 7, 1, 6, 3, 5, 2] [4, 7, 1, 6, 5, 3, 2]
[4, 7, 6, 3, 1, 2, 5] [4, 7, 6, 3, 1, 5, 2] [4, 7, 6, 3, 2, 1, 5] [4, 7, 6, 3, 2, 5, 1]
[4, 7, 6, 3, 5, 2, 1] [4, 7, 6, 3, 5, 1, 2] [4, 7, 6, 1, 3, 2, 5] [4, 7, 6, 1, 3, 5, 2]
[4, 7, 6, 1, 5, 3, 2] [4, 7, 6, 5, 1, 3, 2] [4, 7, 6, 5, 3, 1, 2] [4, 7, 6, 5, 3, 2, 1]
[7, 4, 3, 2, 1, 6, 5] [7, 4, 3, 2, 6, 1, 5] [7, 4, 3, 2, 6, 5, 1] [7, 4, 3, 1, 2, 6, 5]
[7, 4, 3, 1, 6, 2, 5] [7, 4, 3, 1, 6, 5, 2] [7, 4, 3, 6, 1, 2, 5] [7, 4, 3, 6, 1, 5, 2]
[7, 4, 3, 6, 2, 1, 5] [7, 4, 3, 6, 2, 5, 1] [7, 4, 3, 6, 5, 2, 1] [7, 4, 3, 6, 5, 1, 2]
[7, 4, 1, 3, 2, 6, 5] [7, 4, 1, 3, 6, 2, 5] [7, 4, 1, 3, 6, 5, 2] [7, 4, 1, 6, 3, 2, 5]
[7, 4, 1, 6, 3, 5, 2] [7, 4, 1, 6, 5, 3, 2] [7, 4, 6, 3, 1, 2, 5] [7, 4, 6, 3, 1, 5, 2]
[7, 4, 6, 3, 2, 1, 5] [7, 4, 6, 3, 2, 5, 1] [7, 4, 6, 3, 5, 2, 1] [7, 4, 6, 3, 5, 1, 2]
[7, 4, 6, 1, 3, 2, 5] [7, 4, 6, 1, 3, 5, 2] [7, 4, 6, 1, 5, 3, 2] [7, 4, 6, 5, 1, 3, 2]
[7, 4, 6, 5, 3, 1, 2] [7, 4, 6, 5, 3, 2, 1] [7, 1, 4, 3, 2, 6, 5] [7, 1, 4, 3, 6, 2, 5]
[7, 1, 4, 3, 6, 5, 2] [7, 1, 4, 6, 3, 2, 5] [7, 1, 4, 6, 3, 5, 2] [7, 1, 4, 6, 5, 3, 2]
[7, 1, 6, 4, 3, 2, 5] [7, 1, 6, 4, 3, 5, 2] [7, 1, 6, 4, 5, 3, 2] [7, 1, 6, 5, 4, 3, 2]
[7, 6, 4, 3, 1, 2, 5] [7, 6, 4, 3, 1, 5, 2] [7, 6, 4, 3, 2, 1, 5] [7, 6, 4, 3, 2, 5, 1]
[7, 6, 4, 3, 5, 2, 1] [7, 6, 4, 3, 5, 1, 2] [7, 6, 4, 1, 3, 2, 5] [7, 6, 4, 1, 3, 5, 2]
[7, 6, 4, 1, 5, 3, 2] [7, 6, 4, 5, 1, 3, 2] [7, 6, 4, 5, 3, 1, 2] [7, 6, 4, 5, 3, 2, 1]
[7, 6, 1, 4, 3, 2, 5] [7, 6, 1, 4, 3, 5, 2] [7, 6, 1, 4, 5, 3, 2] [7, 6, 1, 5, 4, 3, 2]
[7, 6, 5, 4, 1, 3, 2] [7, 6, 5, 4, 3, 1, 2] [7, 6, 5, 4, 3, 2, 1] [7, 6, 5, 1, 4, 3, 2]
</pre>
[6, 5, 3, 1, 4, 2]
 
[6, 5, 3, 2, 1, 4]
=={{header|XPL0}}==
[6, 5, 3, 2, 4, 1]
<syntaxhighlight lang="xpl0">char N, Column, Sequences, I, Lanterns;
[6, 5, 3, 4, 2, 1]
 
[6, 5, 3, 4, 1, 2]
proc Tally(Level);
[6, 5, 1, 3, 2, 4]
char Level, Col;
[6, 5, 1, 3, 4, 2]
[6,for 5,Col:= 1,0 4,to 3,N-1 2]do
if Column(Col) > 0 then
[6, 5, 4, 1, 3, 2]
[Column(Col):= Column(Col)-1;
[6, 5, 4, 3, 1, 2]
if Level = Lanterns-1 then Sequences:= Sequences+1
[6, 5, 4, 3, 2, 1]
else Tally(Level+1);
Column(Col):= Column(Col)+1;
];
];
 
[Sequences:= 0; Lanterns:= 0;
N:= IntIn(0);
Column:= Reserve(N);
for I:= 0 to N-1 do
[Column(I):= IntIn(0);
Lanterns:= Lanterns + Column(I);
];
Tally(0);
IntOut(0, Sequences);
]</syntaxhighlight>
 
{{out}}
<pre>
5
1 3 5 2 4
37837800
</pre>
60

edits