Update all new Tasks
This commit is contained in:
parent
00a190b0a6
commit
91df62d461
5697 changed files with 93386 additions and 804 deletions
15
Task/Combinations-and-permutations/00DESCRIPTION
Normal file
15
Task/Combinations-and-permutations/00DESCRIPTION
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{{wikipedia|Combination}} {{wikipedia|Permutation}}
|
||||
|
||||
;Task:
|
||||
Implement the [[wp:Combination|combination]] (<sup>n</sup>C<sub>k</sub>) and [[wp:Permutation|permutation]] (<sup>n</sup>P<sub>k</sub>) operators in the target language:
|
||||
* <math>^n\operatorname C_k =\binom nk = \frac{n(n-1)\ldots(n-k+1)}{k(k-1)\dots1} </math>
|
||||
* <math>^n\operatorname P_k = n\cdot(n-1)\cdot(n-2)\cdots(n-k+1)</math>
|
||||
See the wikipedia articles for a more detailed description.
|
||||
|
||||
'''To test''', generate and print examples of:
|
||||
* A sample of permutations from 1 to 12 and Combinations from 10 to 60 using exact Integer arithmetic.
|
||||
* A sample of permutations from 5 to 15000 and Combinations from 100 to 1000 using approximate Floating point arithmetic.<br> This 'floating point' code could be implemented using an approximation, e.g., by calling the [[Gamma function]].
|
||||
|
||||
'''See Also:'''
|
||||
* [[Evaluate binomial coefficients]]
|
||||
{{Template:Combinations and permutations}}
|
||||
2
Task/Combinations-and-permutations/00META.yaml
Normal file
2
Task/Combinations-and-permutations/00META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
note: Probability and statistics
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
# -*- coding: utf-8 -*- #
|
||||
|
||||
COMMENT REQUIRED by "prelude_combinations_and_permutations.a68" CO
|
||||
MODE CPINT = #LONG# ~;
|
||||
MODE CPOUT = #LONG# ~; # the answer, can be REAL #
|
||||
MODE CPREAL = ~; # the answer, can be REAL #
|
||||
PROC cp fix value error = (#REF# CPARGS args)BOOL: ~;
|
||||
#PROVIDES:#
|
||||
# OP C = (CP~,CP~)CP~: ~ #
|
||||
# OP P = (CP~,CP~)CP~: ~ #
|
||||
END COMMENT
|
||||
|
||||
MODE CPARGS = STRUCT(CHAR name, #REF# CPINT n,k);
|
||||
|
||||
PRIO C = 8, P = 8; # should be 7.5, a priority between *,/ and **,SHL,SHR etc #
|
||||
|
||||
# I suspect there is a more reliable way of doing this using the Gamma Function approx #
|
||||
|
||||
OP P = (CPINT n, r)CPOUT: (
|
||||
IF n < r ORF r < 0 THEN IF NOT cp fix value error(CPARGS("P",n,r)) THEN stop FI FI;
|
||||
CPOUT out := 1;
|
||||
# basically nPk = (n-r+1)(n-r+2)...(n-2)(n-1)n = n!/(n-r)! #
|
||||
FOR i FROM n-r+1 TO n DO out *:= i OD;
|
||||
out
|
||||
);
|
||||
|
||||
OP P = (CPREAL n, r)CPREAL: # 'ln gamma' requires GSL library #
|
||||
exp(ln gamma(n+1)-ln gamma(n-r+1));
|
||||
|
||||
# basically nPk = (n-r+1)(n-r+2)...(n-2)(n-1)n = n!/(n-r)! #
|
||||
COMMENT # alternate slower version #
|
||||
OP P = (CPREAL n, r)CPREAL: ( # alternate slower version #
|
||||
IF n < r ORF r < 0 THEN IF NOT cp fix value error(CPARGS("P",ENTIER n,ENTIER r)) THEN stop FI FI;
|
||||
CPREAL out := 1;
|
||||
# basically nPk = (n-r+1)(n-r+2)...(n-2)(n-1)n = n!/(n-r)! #
|
||||
CPREAL i := n-r+1;
|
||||
WHILE i <= n DO
|
||||
out*:= i;
|
||||
# a crude check for underflow #
|
||||
IF i = i + 1 THEN IF NOT cp fix value error(CPARGS("P",ENTIER n,ENTIER r)) THEN stop FI FI;
|
||||
i+:=1
|
||||
OD;
|
||||
out
|
||||
);
|
||||
END COMMENT
|
||||
|
||||
# basically C(n,r) = nCk = nPk/r! = n!/(n-r)!/r! #
|
||||
OP C = (CPINT n, r)CPOUT: (
|
||||
IF n < r ORF r < 0 THEN IF NOT cp fix value error(("C",n,r)) THEN stop FI FI;
|
||||
CPINT largest = ( r > n - r | r | n - r );
|
||||
CPINT smallest = n - largest;
|
||||
CPOUT out := 1;
|
||||
INT smaller fact := 2;
|
||||
FOR larger fact FROM largest+1 TO n DO
|
||||
# try and prevent overflow, p.s. there must be a smarter way to do this #
|
||||
# Problems: loop stalls when 'smaller fact' is a largeish co prime #
|
||||
out *:= larger fact;
|
||||
WHILE smaller fact <= smallest ANDF out MOD smaller fact = 0 DO
|
||||
out OVERAB smaller fact;
|
||||
smaller fact +:= 1
|
||||
OD
|
||||
OD;
|
||||
out # EXIT with: n P r OVER r P r #
|
||||
);
|
||||
|
||||
OP C = (CPREAL n, CPREAL r)CPREAL: # 'ln gamma' requires GSL library #
|
||||
exp(ln gamma(n+1)-ln gamma(n-r+1)-ln gamma(r+1));
|
||||
|
||||
# basically C(n,r) = nCk = nPk/r! = n!/(n-r)!/r! #
|
||||
COMMENT # alternate slower version #
|
||||
OP C = (CPREAL n, REAL r)CPREAL: (
|
||||
IF n < r ORF r < 0 THEN IF NOT cp fix value error(("C",ENTIER n,ENTIER r)) THEN stop FI FI;
|
||||
CPREAL largest = ( r > n - r | r | n - r );
|
||||
CPREAL smallest = n - largest;
|
||||
CPREAL out := 1;
|
||||
REAL smaller fact := 2;
|
||||
REAL larger fact := largest+1;
|
||||
WHILE larger fact <= n DO # todo: check underflow here #
|
||||
# try and prevent overflow, p.s. there must be a smarter way to do this #
|
||||
out *:= larger fact;
|
||||
WHILE smaller fact <= smallest ANDF out > smaller fact DO
|
||||
out /:= smaller fact;
|
||||
smaller fact +:= 1
|
||||
OD;
|
||||
larger fact +:= 1
|
||||
OD;
|
||||
out # EXIT with: n P r OVER r P r #
|
||||
);
|
||||
END COMMENT
|
||||
|
||||
SKIP
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#!/usr/bin/a68g --script #
|
||||
# -*- coding: utf-8 -*- #
|
||||
|
||||
CO REQUIRED by "prelude_combinations_and_permutations.a68" CO
|
||||
MODE CPINT = #LONG# INT;
|
||||
MODE CPOUT = #LONG# INT; # the answer, can be REAL #
|
||||
MODE CPREAL = REAL; # the answer, can be REAL #
|
||||
PROC cp fix value error = (#REF# CPARGS args)BOOL: (
|
||||
putf(stand error, ($"Value error: "g(0)gg(0)"arg out of range"l$,
|
||||
n OF args, name OF args, k OF args));
|
||||
FALSE # unfixable #
|
||||
);
|
||||
#PROVIDES:#
|
||||
# OP C = (CP~,CP~)CP~: ~ #
|
||||
# OP P = (CP~,CP~)CP~: ~ #
|
||||
PR READ "prelude_combinations_and_permutations.a68" PR;
|
||||
|
||||
printf($"A sample of Permutations from 1 to 12:"l$);
|
||||
FOR i FROM 4 BY 1 TO 12 DO
|
||||
INT first = i - 2,
|
||||
second = i - ENTIER sqrt(i);
|
||||
printf(($g(0)" P "g(0)" = "g(0)$, i, first, i P first, $", "$));
|
||||
printf(($g(0)" P "g(0)" = "g(0)$, i, second, i P second, $l$))
|
||||
OD;
|
||||
|
||||
printf($l"A sample of Combinations from 10 to 60:"l$);
|
||||
FOR i FROM 10 BY 10 TO 60 DO
|
||||
INT first = i - 2,
|
||||
second = i - ENTIER sqrt(i);
|
||||
printf(($"("g(0)" C "g(0)") = "g(0)$, i, first, i C first, $", "$));
|
||||
printf(($"("g(0)" C "g(0)") = "g(0)$, i, second, i C second, $l$))
|
||||
OD;
|
||||
|
||||
printf($l"A sample of Permutations from 5 to 15000:"l$);
|
||||
FOR i FROM 5 BY 10 TO 150 DO
|
||||
REAL r = i,
|
||||
first = r - 2,
|
||||
second = r - ENTIER sqrt(r);
|
||||
printf(($g(0)" P "g(0)" = "g(-real width,real width-5,-1)$, r, first, r P first, $", "$));
|
||||
printf(($g(0)" P "g(0)" = "g(-real width,real width-5,-1)$, r, second, r P second, $l$))
|
||||
OD;
|
||||
|
||||
printf($l"A sample of Combinations from 10 to 190:"l$);
|
||||
FOR i FROM 100 BY 100 TO 1000 DO
|
||||
REAL r = i,
|
||||
first = r - 2,
|
||||
second = r - ENTIER sqrt(r);
|
||||
printf(($"("g(0)" C "g(0)") = "g(0,1)$, r, first, r C first, $", "$));
|
||||
printf(($"("g(0)" C "g(0)") = "g(0,1)$, r, second, r C second, $l$))
|
||||
OD
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
( ( C
|
||||
= n k coef
|
||||
. !arg:(?n,?k)
|
||||
& (!n+-1*!k:<!k:?k|)
|
||||
& 1:?coef
|
||||
& whl
|
||||
' ( !k:>0
|
||||
& !coef*!n*!k^-1:?coef
|
||||
& !k+-1:?k
|
||||
& !n+-1:?n
|
||||
)
|
||||
& !coef
|
||||
)
|
||||
& ( P
|
||||
= n k result
|
||||
. !arg:(?n,?k)
|
||||
& !n+-1*!k:?k
|
||||
& 1:?result
|
||||
& whl
|
||||
' ( !n:>!k
|
||||
& !n*!result:?result
|
||||
& !n+-1:?n
|
||||
)
|
||||
& !result
|
||||
)
|
||||
& 0:?i
|
||||
& whl
|
||||
' ( 1+!i:~>12:?i
|
||||
& div$(!i.3):?k
|
||||
& out$(!i P !k "=" P$(!i,!k))
|
||||
)
|
||||
& 0:?i
|
||||
& whl
|
||||
' ( 10+!i:~>60:?i
|
||||
& div$(!i.3):?k
|
||||
& out$(!i C !k "=" C$(!i,!k))
|
||||
)
|
||||
& ( displayBig
|
||||
=
|
||||
. @(!arg:?show [50 ? [?length)
|
||||
& !show "... (" !length+-50 " more digits)"
|
||||
| !arg
|
||||
)
|
||||
& 5 50 500 1000 5000 15000:?is
|
||||
& whl
|
||||
' ( !is:%?i ?is
|
||||
& div$(!i.3):?k
|
||||
& out$(str$(!i " P " !k " = " displayBig$(P$(!i,!k))))
|
||||
)
|
||||
& 0:?i
|
||||
& whl
|
||||
' ( 100+!i:~>1000:?i
|
||||
& div$(!i.3):?k
|
||||
& out$(str$(!i " C " !k " = " displayBig$(C$(!i,!k))))
|
||||
)
|
||||
);
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#include <gmp.h>
|
||||
|
||||
void perm(mpz_t out, int n, int k)
|
||||
{
|
||||
mpz_set_ui(out, 1);
|
||||
k = n - k;
|
||||
while (n > k) mpz_mul_ui(out, out, n--);
|
||||
}
|
||||
|
||||
void comb(mpz_t out, int n, int k)
|
||||
{
|
||||
perm(out, n, k);
|
||||
while (k) mpz_divexact_ui(out, out, k--);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
mpz_t x;
|
||||
mpz_init(x);
|
||||
|
||||
perm(x, 1000, 969);
|
||||
gmp_printf("P(1000,969) = %Zd\n", x);
|
||||
|
||||
comb(x, 1000, 969);
|
||||
gmp_printf("C(1000,969) = %Zd\n", x);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import std.stdio, std.mathspecial, std.range, std.algorithm,
|
||||
std.bigint, std.conv;
|
||||
|
||||
enum permutation = (in uint n, in uint k) pure =>
|
||||
reduce!q{a * b}(1.BigInt, iota(n - k + 1, n + 1));
|
||||
|
||||
enum combination = (in uint n, in uint k) pure =>
|
||||
n.permutation(k) / reduce!q{a * b}(1.BigInt, iota(1, k + 1));
|
||||
|
||||
enum bigPermutation = (in uint n, in uint k) =>
|
||||
exp(logGamma(n + 1) - logGamma(n - k + 1));
|
||||
|
||||
enum bigCombination = (in uint n, in uint k) =>
|
||||
exp(logGamma(n + 1) - logGamma(n - k + 1) - logGamma(k + 1));
|
||||
|
||||
void main() {
|
||||
12.permutation(9).writeln;
|
||||
12.bigPermutation(9).writeln;
|
||||
60.combination(53).writeln;
|
||||
145.bigPermutation(133).writeln;
|
||||
900.bigCombination(450).writeln;
|
||||
1_000.bigCombination(969).writeln;
|
||||
15_000.bigPermutation(73).writeln;
|
||||
15_000.bigPermutation(1185).writeln;
|
||||
writefln("%(%s\\\n%)", 15_000.permutation(74).text.chunks(50));
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
procedure main()
|
||||
write("P(4,2) = ",P(4,2))
|
||||
write("P(8,2) = ",P(8,2))
|
||||
write("P(10,8) = ",P(10,8))
|
||||
write("C(10,8) = ",C(10,8))
|
||||
write("C(20,8) = ",C(20,8))
|
||||
write("C(60,58) = ",C(60,58))
|
||||
write("P(1000,10) = ",P(1000,10))
|
||||
write("P(1000,20) = ",P(1000,20))
|
||||
write("P(15000,2) = ",P(15000,2))
|
||||
write("C(1000,10) = ",C(1000,10))
|
||||
write("C(1000,999) = ",C(1000,999))
|
||||
write("C(1000,1000) = ",C(1000,1000))
|
||||
write("C(15000,14998) = ",C(15000,14998))
|
||||
end
|
||||
|
||||
procedure C(n,k)
|
||||
every (d:=1) *:= 2 to k
|
||||
return P(n,k)/d
|
||||
end
|
||||
|
||||
procedure P(n,k)
|
||||
every (p:=1) *:= (n-k+1) to n
|
||||
return p
|
||||
end
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
C=: !
|
||||
P=: (<: * (*/@}. 1+i.))"0
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
P table 1+i.12
|
||||
┌──┬─────────────────────────────────────────────────────────────┐
|
||||
│P │1 2 3 4 5 6 7 8 9 10 11 12│
|
||||
├──┼─────────────────────────────────────────────────────────────┤
|
||||
│ 1│1 2 6 24 120 720 5040 40320 362880 3628800 39916800 479001600│
|
||||
│ 2│0 1 3 12 60 360 2520 20160 181440 1814400 19958400 239500800│
|
||||
│ 3│0 0 1 4 20 120 840 6720 60480 604800 6652800 79833600│
|
||||
│ 4│0 0 0 1 5 30 210 1680 15120 151200 1663200 19958400│
|
||||
│ 5│0 0 0 0 1 6 42 336 3024 30240 332640 3991680│
|
||||
│ 6│0 0 0 0 0 1 7 56 504 5040 55440 665280│
|
||||
│ 7│0 0 0 0 0 0 1 8 72 720 7920 95040│
|
||||
│ 8│0 0 0 0 0 0 0 1 9 90 990 11880│
|
||||
│ 9│0 0 0 0 0 0 0 0 1 10 110 1320│
|
||||
│10│0 0 0 0 0 0 0 0 0 1 11 132│
|
||||
│11│0 0 0 0 0 0 0 0 0 0 1 12│
|
||||
│12│0 0 0 0 0 0 0 0 0 0 0 1│
|
||||
└──┴─────────────────────────────────────────────────────────────┘
|
||||
|
||||
C table 10+10*i.6x
|
||||
┌──┬─────────────────────────────────────────────────────────────────┐
|
||||
│C │10 20 30 40 50 60│
|
||||
├──┼─────────────────────────────────────────────────────────────────┤
|
||||
│10│ 1 184756 30045015 847660528 10272278170 75394027566│
|
||||
│20│ 0 1 30045015 137846528820 47129212243960 4191844505805495│
|
||||
│30│ 0 0 1 847660528 47129212243960 118264581564861424│
|
||||
│40│ 0 0 0 1 10272278170 4191844505805495│
|
||||
│50│ 0 0 0 0 1 75394027566│
|
||||
│60│ 0 0 0 0 0 1│
|
||||
└──┴─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
5 P 100
|
||||
7.77718e155
|
||||
100 P 200
|
||||
8.45055e216
|
||||
300 P 400
|
||||
2.09224e254
|
||||
700 P 800
|
||||
3.18349e287
|
||||
|
||||
5 C 100
|
||||
75287520
|
||||
100 C 200
|
||||
9.05485e58
|
||||
300 C 400
|
||||
2.24185e96
|
||||
700 C 800
|
||||
3.41114e129
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
ClearAll[Combination,Permutation]
|
||||
Combination[n_,k_]:=Binomial[n,k]
|
||||
Permutation[n_,k_]:=Binomial[n,k]k!
|
||||
|
||||
TableForm[Array[Permutation,{12,12}],TableHeadings->{Range[12],Range[12]}]
|
||||
TableForm[Array[Combination,{6,6},{{10,60},{10,60}}],TableHeadings->{Range[10,60,10],Range[10,60,10]}]
|
||||
{Row[{#,"P",#-2}," "],N@Permutation[#,#-2]}&/@{5,1000,5000,10000,15000}//Grid
|
||||
{Row[{#,"C",#/2}," "],N@Combination[#,#/2]}&/@Range[100,1000,100]//Grid
|
||||
|
|
@ -0,0 +1 @@
|
|||
Permutation[200000, 100000]
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
multi P($n, $k) { [*] $n - $k + 1 .. $n }
|
||||
multi C($n, $k) { P($n, $k) / [*] 1 .. $k }
|
||||
|
||||
sub lstirling(\n) {
|
||||
n < 10 ?? lstirling(n+1) - log(n+1) !!
|
||||
.5*log(2*pi*n)+ n*log(n/e+1/(12*e*n))
|
||||
}
|
||||
|
||||
role Logarithm {
|
||||
method gist {
|
||||
my $e = (self/10.log).Int;
|
||||
sprintf "%.8fE%+d", exp(self - $e*10.log), $e;
|
||||
}
|
||||
}
|
||||
multi P($n, $k, :$float!) {
|
||||
(lstirling($n) - lstirling($n -$k))
|
||||
but Logarithm
|
||||
}
|
||||
multi C($n, $k, :$float!) {
|
||||
(lstirling($n) - lstirling($n -$k) - lstirling($k))
|
||||
but Logarithm
|
||||
}
|
||||
|
||||
say "Exact results:";
|
||||
for 1..12 -> $n {
|
||||
my $p = $n div 3;
|
||||
say "P($n, $p) = ", P($n, $p);
|
||||
}
|
||||
|
||||
for 10, 20 ... 60 -> $n {
|
||||
my $p = $n div 3;
|
||||
say "C($n, $p) = ", C($n, $p);
|
||||
}
|
||||
|
||||
say;
|
||||
say "Floating point approximations:";
|
||||
for 5, 50, 500, 1000, 5000, 15000 -> $n {
|
||||
my $p = $n div 3;
|
||||
say "P($n, $p) = ", P($n, $p, :float);
|
||||
}
|
||||
|
||||
for 100, 200 ... 1000 -> $n {
|
||||
my $p = $n div 3;
|
||||
say "C($n, $p) = ", C($n, $p, :float);
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
|
||||
showoff( "Permutations", \&P, "P", 1 .. 12 );
|
||||
showoff( "Combinations", \&C, "C", map $_*10, 1..6 );
|
||||
showoff( "Permutations", \&P_big, "P", 5, 50, 500, 1000, 5000, 15000 );
|
||||
showoff( "Combinations", \&C_big, "C", map $_*100, 1..10 );
|
||||
|
||||
sub showoff {
|
||||
my ($text, $code, $fname, @n) = @_;
|
||||
print "\nA sample of $text from $n[0] to $n[-1]\n";
|
||||
for my $n ( @n ) {
|
||||
my $k = int( $n / 3 );
|
||||
print $n, " $fname $k = ", $code->($n, $k), "\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub P {
|
||||
my ($n, $k) = @_;
|
||||
my $x = 1;
|
||||
$x *= $_ for $n - $k + 1 .. $n ;
|
||||
$x;
|
||||
}
|
||||
|
||||
sub P_big {
|
||||
my ($n, $k) = @_;
|
||||
my $x = 0;
|
||||
$x += log($_) for $n - $k + 1 .. $n ;
|
||||
eshow($x);
|
||||
}
|
||||
|
||||
sub C {
|
||||
my ($n, $k) = @_;
|
||||
my $x = 1;
|
||||
$x *= ($n - $_ + 1) / $_ for 1 .. $k;
|
||||
$x;
|
||||
}
|
||||
|
||||
sub C_big {
|
||||
my ($n, $k) = @_;
|
||||
my $x = 0;
|
||||
$x += log($n - $_ + 1) - log($_) for 1 .. $k;
|
||||
exp($x);
|
||||
}
|
||||
|
||||
sub eshow {
|
||||
my ($x) = @_;
|
||||
my $e = int( $x / log(10) );
|
||||
sprintf "%.8Fe%+d", exp($x - $e * log(10)), $e;
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
from __future__ import print_function
|
||||
|
||||
from scipy.misc import factorial as fact
|
||||
from scipy.misc import comb
|
||||
|
||||
def perm(N, k, exact=0):
|
||||
return comb(N, k, exact) * fact(k, exact)
|
||||
|
||||
exact=True
|
||||
print('Sample Perms 1..12')
|
||||
for N in range(1, 13):
|
||||
k = max(N-2, 1)
|
||||
print('%iP%i =' % (N, k), perm(N, k, exact), end=', ' if N % 5 else '\n')
|
||||
|
||||
print('\n\nSample Combs 10..60')
|
||||
for N in range(10, 61, 10):
|
||||
k = N-2
|
||||
print('%iC%i =' % (N, k), comb(N, k, exact), end=', ' if N % 50 else '\n')
|
||||
|
||||
exact=False
|
||||
print('\n\nSample Perms 5..1500 Using FP approximations')
|
||||
for N in [5, 15, 150, 1500, 15000]:
|
||||
k = N-2
|
||||
print('%iP%i =' % (N, k), perm(N, k, exact))
|
||||
|
||||
print('\nSample Combs 100..1000 Using FP approximations')
|
||||
for N in range(100, 1001, 100):
|
||||
k = N-2
|
||||
print('%iC%i =' % (N, k), comb(N, k, exact))
|
||||
1
Task/Combinations-and-permutations/README
Normal file
1
Task/Combinations-and-permutations/README
Normal file
|
|
@ -0,0 +1 @@
|
|||
Data source: http://rosettacode.org/wiki/Combinations_and_permutations
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*REXX program to compute a sampling of combinations and permutations. */
|
||||
numeric digits 100 /*use hundred digits of precision*/
|
||||
|
||||
do j=1 to 12 /*show permutations from 1──► 12 */
|
||||
_=; do k=1 to j /*step through all J permutations*/
|
||||
_=_ 'P('j","k')='perm(j,k)" " /*add an extra blank between #s. */
|
||||
end /*k*/
|
||||
say strip(_) /*show a horizontal line of PERMs*/
|
||||
end /*j*/
|
||||
say
|
||||
do j=10 to 60 by 10 /*show some combinations 10──► 60*/
|
||||
_=; do k=1 to j by j%5 /*step through some combinations.*/
|
||||
_=_ 'C('j","k')='comb(j,k)" " /*add an extra blank between #s. */
|
||||
end /*k*/
|
||||
say strip(_) /*show a horizontal line of COMBs*/
|
||||
end /*j*/
|
||||
say
|
||||
numeric digits 20 /*force floating point for big #s*/
|
||||
|
||||
do j=5 to 15000 by 1000 /*show a few permutations, big #s*/
|
||||
_=; do k=1 to j by j%10 for 5 /*go through some J permutations.*/
|
||||
_=_ 'P('j","k')='perm(j,k)" " /*add an extra blank between #s. */
|
||||
end /*k*/
|
||||
say strip(_) /*show a horizontal line of PERMs*/
|
||||
end /*j*/
|
||||
say
|
||||
do j=100 to 1000 by 100 /*show a few combinations, big #s*/
|
||||
_=; do k=1 to j by j%5 /*step through some combinations.*/
|
||||
_=_ 'C('j","k')='comb(j,k)" " /*add an extra blank between #s. */
|
||||
end /*k*/
|
||||
say strip(_) /*show a horizontal line of COMBs*/
|
||||
end /*j*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────COMB subroutine─────────────────────*/
|
||||
comb: procedure; parse arg x,y /*args: X things, Y at-a-time.*/
|
||||
if y>x then return 0 /*oops-say, to big a chunk. */
|
||||
if x=y then return 1 /* X things same as chunk size. */
|
||||
if x-y<y then y=x-y /*switch things around for speed.*/
|
||||
call .cmbPrm /*call sub to do heavy lifting. */
|
||||
return _/!(y) /*perform one last division. */
|
||||
/*──────────────────────────────────PERM subroutine─────────────────────*/
|
||||
perm: procedure; parse arg x,y; call .cmbPrm; return _
|
||||
/*──────────────────────────────────.CMBPRM sugroutine──────────────────*/
|
||||
.cmbPrm: _=1; do j=x-y+1 to x; _=_*j; end; return _
|
||||
/*──────────────────────────────────! subroutine────────────────────────*/
|
||||
!: procedure; parse arg x; !=1; do j=2 to x; !=!*j; end; return !
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#lang racket
|
||||
(require math)
|
||||
(define C binomial)
|
||||
(define P permutations)
|
||||
|
||||
(C 1000 10) ; -> 263409560461970212832400
|
||||
(P 1000 10) ; -> 955860613004397508326213120000
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
include Math
|
||||
|
||||
class Integer
|
||||
|
||||
def permutation(k)
|
||||
(self-k+1 .. self).inject( :*)
|
||||
end
|
||||
|
||||
def combination(k)
|
||||
self.permutation(k) / (1 .. k).inject( :*)
|
||||
end
|
||||
|
||||
def big_permutation(k)
|
||||
exp( lgamma_plus(self) - lgamma_plus(self -k))
|
||||
end
|
||||
|
||||
def big_combination(k)
|
||||
exp( lgamma_plus(self) - lgamma_plus(self - k) - lgamma_plus(k))
|
||||
end
|
||||
|
||||
private
|
||||
def lgamma_plus(n)
|
||||
lgamma(n+1)[0] #lgamma is the natural log of gamma
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
p 12.permutation(9) #=> 79833600
|
||||
p 12.big_permutation(9) #=> 79833600.00000021
|
||||
p 60.combination(53) #=> 386206920
|
||||
p 145.big_permutation(133) #=> 1.6801459655817956e+243
|
||||
p 900.big_combination(450) #=> 2.247471882064647e+269
|
||||
p 1000.big_combination(969) #=> 7.602322407770517e+58
|
||||
p 15000.big_permutation(73) #=> 6.004137561717704e+304
|
||||
#That's about the maximum of Float:
|
||||
p 15000.big_permutation(74) #=> Infinity
|
||||
# Integer has no maximum:
|
||||
p 15000.permutation(74) #=> 896237613852967826239917238565433149353074416025197784301593335243699358040738127950872384197159884905490054194835376498534786047382445592358843238688903318467070575184552953997615178973027752714539513893159815472948987921587671399790410958903188816684444202526779550201576117111844818124800000000000000000000
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# Exact integer versions
|
||||
proc tcl::mathfunc::P {n k} {
|
||||
set t 1
|
||||
for {set i $n} {$i > $n-$k} {incr i -1} {
|
||||
set t [expr {$t * $i}]
|
||||
}
|
||||
return $t
|
||||
}
|
||||
proc tcl::mathfunc::C {n k} {
|
||||
set t [P $n $k]
|
||||
for {set i $k} {$i > 1} {incr i -1} {
|
||||
set t [expr {$t / $i}]
|
||||
}
|
||||
return $t
|
||||
}
|
||||
|
||||
# Floating point versions using the Gamma function
|
||||
package require math
|
||||
proc tcl::mathfunc::lnGamma n {math::ln_Gamma $n}
|
||||
proc tcl::mathfunc::fP {n k} {
|
||||
expr {exp(lnGamma($n+1) - lnGamma($n-$k+1))}
|
||||
}
|
||||
proc tcl::mathfunc::fC {n k} {
|
||||
expr {exp(lnGamma($n+1) - lnGamma($n-$k+1) - lnGamma($k+1))}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
# Using the exact integer versions
|
||||
puts "A sample of Permutations from 1 to 12:"
|
||||
for {set i 4} {$i <= 12} {incr i} {
|
||||
set ii [expr {$i - 2}]
|
||||
set iii [expr {$i - int(sqrt($i))}]
|
||||
puts "$i P $ii = [expr {P($i,$ii)}], $i P $iii = [expr {P($i,$iii)}]"
|
||||
}
|
||||
puts "A sample of Combinations from 10 to 60:"
|
||||
for {set i 10} {$i <= 60} {incr i 10} {
|
||||
set ii [expr {$i - 2}]
|
||||
set iii [expr {$i - int(sqrt($i))}]
|
||||
puts "$i C $ii = [expr {C($i,$ii)}], $i C $iii = [expr {C($i,$iii)}]"
|
||||
}
|
||||
# Using the approximate floating point versions
|
||||
puts "A sample of Permutations from 5 to 15000:"
|
||||
for {set i 5} {$i <= 150} {incr i 10} {
|
||||
set ii [expr {$i - 2}]
|
||||
set iii [expr {$i - int(sqrt($i))}]
|
||||
puts "$i P $ii = [expr {fP($i,$ii)}], $i P $iii = [expr {fP($i,$iii)}]"
|
||||
}
|
||||
puts "A sample of Combinations from 100 to 1000:"
|
||||
for {set i 100} {$i <= 1000} {incr i 100} {
|
||||
set ii [expr {$i - 2}]
|
||||
set iii [expr {$i - int(sqrt($i))}]
|
||||
puts "$i C $ii = [expr {fC($i,$ii)}], $i C $iii = [expr {fC($i,$iii)}]"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue