Lah numbers

Revision as of 23:50, 24 April 2022 by rosettacode>Jeff mallatt (Fix problem in Scheme.)

Lah numbers, sometimes referred to as Stirling numbers of the third kind, are coefficients of polynomial expansions expressing rising factorials in terms of falling factorials.

Task
Lah numbers
You are encouraged to solve this task according to the task description, using any language you may know.

Unsigned Lah numbers count the number of ways a set of n elements can be partitioned into k non-empty linearly ordered subsets.

Lah numbers are closely related to Stirling numbers of the first & second kinds, and may be derived from them.

Lah numbers obey the identities and relations:

  L(n, 0), L(0, k) = 0   # for n, k > 0
  L(n, n) = 1
  L(n, 1) = n!
  L(n, k) =           ( n! * (n - 1)! ) / ( k! * (k - 1)! ) / (n - k)!      # For unsigned Lah numbers
     or
  L(n, k) = (-1)**n * ( n! * (n - 1)! ) / ( k! * (k - 1)! ) / (n - k)!      # For   signed Lah numbers
Task
  • Write a routine (function, procedure, whatever) to find unsigned Lah numbers. There are several methods to generate unsigned Lah numbers. You are free to choose the most appropriate for your language. If your language has a built-in, or easily, publicly available library implementation, it is acceptable to use that.
  • Using the routine, generate and show here, on this page, a table (or triangle) showing the unsigned Lah numbers, L(n, k), up to L(12, 12). it is optional to show the row / column for n == 0 and k == 0. It is optional to show places where L(n, k) == 0 (when k > n).
  • If your language supports large integers, find and show here, on this page, the maximum value of L(n, k) where n == 100.


See also


Related Tasks



11l

Translation of: Python

<lang 11l>F lah(BigInt n, BigInt k)

  I k == 1
     R factorial(n)
  I k == n
     R BigInt(1)
  I k > n
     R BigInt(0)
  I k < 1 | n < 1
     R BigInt(0)
  R (factorial(n) * factorial(n - 1)) I/ (factorial(k) * factorial(k - 1)) I/ factorial(n - k)

print(‘Unsigned Lah numbers: L(n, k):’) print(‘n/k ’, end' ‘ ’) L(i) 13

  print(‘#11’.format(i), end' ‘ ’)

print() L(row) 13

  print(‘#<4’.format(row), end' ‘ ’)
  L(i) 0 .. row
     V l = lah(row, i)
     print(‘#11’.format(l), end' ‘ ’)
  print()

print("\nMaximum value from the L(100, *) row:") V maxVal = max((0.<100).map(a -> lah(100, a))) print(maxVal)</lang>

Output:
Unsigned Lah numbers: L(n, k):
n/k            0           1           2           3           4           5           6           7           8           9          10          11          12 
0              1 
1              0           1 
2              0           2           1 
3              0           6           6           1 
4              0          24          36          12           1 
5              0         120         240         120          20           1 
6              0         720        1800        1200         300          30           1 
7              0        5040       15120       12600        4200         630          42           1 
8              0       40320      141120      141120       58800       11760        1176          56           1 
9              0      362880     1451520     1693440      846720      211680       28224        2016          72           1 
10             0     3628800    16329600    21772800    12700800     3810240      635040       60480        3240          90           1 
11             0    39916800   199584000   299376000   199584000    69854400    13970880     1663200      118800        4950         110           1 
12             0   479001600  2634508800  4390848000  3293136000  1317254400   307359360    43908480     3920400      217800        7260         132           1 

Maximum value from the L(100, *) row:
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

ALGOL 68

Works with: ALGOL 68G version Any - tested with release 2.8.3.win32
Translation of: ALGOL W

Uses Algol 68G's LONG LONG INT which has programmer-specifiable precision, so can find Lah numbers with n = 100 and need not use the scaling "trick" used by the Algol W sample. <lang algol68>BEGIN # calculate Lah numbers upto L( 12, 12 ) #

   PR precision 400 PR # set the precision for LONG LONG INT                       #
   # returns Lah Number L( n, k ), f must be a table of factorials to at least n   #
   PROC lah = ( INT n, k, []LONG LONG INT f )LONG LONG INT:
        IF   n = k          THEN 1
        ELIF n = 0 OR k = 0 THEN 0
        ELIF k = 1          THEN f[ n ]
        ELIF k > n          THEN 0
        ELSE
           # general case: ( n! * ( n - 1 )! ) / ( k! * ( k - 1 )! ) / ( n - k )!  #
           # we re-arrange the above to:                                           #
           #   (    n!      /    k! )      -- t1                                   #
           # * ( ( n - 1 )! / ( k - 1 )! ) -- t2                                   #
           # / ( n - k )!                                                          #
           LONG LONG INT t1 = f[ n     ] OVER f[ k     ];
           LONG LONG INT t2 = f[ n - 1 ] OVER f[ k - 1 ];
           ( t1 * t2 ) OVER f[ n - k ]
        FI # lah # ;
   INT max n       = 100; # max n for Lah Numbers                                  #
   INT max display =  12; # max n to display L( n, k ) values                      # 
   # table of factorials up to max n                                               #
   [ 1 : max n ]LONG LONG INT factorial;
   BEGIN
       LONG LONG INT f := 1;
       FOR i TO UPB factorial DO factorial[ i ] := f *:= i OD
   END;
   # show the Lah numbers                                                          #
   print( ( "Unsigned Lah numbers", newline ) );
   print( ( "n/k  0" ) );
   FOR i FROM 1 TO max display DO print( ( whole( i, -11 ) ) ) OD;
   print( ( newline ) );
   FOR n FROM 0 TO max display DO
       print( ( whole( n, -2 ) ) );
       print( ( whole( lah( n, 0, factorial ), -4 ) ) );
       FOR k FROM 1 TO n DO
           print( ( whole( lah( n, k, factorial ), -11 ) ) )
       OD;
       print( ( newline ) )
   OD;
   # maximum value of a Lah number for n = 100                                     #
   LONG LONG INT max 100 := 0;
   FOR k FROM 0 TO 100 DO
       LONG LONG INT lah n k = lah( 100, k, factorial );
       IF lah n k > max 100 THEN max 100 := lah n k FI
   OD;
   print( ( "maximum Lah number for n = 100: ", whole( max 100, 0 ), newline ) )

END</lang>

Output:
Unsigned Lah numbers
n/k  0          1          2          3          4          5          6          7          8          9         10         11         12
 0   1
 1   0          1
 2   0          2          1
 3   0          6          6          1
 4   0         24         36         12          1
 5   0        120        240        120         20          1
 6   0        720       1800       1200        300         30          1
 7   0       5040      15120      12600       4200        630         42          1
 8   0      40320     141120     141120      58800      11760       1176         56          1
 9   0     362880    1451520    1693440     846720     211680      28224       2016         72          1
10   0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11   0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12   0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1
maximum Lah number for n = 100: 44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

ALGOL W

Algol W's only integer type is signed 32 bit integers.
As L(12,2), L(12,3) and L(12,4) are too large for signed 32 bit integers, this sample scales the result by an appropriate power of 10 to enable the table to be printed up to L(12,12). Luckily, the problematic L(12,k) values all have at least 2 trailing zeros. <lang algolw>begin % calculate Lah numbers upto L( 12, 12 )  %

   % sets lahNumber to L( n, k ), lahScale is returned as the power of 10          %
   % lahNumber should be multiplied by                                             %
   % f must be a table of factorials to at least n                                 %
   procedure L ( integer value n, k
               ; integer array f ( * )
               ; integer result lahNumber, lahScale
               ) ;
       if      n = k          then begin lahNumber := 1;      lahScale := 0 end
       else if n = 0 or k = 0 then begin lahNumber := 0;      lahScale := 0 end
       else if k = 1          then begin lahNumber := f( n ); lahScale := 0 end
       else if k > n          then begin lahNumber := 0;      lahScale := 0 end
       else begin
           % general case: ( n! * ( n - 1 )! ) / ( k! * ( k - 1 )! ) / ( n - k )!  %
           % Algol W has only 32 bit signed integers so we need to avoid overflow  %
           % we re-arrange the above to:                                           %
           %   ( n! / k! / ( n - k ) ! )  -- t1                                    %
           % * ( ( n - 1 )! / ( k - 1 )!  -- t2                                    %
           % and if necessary, reduce t1 and t2 by powers of 10                    %
           integer t1, t2, d1, d2, v;
           t1 := f( n     ) div f( k     ) div f( n - k );
           t2 := f( n - 1 ) div f( k - 1 );
           % calculate the number of digits for t1 and t2                          %
           lahScale := d1 := d2 := 0;
           v := t1; while v > 0 do begin d1 := d1 + 1; v := v div 10 end;
           v := t2; while v > 0 do begin d2 := d2 + 1; v := v div 10 end;
           if d1 + d2 > 8 then begin
               % the result will overflow reduce t1 and t2 by an appropriate power %
               % of 10 and set lahScale accordingly                                %
               while t1 rem 10 = 0 do begin lahScale := lahScale + 1; t1 := t1 div 10 end;
               while t2 rem 10 = 0 do begin lahScale := lahScale + 1; t2 := t2 div 10 end;
           end if_d1_plus_d2_gt_8;
           lahNumber := t1 * t2
       end L;
   % table of factorials up to 12                                 %
   integer array factorial ( 1 :: 12 );
   % compute the factorials                                       %
   begin
       integer f; f := 1;
       for i := 1 until 12 do begin f := f * i; factorial( i ) := f end
   end;
   % show the Lah numbers                                         %
   write( "Unsigned Lah numbers" );
   write( "n/k " );
   for i := 0 until 12 do writeon( i_w := 11, s_w := 0, i );
   for n := 0 until 12 do begin
       write( s_w := 2, i_w := 2, n );
       for k := 0 until n do begin
           integer lahNumber, lahScale;
           L( n, k, factorial, lahNumber, lahScale );
           writeon( S_W := 0, i_w := 11 - lahScale, lahNumber );
           for s := 1 until lahScale do writeon( s_w := 0, "0" )
       end for_k
   end for_n

end.</lang>

Output:
Unsigned Lah numbers
n/k           0          1          2          3          4          5          6          7          8          9         10         11         12
 0            1
 1            0          1
 2            0          2          1
 3            0          6          6          1
 4            0         24         36         12          1
 5            0        120        240        120         20          1
 6            0        720       1800       1200        300         30          1
 7            0       5040      15120      12600       4200        630         42          1
 8            0      40320     141120     141120      58800      11760       1176         56          1
 9            0     362880    1451520    1693440     846720     211680      28224       2016         72          1
10            0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11            0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12            0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1

Arturo

<lang rebol>factorial: function [n]-> product 1..n

lah: function [n,k][

   if k=1 -> return factorial n
   if k=n -> return 1
   if k>n -> return 0
   if or? k<1 n<1 -> return 0
   return (((factorial n)*factorial n-1) / ((factorial k) * factorial k-1)) / factorial n-k

]

print @["n/k"] ++ map to [:string] 1..12 's -> pad s 10 print repeat "-" 136 loop 1..12 'x [

   print @[pad to :string x 3] ++ map to [:string] map 1..12 'y -> lah x y 's -> pad s 10

]</lang>

Output:
n/k          1          2          3          4          5          6          7          8          9         10         11         12 
----------------------------------------------------------------------------------------------------------------------------------------
  1          1          0          0          0          0          0          0          0          0          0          0          0 
  2          2          1          0          0          0          0          0          0          0          0          0          0 
  3          6          6          1          0          0          0          0          0          0          0          0          0 
  4         24         36         12          1          0          0          0          0          0          0          0          0 
  5        120        240        120         20          1          0          0          0          0          0          0          0 
  6        720       1800       1200        300         30          1          0          0          0          0          0          0 
  7       5040      15120      12600       4200        630         42          1          0          0          0          0          0 
  8      40320     141120     141120      58800      11760       1176         56          1          0          0          0          0 
  9     362880    1451520    1693440     846720     211680      28224       2016         72          1          0          0          0 
 10    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1          0          0 
 11   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1          0 
 12  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1

AWK

<lang AWK>

  1. syntax: GAWK -f LAH_NUMBERS.AWK
  2. converted from C

BEGIN {

   print("unsigned Lah numbers: L(n,k)")
   printf("n/k")
   for (i=0; i<13; i++) {
     printf("%11d",i)
   }
   printf("\n")
   for (row=0; row<13; row++) {
     printf("%-3d",row)
     for (i=0; i<row+1; i++) {
       printf(" %10d",lah(row,i))
     }
     printf("\n")
   }
   exit(0)

} function factorial(n, res) {

   res = 1
   if (n == 0) { return(res) }
   while (n > 0) { res *= n-- }
   return(res)

} function lah(n,k) {

   if (k == 1) { return factorial(n) }
   if (k == n) { return(1) }
   if (k > n) { return(0) }
   if (k < 1 || n < 1) { return(0) }
   return (factorial(n) * factorial(n-1)) / (factorial(k) * factorial(k-1)) / factorial(n-k)

} </lang>

Output:
unsigned Lah numbers: L(n,k)
n/k          0          1          2          3          4          5          6          7          8          9         10         11         12
0            1
1            0          1
2            0          2          1
3            0          6          6          1
4            0         24         36         12          1
5            0        120        240        120         20          1
6            0        720       1800       1200        300         30          1
7            0       5040      15120      12600       4200        630         42          1
8            0      40320     141120     141120      58800      11760       1176         56          1
9            0     362880    1451520    1693440     846720     211680      28224       2016         72          1
10           0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11           0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12           0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1

BQN

F is a function that computes the factorial of a number. It returns 0 for negative numbers.

Lah computes the lah function, called as n Lah k.

The last line builds a table where the rows represent n and columns represent k. <lang bqn>F ← (≥⟜0)◶⟨0,×´1+↕⟩ Lah ← {

 𝕨 𝕊 0: 0;
 0 𝕊 𝕩: 0;
 𝕨 𝕊 1: F 𝕨;
 n 𝕊 k:
 (n=k)⊑⟨((n ×○F n-1) ÷ k ×○F k-1) (0=⊢)◶÷‿0 F n-k, 1⟩

}

•Show Lah⌜˜↕12</lang><lang>┌─ ╵ 0 0 0 0 0 0 0 0 0 0 0 0

 0        1         0         0         0        0        0       0      0    0   0 0  
 0        2         1         0         0        0        0       0      0    0   0 0  
 0        6         6         1         0        0        0       0      0    0   0 0  
 0       24        36        12         1        0        0       0      0    0   0 0  
 0      120       240       120        20        1        0       0      0    0   0 0  
 0      720      1800      1200       300       30        1       0      0    0   0 0  
 0     5040     15120     12600      4200      630       42       1      0    0   0 0  
 0    40320    141120    141120     58800    11760     1176      56      1    0   0 0  
 0   362880   1451520   1693440    846720   211680    28224    2016     72    1   0 0  
 0  3628800  16329600  21772800  12700800  3810240   635040   60480   3240   90   1 0  
 0 39916800 199584000 299376000 199584000 69854400 13970880 1663200 118800 4950 110 1  
                                                                                      ┘</lang>

Try It!

C

Translation of: D

<lang c>#include <stdint.h>

  1. include <stdio.h>

uint64_t factorial(uint64_t n) {

   uint64_t res = 1;
   if (n == 0) return res;
   while (n > 0) res *= n--;
   return res;

}

uint64_t lah(uint64_t n, uint64_t k) {

   if (k == 1) return factorial(n);
   if (k == n) return 1;
   if (k > n) return 0;
   if (k < 1 || n < 1) return 0;
   return (factorial(n) * factorial(n - 1)) / (factorial(k) * factorial(k - 1)) / factorial(n - k);

}

int main() {

   int row, i;
   printf("Unsigned Lah numbers: L(n, k):\n");
   printf("n/k ");
   for (i = 0; i < 13; i++) {
       printf("%10d ", i);
   }
   printf("\n");
   for (row = 0; row < 13; row++) {
       printf("%-3d", row);
       for (i = 0; i < row + 1; i++) {
           uint64_t l = lah(row, i);
           printf("%11lld", l);
       }
       printf("\n");
   }
   return 0;

}</lang>

Output:
Unsigned Lah numbers: L(n, k):
n/k          0          1          2          3          4          5          6          7          8          9         10         11         12
0            1
1            0          1
2            0          2          1
3            0          6          6          1
4            0         24         36         12          1
5            0        120        240        120         20          1
6            0        720       1800       1200        300         30          1
7            0       5040      15120      12600       4200        630         42          1
8            0      40320     141120     141120      58800      11760       1176         56          1
9            0     362880    1451520    1693440     846720     211680      28224       2016         72          1
10           0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11           0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12           0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1

C#

Translation of: D

<lang csharp>using System; using System.Linq; using System.Numerics;

namespace LahNumbers {

   class Program {
       static BigInteger Factorial(BigInteger n) {
           if (n == 0) return 1;
           BigInteger res = 1;
           while (n > 0) {
               res *= n--;
           }
           return res;
       }
       static BigInteger Lah(BigInteger n, BigInteger k) {
           if (k == 1) return Factorial(n);
           if (k == n) return 1;
           if (k > n) return 0;
           if (k < 1 || n < 1) return 0;
           return (Factorial(n) * Factorial(n - 1)) / (Factorial(k) * Factorial(k - 1)) / Factorial(n - k);
       }
       static void Main() {
           Console.WriteLine("Unsigned Lah numbers: L(n, k):");
           Console.Write("n/k ");
           foreach (var i in Enumerable.Range(0, 13)) {
               Console.Write("{0,10} ", i);
           }
           Console.WriteLine();
           foreach (var row in Enumerable.Range(0, 13)) {
               Console.Write("{0,-3}", row);
               foreach (var i in Enumerable.Range(0, row + 1)) {
                   var l = Lah(row, i);
                   Console.Write("{0,11}", l);
               }
               Console.WriteLine();
           }
           Console.WriteLine("\nMaximum value from the L(100, *) row:");
           var maxVal = Enumerable.Range(0, 100).Select(a => Lah(100, a)).Max();
           Console.WriteLine(maxVal);
       }
   }

}</lang>

Output:
0            1
1            0          1
2            0          2          1
3            0          6          6          1
4            0         24         36         12          1
5            0        120        240        120         20          1
6            0        720       1800       1200        300         30          1
7            0       5040      15120      12600       4200        630         42          1
8            0      40320     141120     141120      58800      11760       1176         56          1
9            0     362880    1451520    1693440     846720     211680      28224       2016         72          1
10           0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11           0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12           0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1

Maximum value from the L(100, *) row:
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

C++

Library: GMP

<lang cpp>// Reference: https://en.wikipedia.org/wiki/Lah_number#Identities_and_relations

  1. include <algorithm>
  2. include <iomanip>
  3. include <iostream>
  4. include <map>
  5. include <gmpxx.h>

using integer = mpz_class;

class unsigned_lah_numbers { public:

   integer get(int n, int k);

private:

   std::map<std::pair<int, int>, integer> cache_;

};

integer unsigned_lah_numbers::get(int n, int k) {

   if (k == n)
       return 1;
   if (k == 0 || k > n)
       return 0;
   auto p = std::make_pair(n, k);
   auto i = cache_.find(p);
   if (i != cache_.end())
       return i->second;
   integer result = (n - 1 + k) * get(n - 1, k) + get(n - 1, k - 1);
   cache_.emplace(p, result);
   return result;

}

void print_lah_numbers(unsigned_lah_numbers& uln, int n) {

   std::cout << "Unsigned Lah numbers up to L(12,12):\nn/k";
   for (int j = 1; j <= n; ++j)
       std::cout << std::setw(11) << j;
   std::cout << '\n';
   for (int i = 1; i <= n; ++i) {
       std::cout << std::setw(2) << i << ' ';
       for (int j = 1; j <= i; ++j)
           std::cout << std::setw(11) << uln.get(i, j);
       std::cout << '\n';
   }

}

int main() {

   unsigned_lah_numbers uln;
   print_lah_numbers(uln, 12);
   std::cout << "Maximum value of L(n,k) where n == 100:\n";
   integer max = 0;
   for (int k = 0; k <= 100; ++k)
       max = std::max(max, uln.get(100, k));
   std::cout << max << '\n';
   return 0;

}</lang>

Output:
Unsigned Lah numbers up to L(12,12):
n/k          1          2          3          4          5          6          7          8          9         10         11         12
 1           1
 2           2          1
 3           6          6          1
 4          24         36         12          1
 5         120        240        120         20          1
 6         720       1800       1200        300         30          1
 7        5040      15120      12600       4200        630         42          1
 8       40320     141120     141120      58800      11760       1176         56          1
 9      362880    1451520    1693440     846720     211680      28224       2016         72          1
10     3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11    39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12   479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1
Maximum value of L(n,k) where n == 100:
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

D

Translation of: Kotlin

<lang d>import std.algorithm : map; import std.bigint; import std.range; import std.stdio;

BigInt factorial(BigInt n) {

   if (n == 0) return BigInt(1);
   BigInt res = 1;
   while (n > 0) {
       res *= n--;
   }
   return res;

}

BigInt lah(BigInt n, BigInt k) {

   if (k == 1) return factorial(n);
   if (k == n) return BigInt(1);
   if (k > n) return BigInt(0);
   if (k < 1 || n < 1) return BigInt(0);
   return (factorial(n) * factorial(n - 1)) / (factorial(k) * factorial(k - 1)) / factorial(n - k);

}

auto max(R)(R r) if (isInputRange!R) {

   alias T = ElementType!R;
   T v = T.init;
   while (!r.empty) {
       if (v < r.front) {
           v = r.front;
       }
       r.popFront;
   }
   return v;

}

void main() {

   writeln("Unsigned Lah numbers: L(n, k):");
   write("n/k ");
   foreach (i; 0..13) {
       writef("%10d ", i);
   }
   writeln();
   foreach (row; 0..13) {
       writef("%-3d", row);
       foreach (i; 0..row+1) {
           auto l = lah(BigInt(row), BigInt(i));
           writef("%11d", l);
       }
       writeln();
   }
   writeln("\nMaximum value from the L(100, *) row:");
   auto lambda = (int a) => lah(BigInt(100), BigInt(a));
   writeln(iota(0, 100).map!lambda.max);

}</lang>

Output:
Unsigned Lah numbers: L(n, k):
n/k          0          1          2          3          4          5          6          7          8          9         10         11         12
0            1
1            0          1
2            0          2          1
3            0          6          6          1
4            0         24         36         12          1
5            0        120        240        120         20          1
6            0        720       1800       1200        300         30          1
7            0       5040      15120      12600       4200        630         42          1
8            0      40320     141120     141120      58800      11760       1176         56          1
9            0     362880    1451520    1693440     846720     211680      28224       2016         72          1
10           0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11           0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12           0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1

Maximum value from the L(100, *) row:
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

Factor

Works with: Factor version 0.99 development version 2019-07-10

<lang factor>USING: combinators combinators.short-circuit formatting infix io kernel locals math math.factorials math.ranges prettyprint sequences ; IN: rosetta-code.lah-numbers

! Yes, Factor can do infix arithmetic with local variables! ! This is a good use case for it.

INFIX:: (lah) ( n k -- m )

   ( factorial(n) * factorial(n-1) ) /
   ( factorial(k) * factorial(k-1) ) / factorial(n-k) ;
lah ( n k -- m )
   {
       { [ k 1 = ] [ n factorial ] }
       { [ k n = ] [ 1 ] }
       { [ k n > ] [ 0 ] }
       { [ k 1 < n 1 < or ] [ 0 ] }
       [ n k (lah) ]
   } cond ;

"Unsigned Lah numbers: n k lah:" print "n\\k" write 13 dup [ "%11d" printf ] each-integer nl

<iota> [

   dup dup "%-2d " printf [0,b] [
       lah "%11d" printf
   ] with each nl

] each nl

"Maximum value from the 100 _ lah row:" print 100 [0,b] [ 100 swap lah ] map supremum .</lang>

Output:
Unsigned Lah numbers: n k lah:
n\k          0          1          2          3          4          5          6          7          8          9         10         11         12
0            1
1            0          1
2            0          2          1
3            0          6          6          1
4            0         24         36         12          1
5            0        120        240        120         20          1
6            0        720       1800       1200        300         30          1
7            0       5040      15120      12600       4200        630         42          1
8            0      40320     141120     141120      58800      11760       1176         56          1
9            0     362880    1451520    1693440     846720     211680      28224       2016         72          1
10           0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11           0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12           0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1

Maximum value from the 100 _ lah row:
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

FreeBASIC

<lang FreeBASIC>function factorial( n as uinteger ) as ulongint

   if n = 0 then return 1
   return n*factorial(n-1)

end function

function s_Lah( n as uinteger, k as uinteger ) as ulongint

   if n = k then return 1
   if n = 0 orelse k = 0 then return 0
   if k = 1 then return factorial(n)
   return ((-1)^n)*(factorial(n)*factorial(n - 1))/(factorial(k)*factorial(k - 1))/factorial(n - k)

end function

function u_Lah( n as uinteger, k as uinteger ) as ulongint

   return abs(s_Lah(n,k))

end function

function padto( i as ubyte, j as integer ) as string

   return wspace(i-len(str(j)))+str(j)

end function

print "Unsiged Lah numbers" print dim as string outstr = " k" for k as integer =0 to 12

   outstr += padto(12, k)

next k print outstr print " n" for n as integer = 0 to 12

   outstr = padto(2, n)+"  "
   for k as integer  = 0 to n
       outstr += padto(12, u_Lah(n, k))
   next k
   print outstr

next n</lang>

Output:
Unsiged Lah numbers

   k           0           1           2           3           4           5           6           7           8           9          10          11          12
 n
 0             1
 1             0           1
 2             0           2           1
 3             0           6           6           1
 4             0          24          36          12           1
 5             0         120         240         120          20           1
 6             0         720        1800        1200         300          30           1
 7             0        5040       15120       12600        4200         630          42           1
 8             0       40320      141120      141120       58800       11760        1176          56           1
 9             0      362880     1451520     1693440      846720      211680       28224        2016          72           1
10             0     3628800    16329600    21772800    12700800     3810240      635040       60480        3240          90           1
11             0    39916800   199584000   299376000   199584000    69854400    13970880     1663200      118800        4950         110           1
12             0   479001600  2634508800  4390848000  3293136000  1317254400   307359360    43908480     3920400      217800        7260         132           1

Fōrmulæ

Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.

Programs in Fōrmulæ are created/edited online in its website, However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.

In this page you can see the program(s) related to this task and their results.

Go

<lang go>package main

import (

   "fmt"
   "math/big"

)

func main() {

   limit := 100
   last := 12
   unsigned := true
   l := make([][]*big.Int, limit+1)
   for n := 0; n <= limit; n++ {
       l[n] = make([]*big.Int, limit+1)
       for k := 0; k <= limit; k++ {
           l[n][k] = new(big.Int)
       }
       l[n][n].SetInt64(int64(1))
       if n != 1 {
           l[n][1].MulRange(int64(2), int64(n))
       }
   }
   var t big.Int
   for n := 1; n <= limit; n++ {
       for k := 1; k <= n; k++ {
           t.Mul(l[n][1], l[n-1][1])
           t.Quo(&t, l[k][1])
           t.Quo(&t, l[k-1][1])
           t.Quo(&t, l[n-k][1])
           l[n][k].Set(&t)
           if !unsigned && (n%2 == 1) {
               l[n][k].Neg(l[n][k])
           }
       }
   }
   fmt.Println("Unsigned Lah numbers: l(n, k):")
   fmt.Printf("n/k")
   for i := 0; i <= last; i++ {
       fmt.Printf("%10d ", i)
   }
   fmt.Printf("\n--")
   for i := 0; i <= last; i++ {
       fmt.Printf("-----------")
   }
   fmt.Println()
   for n := 0; n <= last; n++ {
       fmt.Printf("%2d ", n)
       for k := 0; k <= n; k++ {
           fmt.Printf("%10d ", l[n][k])
       }
       fmt.Println()
   }
   fmt.Println("\nMaximum value from the l(100, *) row:")
   max := new(big.Int).Set(l[limit][0])
   for k := 1; k <= limit; k++ {
       if l[limit][k].Cmp(max) > 0 {
           max.Set(l[limit][k])
       }
   }
   fmt.Println(max)
   fmt.Printf("which has %d digits.\n", len(max.String()))

}</lang>

Output:
Unsigned Lah numbers: l(n, k):
n/k         0          1          2          3          4          5          6          7          8          9         10         11         12 
-------------------------------------------------------------------------------------------------------------------------------------------------
 0          1 
 1          0          1 
 2          0          2          1 
 3          0          6          6          1 
 4          0         24         36         12          1 
 5          0        120        240        120         20          1 
 6          0        720       1800       1200        300         30          1 
 7          0       5040      15120      12600       4200        630         42          1 
 8          0      40320     141120     141120      58800      11760       1176         56          1 
 9          0     362880    1451520    1693440     846720     211680      28224       2016         72          1 
10          0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1 
11          0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1 
12          0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1 

Maximum value from the l(100, *) row:
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000
which has 164 digits.

Haskell

Translation of: Python

<lang haskell>import Text.Printf (printf) import Control.Monad (when)

factorial :: Integral n => n -> n factorial 0 = 1 factorial n = product [1..n]

lah :: Integral n => n -> n -> n lah n k

 | k == 1 = factorial n
 | k == n = 1
 | k > n  = 0
 | k < 1 || n < 1 = 0
 | otherwise = f n `div` f k `div` factorial (n - k)
     where
       f = (*) =<< (^ 2) . factorial . pred  

printLah :: (Word, Word) -> IO () printLah (n, k) = do

 when (k == 0) (printf "\n%3d" n)
 printf "%11d" (lah n k)

main :: IO () main = do

 printf "Unsigned Lah numbers: L(n, k):\nn/k"
 mapM_ (printf "%11d") zeroToTwelve
 mapM_ printLah $ (,) <$> zeroToTwelve <*> zeroToTwelve
 printf "\nMaximum value from the L(100, *) row:\n%d\n"
   (maximum $ lah 100 <$> ([0..100] :: [Integer]))
 where zeroToTwelve = [0..12]</lang>
Output:
Unsigned Lah numbers: L(n, k):
n/k          0          1          2          3          4          5          6          7          8          9         10         11         12
  0          1          1          0          0          0          0          0          0          0          0          0          0          0
  1          0          1          0          0          0          0          0          0          0          0          0          0          0
  2          0          2          1          0          0          0          0          0          0          0          0          0          0
  3          0          6          6          1          0          0          0          0          0          0          0          0          0
  4          0         24         36         12          1          0          0          0          0          0          0          0          0
  5          0        120        240        120         20          1          0          0          0          0          0          0          0
  6          0        720       1800       1200        300         30          1          0          0          0          0          0          0
  7          0       5040      15120      12600       4200        630         42          1          0          0          0          0          0
  8          0      40320     141120     141120      58800      11760       1176         56          1          0          0          0          0
  9          0     362880    1451520    1693440     846720     211680      28224       2016         72          1          0          0          0
 10          0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1          0          0
 11          0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1          0
 12          0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1

Maximum value from the L(100, *) row:
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

J

<lang J> NB. use: k lah n lah=: ! :(!&<: * %&!~)&x: NB. `%~' is shorter than `*inv'

NB. wory_lah translates lah to algebraic English. Monad =: :[: NB. permit only a y argument Dyad =: [: : NB. require x and y arguments but_1st =: & decrement =: <: Monad

NB. ! means either factorial or combinations (just as - means negate or subtract) factorial =: ! Monad combinations =: ! Dyad

into =: *inv Dyad times =: * Dyad extend_precision =: x: Monad wordy_lah =: ((combinations but_1st decrement) times (into but_1st factorial))but_1st extend_precision Dyad </lang>

   lah&>~table~>:i.12
+------+---------------------------------------------------------------------------------------------------+
|lah&>~|        1          2          3          4          5         6        7       8      9   10  11 12|
+------+---------------------------------------------------------------------------------------------------+
| 1    |        1          0          0          0          0         0        0       0      0    0   0  0|
| 2    |        2          1          0          0          0         0        0       0      0    0   0  0|
| 3    |        6          6          1          0          0         0        0       0      0    0   0  0|
| 4    |       24         36         12          1          0         0        0       0      0    0   0  0|
| 5    |      120        240        120         20          1         0        0       0      0    0   0  0|
| 6    |      720       1800       1200        300         30         1        0       0      0    0   0  0|
| 7    |     5040      15120      12600       4200        630        42        1       0      0    0   0  0|
| 8    |    40320     141120     141120      58800      11760      1176       56       1      0    0   0  0|
| 9    |   362880    1451520    1693440     846720     211680     28224     2016      72      1    0   0  0|
|10    |  3628800   16329600   21772800   12700800    3810240    635040    60480    3240     90    1   0  0|
|11    | 39916800  199584000  299376000  199584000   69854400  13970880  1663200  118800   4950  110   1  0|
|12    |479001600 2634508800 4390848000 3293136000 1317254400 307359360 43908480 3920400 217800 7260 132  1|
+------+---------------------------------------------------------------------------------------------------+

   wordy_lah f.
[: :(([: :!&(<: :[:) [: :* [: :(*^:_1)&(! :[:))&(x: :[:))

   lah   NB. 1 or 2 arguments are clear from the context
! :(!&<: * %&!~)&x:

   (lah/ -: wordy_lah/)~>:i.12   NB. the lah and wordy_lah tables agree
1

   NB. maximum Lah value with n = 100
   >./(lah~ >:@:i.)100
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

Java

<lang java> import java.math.BigInteger; import java.util.HashMap; import java.util.Map;

public class LahNumbers {

   public static void main(String[] args) {
       System.out.println("Show the unsigned Lah numbers up to n = 12:");
       for ( int n = 0 ; n <= 12 ; n++ ) {
           System.out.printf("%5s", n);
           for ( int k = 0 ; k <= n ; k++ ) {
               System.out.printf("%12s", lahNumber(n, k));
           }
           System.out.printf("%n");
       }
       
       System.out.println("Show the maximum value of L(100, k):");
       int n = 100;
       BigInteger max = BigInteger.ZERO;
       for ( int k = 0 ; k <= n ; k++ ) {
           max = max.max(lahNumber(n, k));
       }
       System.out.printf("%s", max);
   }
   
   private static Map<String,BigInteger> CACHE = new HashMap<>();
   
   private static BigInteger lahNumber(int n, int k) {
       String key = n + "," + k;
       if ( CACHE.containsKey(key) ) {
           return CACHE.get(key);
       }
       
       //  L(n,0) = 0;
       BigInteger result;
       if ( n == 0 && k == 0 ) {
           result = BigInteger.ONE;
       }
       else if ( k == 0 ) {
           result = BigInteger.ZERO;
       }
       else if ( k > n ) {
           result = BigInteger.ZERO;
       }
       else if ( n == 1 && k == 1 ) {
           result = BigInteger.ONE;
       }
       else {
           result = BigInteger.valueOf(n-1+k).multiply(lahNumber(n-1,k)).add(lahNumber(n-1,k-1));
       }
       
       CACHE.put(key, result);
       
       return result;
   }

} </lang>

Output:
Show the unsigned Lah numbers up to n = 12:
    0           1
    1           0           1
    2           0           2           1
    3           0           6           6           1
    4           0          24          36          12           1
    5           0         120         240         120          20           1
    6           0         720        1800        1200         300          30           1
    7           0        5040       15120       12600        4200         630          42           1
    8           0       40320      141120      141120       58800       11760        1176          56           1
    9           0      362880     1451520     1693440      846720      211680       28224        2016          72           1
   10           0     3628800    16329600    21772800    12700800     3810240      635040       60480        3240          90           1
   11           0    39916800   199584000   299376000   199584000    69854400    13970880     1663200      118800        4950         110           1
   12           0   479001600  2634508800  4390848000  3293136000  1317254400   307359360    43908480     3920400      217800        7260         132           1

Show the maximum value of L(100, k):
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

jq

The table can be produced by either jq or gojq (the Go implementation of jq), but gojq is required to produce the precise maximum value.

<lang jq>## Generic functions

def factorial: reduce range(2;.+1) as $i (1; . * $i);

  1. nCk assuming n >= k

def binomial($n; $k):

 if $k > $n / 2 then binomial($n; $n-$k)
 else (reduce range($k+1; $n+1) as $i (1; . * $i)) as $numerator
 | reduce range(1;1+$n-$k) as $i ($numerator; . / $i)
 end;

def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;

def max(s): reduce s as $x (-infinite; if $x > . then $x else . end);

def lah($n; $k; $signed):

   if $n == $k then 1
   elif $n == 0 or $k == 0 or $k > $n then 0
   elif $k == 1 then $n|factorial
   else
      (binomial($n; $k) * binomial($n - 1; $k - 1) * (($n - $k)|factorial)) as $unsignedvalue
       | if $signed and ($n % 1 == 1)
         then -$unsignedvalue
         else $unsignedvalue
         end
   end;

def lah($n; $k): lah($n;$k;false); </lang> The task <lang jq>def printlahtable($kmax):

 def pad: lpad(12);
 reduce range(0;$kmax+1) as $k ("n/k"|lpad(4); . + ($k|pad)),
 (range(0; $kmax+1) as $n
  | reduce range(0;$n+1) as $k ($n|lpad(4);
      . + (lah($n; $k) | pad)) ) ;

def task:

"Unsigned Lah numbers up to n==12",
printlahtable(12), "",
"The maxiumum of lah(100, _) is: \(max( lah(100; range(0;101)) ))"
;

task </lang>

Output:
Unsigned Lah numbers up to n==12
 n/k           0           1           2           3           4           5           6           7           8           9          10          11          12
   0           1
   1           0           1
   2           0           2           1
   3           0           6           6           1
   4           0          24          36          12           1
   5           0         120         240         120          20           1
   6           0         720        1800        1200         300          30           1
   7           0        5040       15120       12600        4200         630          42           1
   8           0       40320      141120      141120       58800       11760        1176          56           1
   9           0      362880     1451520     1693440      846720      211680       28224        2016          72           1
  10           0     3628800    16329600    21772800    12700800     3810240      635040       60480        3240          90           1
  11           0    39916800   199584000   299376000   199584000    69854400    13970880     1663200      118800        4950         110           1
  12           0   479001600  2634508800  4390848000  3293136000  1317254400   307359360    43908480     3920400      217800        7260         132           1

The maxiumum of lah(100, _) is: 44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

Julia

<lang julia>using Combinatorics

function lah(n::Integer, k::Integer, signed=false)

   if n == 0 || k == 0 || k > n
       return zero(n)
   elseif n == k
       return one(n)
   elseif k == 1
       return factorial(n)
   else
       unsignedvalue = binomial(n, k) * binomial(n - 1, k - 1) * factorial(n - k)
       if signed && isodd(n)
           return -unsignedvalue
       else
           return unsignedvalue
       end
   end

end

function printlahtable(kmax)

   println("  ", mapreduce(i -> lpad(i, 12), *, 0:kmax))
   sstring(n, k) = begin i = lah(n, k); lpad(k > n && i == 0 ? "" : i, 12) end
   for n in 0:kmax
       println(rpad(n, 2) * mapreduce(k -> sstring(n, k), *, 0:kmax))
   end

end

printlahtable(12)

println("\nThe maxiumum of lah(100, _) is: ", maximum(k -> lah(BigInt(100), BigInt(k)), 1:100))

</lang>

Output:
             0           1           2           3           4           5           6           7           8           9          10          11          12
0            0
1            0           1
2            0           2           1
3            0           6           6           1
4            0          24          36          12           1
5            0         120         240         120          20           1
6            0         720        1800        1200         300          30           1
7            0        5040       15120       12600        4200         630          42           1
8            0       40320      141120      141120       58800       11760        1176          56           1
9            0      362880     1451520     1693440      846720      211680       28224        2016          72           1
10           0     3628800    16329600    21772800    12700800     3810240      635040       60480        3240          90           1
11           0    39916800   199584000   299376000   199584000    69854400    13970880     1663200      118800        4950         110           1
12           0   479001600  2634508800  4390848000  3293136000  1317254400   307359360    43908480     3920400      217800        7260         132           1

The maxiumum of lah(100, _) is: 44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

Kotlin

Translation of: Perl

<lang scala>import java.math.BigInteger

fun factorial(n: BigInteger): BigInteger {

   if (n == BigInteger.ZERO) return BigInteger.ONE
   if (n == BigInteger.ONE) return BigInteger.ONE
   var prod = BigInteger.ONE
   var num = n
   while (num > BigInteger.ONE) {
       prod *= num
       num--
   }
   return prod

}

fun lah(n: BigInteger, k: BigInteger): BigInteger {

   if (k == BigInteger.ONE) return factorial(n)
   if (k == n) return BigInteger.ONE
   if (k > n) return BigInteger.ZERO
   if (k < BigInteger.ONE || n < BigInteger.ONE) return BigInteger.ZERO
   return (factorial(n) * factorial(n - BigInteger.ONE)) / (factorial(k) * factorial(k - BigInteger.ONE)) / factorial(n - k)

}

fun main() {

   println("Unsigned Lah numbers: L(n, k):")
   print("n/k ")
   for (i in 0..12) {
       print("%10d ".format(i))
   }
   println()
   for (row in 0..12) {
       print("%-3d".format(row))
       for (i in 0..row) {
           val l = lah(BigInteger.valueOf(row.toLong()), BigInteger.valueOf(i.toLong()))
           print("%11d".format(l))
       }
       println()
   }
   println("\nMaximum value from the L(100, *) row:")
   println((0..100).map { lah(BigInteger.valueOf(100.toLong()), BigInteger.valueOf(it.toLong())) }.max())

}</lang>

Output:
Unsigned Lah numbers: L(n, k):
n/k          0          1          2          3          4          5          6          7          8          9         10         11         12 
0            1
1            0          1
2            0          2          1
3            0          6          6          1
4            0         24         36         12          1
5            0        120        240        120         20          1
6            0        720       1800       1200        300         30          1
7            0       5040      15120      12600       4200        630         42          1
8            0      40320     141120     141120      58800      11760       1176         56          1
9            0     362880    1451520    1693440     846720     211680      28224       2016         72          1
10           0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11           0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12           0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1

Maximum value from the L(100, *) row:
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

Mathematica / Wolfram Language

<lang Mathematica>ClearAll[Lah] Lah[n_?Positive, 0] := 0 Lah[0, k_?Positive] := 0 Lah[n_, n_] := 1 Lah[n_, 1] := n! Lah[n_, k_] := (-1)^n (n! ((n - 1)!))/((k! ((k - 1)!)) ((n - k)!)) Table[Lah[i, j], {i, 0, 12}, {j, 0, 12}] // Grid Max[Lah[100, Range[0, 100]]]</lang>

Output:
1	0	0	0	0	0	0	0	0	0	0	0	0
0	1	0	0	0	0	0	0	0	0	0	0	0
0	2	1	0	0	0	0	0	0	0	0	0	0
0	6	-6	1	0	0	0	0	0	0	0	0	0
0	24	36	12	1	0	0	0	0	0	0	0	0
0	120	-240	-120	-20	1	0	0	0	0	0	0	0
0	720	1800	1200	300	30	1	0	0	0	0	0	0
0	5040	-15120	-12600	-4200	-630	-42	1	0	0	0	0	0
0	40320	141120	141120	58800	11760	1176	56	1	0	0	0	0
0	362880	-1451520	-1693440	-846720	-211680	-28224	-2016	-72	1	0	0	0
0	3628800	16329600	21772800	12700800	3810240	635040	60480	3240	90	1	0	0
0	39916800	-199584000	-299376000	-199584000	-69854400	-13970880	-1663200	-118800	-4950	-110	1	0
0	479001600	2634508800	4390848000	3293136000	1317254400	307359360	43908480	3920400	217800	7260	132	1

44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000


Nim

Translation of: Julia
Library: bignum

<lang Nim>import math, strutils import bignum

func lah[T: int | Int](n, k: T; signed = false): T =

 if n == 0 or k == 0 or k > n: return when T is int: 0 else: newInt(0)
 if n == k: return when T is int: 1 else: newInt(1)
 if k == 1: return fac(n)
 result = binom(n, k) * binom(n - 1, k - 1) * fac(n - k)
 if signed and (n and 1) != 0: result = -result

proc printLahTable(kmax: int) =

 stdout.write "  "
 for k in 0..kmax:
   stdout.write ($k).align(12)
 stdout.write('\n')
 for n in 0..kmax:
   stdout.write ($n).align(2)
   for k in 0..n:
     stdout.write ($lah(n, k)).align(12)
   stdout.write('\n')

printLahTable(12)

var maxval = newInt(0) let n = newInt(100) for k in newInt(0)..newInt(100):

 let val = lah(n, k)
 if val > maxval: maxval = val

echo "\nThe maximum value of lah(100, k) is ", maxval</lang>

Output:
             0           1           2           3           4           5           6           7           8           9          10          11          12
 0           0
 1           0           1
 2           0           2           1
 3           0           6           6           1
 4           0          24          36          12           1
 5           0         120         240         120          20           1
 6           0         720        1800        1200         300          30           1
 7           0        5040       15120       12600        4200         630          42           1
 8           0       40320      141120      141120       58800       11760        1176          56           1
 9           0      362880     1451520     1693440      846720      211680       28224        2016          72           1
10           0     3628800    16329600    21772800    12700800     3810240      635040       60480        3240          90           1
11           0    39916800   199584000   299376000   199584000    69854400    13970880     1663200      118800        4950         110           1
12           0   479001600  2634508800  4390848000  3293136000  1317254400   307359360    43908480     3920400      217800        7260         132           1

The maximum value of lah(100, k) is 44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

Perl

Library: ntheory
Translation of: Raku

<lang perl>use strict; use warnings; use feature 'say'; use ntheory qw(factorial); use List::Util qw(max);

sub Lah {

   my($n, $k) = @_;
   return factorial($n) if $k == 1;
   return 1 if $k == $n;
   return 0 if $k > $n;
   return 0 if $k < 1 or $n < 1;
   (factorial($n) * factorial($n - 1)) / (factorial($k) * factorial($k - 1)) / factorial($n - $k)

}

my $upto = 12; my $mx = 1 + length max map { Lah(12,$_) } 0..$upto;

say 'Unsigned Lah numbers: L(n, k):'; print 'n\k' . sprintf "%${mx}s"x(1+$upto)."\n", 0..1+$upto;

for my $row (0..$upto) {

   printf '%-3d', $row;
   map { printf "%${mx}d", Lah($row, $_) } 0..$row;
   print "\n";

}

say "\nMaximum value from the L(100, *) row:"; say max map { Lah(100,$_) } 0..100;</lang>

Output:
Unsigned Lah numbers:  L(n, k):
n\k          0          1          2          3          4          5          6          7          8          9         10         11
0            1
1            0          1
2            0          2          1
3            0          6          6          1
4            0         24         36         12          1
5            0        120        240        120         20          1
6            0        720       1800       1200        300         30          1
7            0       5040      15120      12600       4200        630         42          1
8            0      40320     141120     141120      58800      11760       1176         56          1
9            0     362880    1451520    1693440     846720     211680      28224       2016         72          1
10           0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11           0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12           0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132

Maximum value from the L(100, *) row:
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

Phix

Library: Phix/mpfr
Translation of: Go
with javascript_semantics 
include mpfr.e
 
constant lim = 100,
         lim1 = lim+1,
         last = 12
sequence l = repeat(0,lim1)
for n=1 to lim1 do
    l[n] = mpz_inits(lim1)
    mpz_set_si(l[n][n],1)
    if n!=2 then
        mpz_fac_ui(l[n][2],n-1)
    end if
end for
mpz {t, m100} = mpz_inits(2)
for n=1 to lim do
    for k=1 to n do
        mpz_mul(t,l[n+1][2],l[n][2])
        mpz_fdiv_q(t, t, l[k+1][2])
        mpz_fdiv_q(t, t, l[k][2])
        mpz_fdiv_q(l[n+1][k+1], t, l[n-k+1][2])
    end for
end for
printf(1,"Unsigned Lah numbers: l(n, k):\n n   k:")
for i=0 to last do
    printf(1,"%6d     ", i)
end for
printf(1,"\n---    %s\n",repeat('-',last*11+6))
for n=0 to last do
    printf(1,"%2d ", n)
    for k=1 to n+1 do
        printf(1,"%10s ",{mpz_get_str(l[n+1][k])})
    end for
    printf(1,"\n")
end for
for k=1 to lim1 do
    mpz l100k = l[lim1][k] 
    if mpz_cmp(l100k,m100) > 0 then
        mpz_set(m100,l100k)
    end if
end for
printf(1,"\nThe maximum l(100,k): %s\n",shorten(mpz_get_str(m100)))
Output:
Unsigned Lah numbers: l(n, k):
 n   k:     0          1          2          3          4          5          6          7          8          9         10         11         12
---    ------------------------------------------------------------------------------------------------------------------------------------------
 0          1
 1          0          1
 2          0          2          1
 3          0          6          6          1
 4          0         24         36         12          1
 5          0        120        240        120         20          1
 6          0        720       1800       1200        300         30          1
 7          0       5040      15120      12600       4200        630         42          1
 8          0      40320     141120     141120      58800      11760       1176         56          1
 9          0     362880    1451520    1693440     846720     211680      28224       2016         72          1
10          0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11          0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12          0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1

The maximum l(100,k): 4451900544899314481...0000000000000000000 (164 digits)

PicoLisp

<lang PicoLisp>(de fact (N)

  (if (=0 N)
     1
     (* N (fact (dec N))) ) )

(de lah (N K)

  (cond
     ((=1 K) (fact N))
     ((= N K) 1)
     ((> K N) 0)
     ((or (> 1 N) (> 1 K)) 0)
     (T
        (/
           (* (fact N) (fact (dec N)))
           (* (fact K) (fact (dec K)))
           (fact (- N K)) ) ) ) )

(prin (align -12 "n/k")) (apply tab (range 0 12) (need 13 -11)) (for A (range 0 12)

  (prin (align -2 A))
  (for B (range 0 A)
     (prin (align 11 (lah A B))) )
  (prinl) )

(prinl "Maximum value from the L(100, *) row:") (maxi '((N) (lah 100 N)) (range 0 100)) (prinl @@)</lang>

Output:
n/k         0          1          2          3          4          5          6          7          8          9          10         11         12
0           1
1           0          1
2           0          2          1
3           0          6          6          1
4           0         24         36         12          1
5           0        120        240        120         20          1
6           0        720       1800       1200        300         30          1
7           0       5040      15120      12600       4200        630         42          1
8           0      40320     141120     141120      58800      11760       1176         56          1
9           0     362880    1451520    1693440     846720     211680      28224       2016         72          1
10          0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11          0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12          0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1
Maximum value from the L(100, *) row:
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

Prolog

Works with: SWI Prolog

<lang prolog>% Reference: https://en.wikipedia.org/wiki/Lah_number#Identities_and_relations

- dynamic unsigned_lah_number_cache/3.

unsigned_lah_number(N, N, 1):-!. unsigned_lah_number(_, 0, 0):-!. unsigned_lah_number(N, K, 0):- K > N, !. unsigned_lah_number(N, K, L):- unsigned_lah_number_cache(N, K, L), !. unsigned_lah_number(N, K, L):- N1 is N - 1, K1 is K - 1, unsigned_lah_number(N1, K, L1), unsigned_lah_number(N1, K1, L2), !, L is (N1 + K) * L1 + L2, assertz(unsigned_lah_number_cache(N, K, L)).

print_unsigned_lah_numbers(N):- between(1, N, K), unsigned_lah_number(N, K, L), writef('%11r', [L]), fail. print_unsigned_lah_numbers(_):- nl.

print_unsigned_lah_numbers:- between(1, 12, N), print_unsigned_lah_numbers(N), fail. print_unsigned_lah_numbers.

max_unsigned_lah_number(N, Max):-

   aggregate_all(max(L), (between(1, N, K), unsigned_lah_number(N, K, L)), Max).

main:- writeln('Unsigned Lah numbers up to L(12,12):'), print_unsigned_lah_numbers, writeln('Maximum value of L(n,k) where n = 100:'), max_unsigned_lah_number(100, M), writeln(M).</lang>

Output:
Unsigned Lah numbers up to L(12,12):
          1
          2          1
          6          6          1
         24         36         12          1
        120        240        120         20          1
        720       1800       1200        300         30          1
       5040      15120      12600       4200        630         42          1
      40320     141120     141120      58800      11760       1176         56          1
     362880    1451520    1693440     846720     211680      28224       2016         72          1
    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1
Maximum value of L(n,k) where n = 100:
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

Python

<lang python>def factorial(n):

   if n == 0:
       return 1
   res = 1
   while n > 0:
       res *= n
       n -= 1
   return res

def lah(n,k):

   if k == 1:
       return factorial(n)
   if k == n:
       return 1
   if k > n:
       return 0
   if k < 1 or n < 1:
       return 0
   return (factorial(n) * factorial(n - 1)) / (factorial(k) * factorial(k - 1)) / factorial(n - k)

def main():

   print "Unsigned Lah numbers: L(n, k):"
   print "n/k ",
   for i in xrange(13):
       print "%11d" % i,
   print
   for row in xrange(13):
       print "%-4d" % row,
       for i in xrange(row + 1):
           l = lah(row, i)
           print "%11d" % l,
       print
   print "\nMaximum value from the L(100, *) row:"
   maxVal = max([lah(100, a) for a in xrange(100)])
   print maxVal

main()</lang>

Output:
Unsigned Lah numbers: L(n, k):
n/k            0           1           2           3           4           5           6           7           8           9          10          11          12
0              1
1              0           1
2              0           2           1
3              0           6           6           1
4              0          24          36          12           1
5              0         120         240         120          20           1
6              0         720        1800        1200         300          30           1
7              0        5040       15120       12600        4200         630          42           1
8              0       40320      141120      141120       58800       11760        1176          56           1
9              0      362880     1451520     1693440      846720      211680       28224        2016          72           1
10             0     3628800    16329600    21772800    12700800     3810240      635040       60480        3240          90           1
11             0    39916800   199584000   299376000   199584000    69854400    13970880     1663200      118800        4950         110           1
12             0   479001600  2634508800  4390848000  3293136000  1317254400   307359360    43908480     3920400      217800        7260         132           1

Maximum value from the L(100, *) row:
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

Quackery

<lang Quackery> [ table ] is ! ( n --> n )

 1
 101 times 
   [ dup ' ! put
     i^ 1+ * ]
 drop 
 [ 2dup = iff [ 2drop 1 ] done
   2dup * 0 = iff * done
   dup 1 = iff [ drop ! ] done
   2dup - ! unrot
   dup ! 
   swap 1 - ! *
   swap dup !
   swap 1 - ! *
   swap / 
   swap / ]                    is lah      (   n --> n )
 [ dip number$ 
   over size - 
   space swap of
   swap join echo$ ]           is justify  ( n n -->   )
 [ table ]                     is colwidth (   n --> n )
 13 times
  [ 12 i^ lah number$ 
    size 2 + ' colwidth put ]
 say "  k| " 
 13 times 
   [ i^ dup colwidth justify ] cr
 say " n |" 
 char - 115 of echo$ cr
 13 times 
   [ i^ dup 
     dup 2 justify say " | "
     1+ times 
       [ dup i^ lah
         i^ colwidth justify ] 
     drop cr ] 
 cr
 0 
 101 times 
   [ 100 i^ lah 
     2dup < iff nip else drop ]
 echo</lang>
Output:
  k|   0          1           2           3           4           5          6         7        8       9    10   11 12
 n |-------------------------------------------------------------------------------------------------------------------
 0 |   1
 1 |   0          1
 2 |   0          2           1
 3 |   0          6           6           1
 4 |   0         24          36          12           1
 5 |   0        120         240         120          20           1
 6 |   0        720        1800        1200         300          30          1
 7 |   0       5040       15120       12600        4200         630         42         1
 8 |   0      40320      141120      141120       58800       11760       1176        56        1
 9 |   0     362880     1451520     1693440      846720      211680      28224      2016       72       1
10 |   0    3628800    16329600    21772800    12700800     3810240     635040     60480     3240      90     1
11 |   0   39916800   199584000   299376000   199584000    69854400   13970880   1663200   118800    4950   110    1
12 |   0  479001600  2634508800  4390848000  3293136000  1317254400  307359360  43908480  3920400  217800  7260  132  1

44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000


R

 <lang R>Lah_numbers <- function(n, k, type = "unsigned") {
   
   if (n == k)
     return(1)
   
   if (n == 0 | k == 0)
     return(0)
   
   if (k == 1)
     return(factorial(n))
   
   if (k > n)
     return(NA)
   
   if (type == "unsigned")
     return((factorial(n) * factorial(n - 1)) / (factorial(k) * factorial(k - 1)) / factorial(n - k))
   
   if (type == "signed")
     return(-1 ** n * (factorial(n) * factorial(n - 1)) / (factorial(k) * factorial(k - 1)) / factorial(n - k))
 }
  1. demo

Table <- matrix(0 , 13, 13, dimnames = list(0:12, 0:12))

for (n in 0:12) {

 for (k in 0:12) {
   Table[n + 1, k + 1] <- Lah_numbers(n, k, type = "unsigned")
 }

}

Table

 </lang>
   
Output:
     0         1          2          3          4          5         6        7       8      9   10  11 12
  0  1         0          0          0          0          0         0        0       0      0    0   0  0
  1  0         1         NA         NA         NA         NA        NA       NA      NA     NA   NA  NA NA
  2  0         2          1         NA         NA         NA        NA       NA      NA     NA   NA  NA NA
  3  0         6          6          1         NA         NA        NA       NA      NA     NA   NA  NA NA
  4  0        24         36         12          1         NA        NA       NA      NA     NA   NA  NA NA
  5  0       120        240        120         20          1        NA       NA      NA     NA   NA  NA NA
  6  0       720       1800       1200        300         30         1       NA      NA     NA   NA  NA NA
  7  0      5040      15120      12600       4200        630        42        1      NA     NA   NA  NA NA
  8  0     40320     141120     141120      58800      11760      1176       56       1     NA   NA  NA NA
  9  0    362880    1451520    1693440     846720     211680     28224     2016      72      1   NA  NA NA
  10 0   3628800   16329600   21772800   12700800    3810240    635040    60480    3240     90    1  NA NA
  11 0  39916800  199584000  299376000  199584000   69854400  13970880  1663200  118800   4950  110   1 NA
  12 0 479001600 2634508800 4390848000 3293136000 1317254400 307359360 43908480 3920400 217800 7260 132  1

Raku

(formerly Perl 6)

Works with: Rakudo version 2019.07.1

<lang perl6>constant @factorial = 1, |[\*] 1..*;

sub Lah (Int \n, Int \k) {

   return @factorial[n] if k == 1;
   return 1 if k == n;
   return 0 if k > n;
   return 0 if k < 1 or n < 1;
   (@factorial[n] * @factorial[n - 1]) / (@factorial[k] * @factorial[k - 1]) / @factorial[n - k]

}

my $upto = 12;

my $mx = (1..$upto).map( { Lah($upto, $_) } ).max.chars;

put 'Unsigned Lah numbers: L(n, k):'; put 'n\k', (0..$upto)».fmt: "%{$mx}d";

for 0..$upto -> $row {

   $row.fmt('%-3d').print;
   put (0..$row).map( { Lah($row, $_) } )».fmt: "%{$mx}d";

}

say "\nMaximum value from the L(100, *) row:"; say (^100).map( { Lah 100, $_ } ).max;</lang>

Output:
Unsigned Lah numbers:  L(n, k):
n\k         0          1          2          3          4          5          6          7          8          9         10         11         12
0           1
1           0          1
2           0          2          1
3           0          6          6          1
4           0         24         36         12          1
5           0        120        240        120         20          1
6           0        720       1800       1200        300         30          1
7           0       5040      15120      12600       4200        630         42          1
8           0      40320     141120     141120      58800      11760       1176         56          1
9           0     362880    1451520    1693440     846720     211680      28224       2016         72          1
10          0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11          0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12          0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1

Maximum value from the L(100, *) row:
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

REXX

Some extra code was added to minimize the column widths in the displaying of the numbers.

Also, code was added to use memoization of the factorial calculations. <lang rexx>/*REXX pgm computes & display (unsigned) Stirling numbers of the 3rd kind (Lah numbers).*/ parse arg lim . /*obtain optional argument from the CL.*/ if lim== | lim=="," then lim= 12 /*Not specified? Then use the default.*/ olim= lim /*save the original value of LIM. */ lim= abs(lim) /*only use the absolute value of LIM. */ numeric digits max(9, 4*lim) /*(over) specify maximum number in grid*/ max#.= 0 !.=. @.= /* [↓] calculate values for the grid. */

       do   n=0  to  lim;   nm= n - 1
         do k=0  to  lim;   km= k - 1
         if k==1               then do;  @.n.k= !(n); call maxer; iterate;  end
         if k==n               then do;  @.n.k= 1   ;             iterate;  end
         if k>n | k==0 | n==0  then do;  @.n.k= 0   ;             iterate;  end
         @.n.k = (!(n) * !(nm)) % (!(k) * !(km)) % !(n-k)  /*calculate a # in the grid.*/
         call maxer                                        /*find    max #  "  "    "  */
         end   /*k*/
       end     /*n*/
       do k=0  for lim+1                        /*find max column width for each column*/
       max#.a= max#.a + length(max#.k)
       end   /*k*/
                                                /* [↓]  only show the maximum value ?  */

w= length(max#.b) /*calculate max width of all numbers. */ if olim<0 then do; say 'The maximum value (which has ' w " decimal digits):"

                    say max#.b                  /*display maximum number in the grid.  */
                    exit                        /*stick a fork in it,  we're all done. */
               end                              /* [↑]  the 100th row is when LIM is 99*/

wi= max(3, length(lim+1) ) /*the maximum width of the grid's index*/ say 'row' center('columns', max(9, max#.a + lim), '═') /*display header of the grid.*/

       do r=0  for lim+1;   $=                  /* [↓]  display the grid to the term.  */
         do c=0  for lim+1  until c>=r          /*build a row of grid, 1 col at a time.*/
         $= $  right(@.r.c, length(max#.c) )    /*append a column to a row of the grid.*/
         end   /*c*/
       say right(r,wi)  strip(substr($,2), 'T') /*display a single row of the grid.    */
       end     /*r*/

exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ !: parse arg z; if !.z\==. then return !.z; !=1; do f=2 to z; !=!*f; end; !.z=!; return ! maxer: max#.k= max(max#.k, @.n.k); max#.b= max(max#.b, @.n.k); return</lang>

output   when using the default input:
row ══════════════════════════════════════════════columns═══════════════════════════════════════════════
  0 1
  1 0         1
  2 0         2          1
  3 0         6          6          1
  4 0        24         36         12          1
  5 0       120        240        120         20          1
  6 0       720       1800       1200        300         30         1
  7 0      5040      15120      12600       4200        630        42        1
  8 0     40320     141120     141120      58800      11760      1176       56       1
  9 0    362880    1451520    1693440     846720     211680     28224     2016      72      1
 10 0   3628800   16329600   21772800   12700800    3810240    635040    60480    3240     90    1
 11 0  39916800  199584000  299376000  199584000   69854400  13970880  1663200  118800   4950  110   1
 12 0 479001600 2634508800 4390848000 3293136000 1317254400 307359360 43908480 3920400 217800 7260 132 1
output   when using the input of:     -100
The maximum value  (which has  164  decimal digits):
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

Ruby

Works with Ruby 3.0 (end-less method; end-less and begin-less range). <lang ruby>def fact(n) = n.zero? ? 1 : 1.upto(n).inject(&:*)

def lah(n, k)

 case k
   when 1 then fact(n)
   when n then 1
   when (..1),(n..) then 0
   else n<1 ? 0 : (fact(n)*fact(n-1)) / (fact(k)*fact(k-1)) / fact(n-k)
 end

end

r = (0..12) puts "Unsigned Lah numbers: L(n, k):" puts "n/k #{r.map{|n| "%11d" % n}.join}"

r.each do |row|

 print "%-4s" % row
 puts "#{(0..row).map{|col| "%11d" % lah(row,col)}.join}"

end

puts "\nMaximum value from the L(100, *) row:"; puts (1..100).map{|a| lah(100,a)}.max </lang>

Output:
Unsigned Lah numbers: L(n, k):
n/k           0          1          2          3          4          5          6          7          8          9         10         11         12
0             1
1             0          1
2             0          2          1
3             0          6          6          1
4             0         24         36         12          1
5             0        120        240        120         20          1
6             0        720       1800       1200        300         30          1
7             0       5040      15120      12600       4200        630         42          1
8             0      40320     141120     141120      58800      11760       1176         56          1
9             0     362880    1451520    1693440     846720     211680      28224       2016         72          1
10            0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11            0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12            0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1

Maximum value from the L(100, *) row:
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

Scheme

Works with: Chez Scheme

<lang scheme>; Compute the Unsigned Lah number L(n, k). (define lah

 (lambda (n k)
   (/ (/ (* (fact n) (fact (1- n))) (* (fact k) (fact (1- k)))) (fact (- n k)))))
Procedure to compute factorial.

(define fact

 (lambda (n)
   (if (<= n 0)
     1
     (* n (fact (1- n))))))
Generate a table of the Unsigned Lah numbers L(n, k) up to L(12, 12).

(printf "The Unsigned Lah numbers L(n, k) up to L(12, 12):~%") (printf "n\\k~10d" 1) (do ((k 2 (1+ k)))

   ((> k 12))
 (printf " ~10d" k))

(newline) (do ((n 1 (1+ n)))

   ((> n 12))
 (printf "~2d" n)
 (do ((k 1 (1+ k)))
     ((> k n))
   (printf " ~10d" (lah n k)))
 (newline))
Find the maximum value of L(n, k) where n = 100.

(printf "~%The maximum value of L(n, k) where n = 100:~%") (let ((max 0))

 (do ((k 1 (1+ k)))
     ((> k 100))
   (let ((val (lah 100 k)))
     (when (> val max) (set! max val))))
 (printf "~d~%" max))</lang>
Output:
The Unsigned Lah numbers L(n, k) up to L(12, 12):
n\k         1          2          3          4          5          6          7          8          9         10         11         12
 1          1
 2          2          1
 3          6          6          1
 4         24         36         12          1
 5        120        240        120         20          1
 6        720       1800       1200        300         30          1
 7       5040      15120      12600       4200        630         42          1
 8      40320     141120     141120      58800      11760       1176         56          1
 9     362880    1451520    1693440     846720     211680      28224       2016         72          1
10    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1

The maximum value of L(n, k) where n = 100:
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

Sidef

<lang ruby>func lah(n, k) {

   stirling3(n, k)
   #binomial(n-1, k-1) * n!/k!     # alternative formula

}

const r = (0..12)

var triangle = r.map {|n| 0..n -> map {|k| lah(n, k) } } var widths = r.map {|n| r.map {|k| (triangle[k][n] \\ 0).len }.max }

say ('n\k ', r.map {|n| "%*s" % (widths[n], n) }.join(' '))

r.each {|n|

   var str = ('%-3s ' % n)
   str += triangle[n].map_kv {|k,v| "%*s" % (widths[k], v) }.join(' ')
   say str

}

with (100) {|n|

   say "\nMaximum value from the L(#{n}, *) row:"
   say { lah(n, _) }.map(^n).max

}</lang>

Output:
n\k 0         1          2          3          4          5         6        7       8      9   10  11 12
0   1
1   0         1
2   0         2          1
3   0         6          6          1
4   0        24         36         12          1
5   0       120        240        120         20          1
6   0       720       1800       1200        300         30         1
7   0      5040      15120      12600       4200        630        42        1
8   0     40320     141120     141120      58800      11760      1176       56       1
9   0    362880    1451520    1693440     846720     211680     28224     2016      72      1
10  0   3628800   16329600   21772800   12700800    3810240    635040    60480    3240     90    1
11  0  39916800  199584000  299376000  199584000   69854400  13970880  1663200  118800   4950  110   1
12  0 479001600 2634508800 4390848000 3293136000 1317254400 307359360 43908480 3920400 217800 7260 132 1

Maximum value from the L(100, *) row:
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

Swift

Translation of: Kotlin

<lang swift>import BigInt import Foundation

@inlinable public func factorial<T: BinaryInteger>(_ n: T) -> T {

 guard n != 0 else {
   return 1
 }
 return stride(from: n, to: 0, by: -1).reduce(1, *)

}

@inlinable public func lah<T: BinaryInteger>(n: T, k: T) -> T {

 if k == 1 {
   return factorial(n)
 } else if k == n {
   return 1
 } else if k > n {
   return 0
 } else if k < 1 || n < 1 {
   return 0
 } else {
   let a = (factorial(n) * factorial(n - 1))
   let b = (factorial(k) * factorial(k - 1))
   let c = factorial(n - k)
   return a / b / c
 }

}

print("Unsigned Lah numbers: L(n, k):") print("n\\k", terminator: "")

for i in 0...12 {

 print(String(format: "%10d", i), terminator: " ")

}

print()

for row in 0...12 {

 print(String(format: "%-2d", row), terminator: "")
 for i in 0...row {
   lah(n: BigInt(row), k: BigInt(i)).description.withCString {str in
     print(String(format: "%11s", str), terminator: "")
   }
 }
 print()

}

let maxLah = (0...100).map({ lah(n: BigInt(100), k: BigInt($0)) }).max()!

print("Maximum value from the L(100, *) row: \(maxLah)")</lang>

Output:


Unsigned Lah numbers: L(n, k):
n\k         0          1          2          3          4          5          6          7          8          9         10         11         12 
0           1
1           0          1
2           0          2          1
3           0          6          6          1
4           0         24         36         12          1
5           0        120        240        120         20          1
6           0        720       1800       1200        300         30          1
7           0       5040      15120      12600       4200        630         42          1
8           0      40320     141120     141120      58800      11760       1176         56          1
9           0     362880    1451520    1693440     846720     211680      28224       2016         72          1
10          0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11          0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12          0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1
Maximum value from the L(100, *) row: 44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

Tcl

<lang Tcl>proc prod {from to} {

   set r 1
   if {$from <= $to} {
       set r $from
       while {[incr from] <= $to} {
           set r [expr {$r * $from}]
       }
   }
   return $r

}

proc US3 {n k} {

   if {$n < 0 || $k < 0} {
       error "US3(): negative arg ($n,$k)"
   }
   ## L(0,0) = 1
   ## L(n,0) = 0       if 0 < n
   ## L(0,k) = 0       if 0 < k
   ## L(n,k) = 0       if n < k
   ## L(n,n) = 1
   if {$n == $k} {
       return 1
   }
   if {$n == 0 || $k == 0} {
       return 0
   }
   if {$n < $k} {
       return 0
   }
   set nk [list $n $k]
   if {[info exists ::US3cache($nk)]} {
       return      $::US3cache($nk)
   }
   if {$k == 1} {
       ## L(n,1) = n!
       set r [prod 2 $n]
   } else {
       ## k > 1
       ## L(n,k) = L(n,k-1) * (n - (k-1)) / ((k-1)*k)
       set k1 [expr {$k - 1}]
       set r  [expr {([US3 $n $k1] * ($n - $k1)) / ($k * $k1)}]
   }
   set ::US3cache($nk) $r

}

proc main {} {

   puts "Unsigned Lah numbers L(n,k):"
   set max  12                 ;# last n,k to print
   set L    10                 ;# space to use for 1 number
   set minn  1                 ;# first row to print
   set mink  1                 ;# first column to print
   puts -nonewline "n\\k"
   for {set n $minn} {$n <= $max} {incr n} {
       puts -nonewline " [format %${L}d $n]"
   }
   puts ""
   for {set n $minn} {$n <= $max} {incr n} {
       puts -nonewline [format %3d $n]
       for {set k $mink} {$k <= $n} {incr k} {
           puts -nonewline " [format %${L}s [US3 $n $k]]"
       }
       puts ""
   }
   set n 100
   puts "The maximum value of L($n, k) = "
   set maxv  0
   set maxk -1
   for {set k 0} {$k <= $n} {incr k} {
       set v [US3 $n $k]
       if {$v > $maxv} {
           set maxv $v
           set maxk $k
       }
   }
   puts $maxv
   puts "([string length $maxv] digits, k=$maxk)"

} main </lang>

Output:
Unsigned Lah numbers L(n,k):
n\k          1          2          3          4          5          6          7          8          9         10         11         12
  1          1
  2          2          1
  3          6          6          1
  4         24         36         12          1
  5        120        240        120         20          1
  6        720       1800       1200        300         30          1
  7       5040      15120      12600       4200        630         42          1
  8      40320     141120     141120      58800      11760       1176         56          1
  9     362880    1451520    1693440     846720     211680      28224       2016         72          1
 10    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
 11   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
 12  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1
The maximum value of L(100, k) = 
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000
(164 digits, k=10)

VBScript

Translation of: Visual Basic .NET

<lang vb>' Lah numbers - VBScript - 04/02/2021

   Function F(i,n)
       Dim c: c=CCur(i): If n>Len(c) Then F=Space(n-Len(c))&c Else F=c
   End Function 'F
   Function Fact(ByVal n)
       Dim res
       If n=0 Then
           Fact = 1
       Else
           res = 1
           While n>0
               res = res*n
               n = n-1
           Wend
           Fact = res
       End If
   End Function 'Fact

   Function Lah(n, k)
       If k=1 Then
           Lah = Fact(n)
       ElseIf k=n Then
           Lah = 1
       ElseIf k>n Then
           Lah=0
       ElseIf k < 1 Or n < 1 Then
           Lah = 0
       Else
           Lah = (Fact(n) * Fact(n-1)) / (Fact(k) * Fact(k-1)) / Fact(n-k)
       End If
   End Function 'Lah

   Sub Main()
       ns=12: p=10
       WScript.Echo "Unsigned Lah numbers: Lah(n,k):"
       buf = "n/k "
       For k=1 To ns
          buf = buf & F(k,p) & " "
       Next 'k
       WScript.Echo buf
       For n=1 To ns
          buf = F(n,3) & " "
           For k=1 To n
               l = Lah(n,k)
               buf = buf & F(l,p) & " "
           Next 'k
           WScript.Echo buf
       Next 'n
   End Sub 'Main
   Main() </lang>
Output:
Unsigned Lah numbers: Lah(n,k):
n/k          1          2          3          4          5          6          7          8          9         10         11         12
  1          1
  2          2          1
  3          6          6          1
  4         24         36         12          1
  5        120        240        120         20          1
  6        720       1800       1200        300         30          1
  7       5040      15120      12600       4200        630         42          1
  8      40320     141120     141120      58800      11760       1176         56          1
  9     362880    1451520    1693440     846720     211680      28224       2016         72          1
 10    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
 11   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
 12  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1

Visual Basic .NET

Translation of: C#

<lang vbnet>Imports System.Numerics

Module Module1

   Function Factorial(n As BigInteger) As BigInteger
       If n = 0 Then
           Return 1
       End If
       Dim res As BigInteger = 1
       While n > 0
           res *= n
           n -= 1
       End While
       Return res
   End Function
   Function Lah(n As BigInteger, k As BigInteger) As BigInteger
       If k = 1 Then
           Return Factorial(n)
       End If
       If k = n Then
           Return 1
       End If
       If k > n Then
           Return 0
       End If
       If k < 1 OrElse n < 1 Then
           Return 0
       End If
       Return (Factorial(n) * Factorial(n - 1)) / (Factorial(k) * Factorial(k - 1)) / Factorial(n - k)
   End Function
   Sub Main()
       Console.WriteLine("Unsigned Lah numbers: L(n, k):")
       Console.Write("n/k ")
       For Each i In Enumerable.Range(0, 13)
           Console.Write("{0,10} ", i)
       Next
       Console.WriteLine()
       For Each row In Enumerable.Range(0, 13)
           Console.Write("{0,-3}", row)
           For Each i In Enumerable.Range(0, row + 1)
               Dim l = Lah(row, i)
               Console.Write("{0,11}", l)
           Next
           Console.WriteLine()
       Next
       Console.WriteLine()
       Console.WriteLine("Maximum value from the L(100, *) row:")
       Dim maxVal = Enumerable.Range(0, 100).Select(Function(a) Lah(100, a)).Max
       Console.WriteLine(maxVal)
   End Sub

End Module</lang>

Output:
Unsigned Lah numbers: L(n, k):
n/k          0          1          2          3          4          5          6          7          8          9         10         11         12
0            1
1            0          1
2            0          2          1
3            0          6          6          1
4            0         24         36         12          1
5            0        120        240        120         20          1
6            0        720       1800       1200        300         30          1
7            0       5040      15120      12600       4200        630         42          1
8            0      40320     141120     141120      58800      11760       1176         56          1
9            0     362880    1451520    1693440     846720     211680      28224       2016         72          1
10           0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11           0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12           0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1

Maximum value from the L(100, *) row:
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000

Wren

Library: Wren-fmt

<lang ecmascript>import "/fmt" for Fmt

var fact = Fn.new { |n|

   if (n < 2) return 1
   var fact = 1
   for (i in 2..n) fact = fact * i
   return fact

}

var lah = Fn.new { |n, k|

   if (k == 1) return fact.call(n)
   if (k == n) return 1
   if (k > n) return 0
   if (k < 1 || n < 1) return 0
   return (fact.call(n) * fact.call(n-1)) / (fact.call(k) * fact.call(k-1)) / fact.call(n-k)

}

System.print("Unsigned Lah numbers: l(n, k):") System.write("n/k") for (i in 0..12) System.write("%(Fmt.d(10, i)) ") System.print("\n" + "-" * 145) for (n in 0..12) {

   System.write("%(Fmt.d(2, n)) ")
   for (k in 0..n) System.write("%(Fmt.d(10, lah.call(n, k))) ")
   System.print()

}</lang>

Output:
Unsigned Lah numbers: l(n, k):
n/k         0          1          2          3          4          5          6          7          8          9         10         11         12 
-------------------------------------------------------------------------------------------------------------------------------------------------
 0          1 
 1          0          1 
 2          0          2          1 
 3          0          6          6          1 
 4          0         24         36         12          1 
 5          0        120        240        120         20          1 
 6          0        720       1800       1200        300         30          1 
 7          0       5040      15120      12600       4200        630         42          1 
 8          0      40320     141120     141120      58800      11760       1176         56          1 
 9          0     362880    1451520    1693440     846720     211680      28224       2016         72          1 
10          0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1 
11          0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1 
12          0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1 

Vala

<lang Vala>uint64 factorial(uint8 n) {

 uint64 res = 1; 
 if (n == 0) return res; 
 while (n > 0) res *= n--; 
 return res; 

}

uint64 lah(uint8 n, uint8 k) {

 if (k == 1) return factorial(n); 
 if (k == n) return 1; 
 if (k > n)  return 0; 
 if (k < 1 || n < 1) return 0; 
 return (factorial(n) * factorial(n - 1)) / (factorial(k) * factorial(k - 1)) / factorial(n - k); 

}

void main() {

 uint8 row, i; 

 print("Unsigned Lah numbers: L(n, k):\n"); 
 print("n/k "); 
 for (i = 0; i < 13; i++) { 
  print("%10d ", i); 
 }
 print("\n"); 
 for (row = 0; row < 13; row++) { 
   print("%-3d", row);
   for (i = 0; i < row + 1; i++) { 
     uint64 l = lah(row, i); 
     print("%11lld", l); 
   }
   print("\n");
 }

}</lang>

Output:
Unsigned Lah numbers: L(n, k):
n/k          0          1          2          3          4          5          6          7          8          9         10         11         12
0            1
1            0          1
2            0          2          1
3            0          6          6          1
4            0         24         36         12          1
5            0        120        240        120         20          1
6            0        720       1800       1200        300         30          1
7            0       5040      15120      12600       4200        630         42          1
8            0      40320     141120     141120      58800      11760       1176         56          1
9            0     362880    1451520    1693440     846720     211680      28224       2016         72          1
10           0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
11           0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
12           0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1

zkl

<lang zkl>fcn lah(n,k,fact=fcn(n){ [1..n].reduce('*,1) }){

  if(n==k)	  return(1);
  if(k==1)	  return(fact(n));
  if(n<1 or k<1) return(0);  
  (fact(n)*fact(n - 1)) /(fact(k)*fact(k - 1)) /fact(n - k)

}</lang> <lang zkl>// calculate entire table (quick), find max, find num digits in max N,mx := 12, [1..N].apply(fcn(n){ [1..n].apply(lah.fp(n)) }).flatten() : (0).max(_); fmt:="%%%dd".fmt("%d".fmt(mx.numDigits + 1)).fmt; // "%9d".fmt println("Unsigned Lah numbers: L(n,k):"); println("n\\k",[0..N].pump(String,fmt)); foreach row in ([0..N]){

  println("%3d".fmt(row), [0..row].pump(String, lah.fp(row), fmt));

}</lang>

Output:
Unsigned Lah numbers: L(n,k):
n\k          0          1          2          3          4          5          6          7          8          9         10         11         12
  0          0
  1          0          1
  2          0          2          1
  3          0          6          6          1
  4          0         24         36         12          1
  5          0        120        240        120         20          1
  6          0        720       1800       1200        300         30          1
  7          0       5040      15120      12600       4200        630         42          1
  8          0      40320     141120     141120      58800      11760       1176         56          1
  9          0     362880    1451520    1693440     846720     211680      28224       2016         72          1
 10          0    3628800   16329600   21772800   12700800    3810240     635040      60480       3240         90          1
 11          0   39916800  199584000  299376000  199584000   69854400   13970880    1663200     118800       4950        110          1
 12          0  479001600 2634508800 4390848000 3293136000 1317254400  307359360   43908480    3920400     217800       7260        132          1
Library: GMP

GNU Multiple Precision Arithmetic Library

<lang zkl>var [const] BI=Import("zklBigNum"); // libGMP N=100; L100:=[1..N].apply(lah.fpM("101",BI(N),fcn(n){ BI(n).factorial() }))

      .reduce(fcn(m,n){ m.max(n) });

println("Maximum value from the L(%d, *) row (%d digits):".fmt(N,L100.numDigits)); println(L100);</lang>

Output:
Maximum value from the L(100, *) row (164 digits):
44519005448993144810881324947684737529186447692709328597242209638906324913313742508392928375354932241404408343800007105650554669129521241784320000000000000000000000