2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -1,15 +1,25 @@
{{wikipedia|Combination}} {{wikipedia|Permutation}}
{{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.
Implement the [[wp:Combination|combination]] &nbsp; <big> (<sup>n</sup>C<sub>k</sub>) </big> &nbsp; and [[wp:Permutation|permutation]] &nbsp; <big> (<sup>n</sup>P<sub>k</sub>) </big> &nbsp; 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>
<br>
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]].
* &nbsp; A sample of permutations from 1 to 12 and Combinations from 10 to 60 using exact Integer arithmetic.
* &nbsp; 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]].
;Related task:
* &nbsp; [[Evaluate binomial coefficients]]
'''See Also:'''
* [[Evaluate binomial coefficients]]
{{Template:Combinations and permutations}}
<br><br>

View file

@ -0,0 +1,11 @@
(defun combinations (n k)
(let ((num 1)
(den 1) )
(dotimes (i k (/ num den))
(setq num (* num (- n i)) den (* den (- k i))) )))
(defun permutations (n k)
(let ((p 1))
(dotimes (i k p)
(setq p (* p (- n i))) )))

View file

@ -0,0 +1,38 @@
defmodule Combinations_permutations do
def perm(n, k), do: product(n - k + 1 .. n)
def comb(n, k), do: div( perm(n, k), product(1 .. k) )
defp product(a..b) when a>b, do: 1
defp product(list), do: Enum.reduce(list, 1, fn n, acc -> n * acc end)
def test do
IO.puts "\nA sample of permutations from 1 to 12:"
Enum.each(1..12, &show_perm(&1, div(&1, 3)))
IO.puts "\nA sample of combinations from 10 to 60:"
Enum.take_every(10..60, 10) |> Enum.each(&show_comb(&1, div(&1, 3)))
IO.puts "\nA sample of permutations from 5 to 15000:"
Enum.each([5,50,500,1000,5000,15000], &show_perm(&1, div(&1, 3)))
IO.puts "\nA sample of combinations from 100 to 1000:"
Enum.take_every(100..1000, 100) |> Enum.each(&show_comb(&1, div(&1, 3)))
end
defp show_perm(n, k), do: show_gen(n, k, "perm", &perm/2)
defp show_comb(n, k), do: show_gen(n, k, "comb", &comb/2)
defp show_gen(n, k, strfun, fun), do:
IO.puts "#{strfun}(#{n}, #{k}) = #{show_big(fun.(n, k), 40)}"
defp show_big(n, limit) do
strn = to_string(n)
if String.length(strn) < limit do
strn
else
{shown, hidden} = String.split_at(strn, limit)
"#{shown}... (#{String.length(hidden)} more digits)"
end
end
end
Combinations_permutations.test

View file

@ -0,0 +1,10 @@
sample(f,a,b)=for(i=1,4, my(n1=random(b-a)+a,n2=random(b-a)+a); [n1,n2]=[max(n1,n2),min(n1,n2)]; print(n1", "n2": "f(n1,n2)))
permExact(m,n)=factorback([m-n+1..m]);
combExact=binomial;
permApprox(m,n)=exp(lngamma(m+1)-lngamma(m-n+1));
combApprox(m,n)=exp(lngamma(m+1)-lngamma(n+1)-lngamma(m-n+1));
sample(permExact, 1, 12);
sample(combExact, 10, 60);
sample(permApprox, 5, 15000);
sample(combApprox, 100, 1000);

View file

@ -1,44 +1,44 @@
/*REXX program to compute and show a sampling of combinations and permutations*/
numeric digits 100 /*use 100 decimal digits of precision. */
/*REXX program compute and displays a sampling of combinations and permutations. */
numeric digits 100 /*use 100 decimal digits of precision. */
do j=1 for 12 /*show all permutations from 1 ──► 12.*/
_=; do k=1 for j /*step through all J permutations. */
_=_ 'P('j","k')='perm(j,k)" " /*add an extra blank between numbers. */
end /*k*/
say strip(_) /*show the permutations horizontally. */
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 numbers. */
end /*k*/
say strip(_) /*show the combinations horizontally. */
end /*j*/
say
numeric digits 20 /*force floating point for big numbers.*/
do j=1 for 12; _= /*show all permutations from 1 ──► 12.*/
do k=1 for j /*step through all J permutations. */
_=_ 'P('j","k')='perm(j,k)" " /*add an extra blank between numbers. */
end /*k*/
say strip(_) /*show the permutations horizontally. */
end /*j*/
say /*display a blank line for readability.*/
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 numbers. */
end /*k*/
say strip(_) /*show the combinations horizontally. */
end /*j*/
say /*display a blank line for readability.*/
numeric digits 20 /*force floating point for big numbers.*/
do j=5 to 15000 by 1000 /*show a few permutations, big numbers.*/
_=; do k=1 to j for 5 by j%10 /*step through some J permutations. */
_=_ 'P('j","k')='perm(j,k)" " /*add an extra blank between numbers. */
end /*k*/
say strip(_) /*show the permutations horizontally. */
end /*j*/
say
do j=100 to 1000 by 100 /*show a few combinations, big numbers.*/
_=; do k= 1 to j by j%5 /*step through some combinations. */
_=_ 'C('j","k')='comb(j,k)" " /*add an extra blank between numbers. */
end /*k*/
say strip(_) /*show the combinations horizontally. */
end /*j*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────one─liner subroutines─────────────────────*/
perm: procedure; parse arg x,y; call .combPerm; return _
.combPerm: _=1; do j=x-y+1 to x; _=_*j; end; return _
!: procedure; parse arg x; !=1; do j=2 to x; !=!*j; end; return !
/*────────────────────────────────────────────────────────────────────────────*/
comb: procedure; parse arg x,y /*arguments: X things, Y at-a-time.*/
if y>x then return 0 /*oops-say, too big a chunk. */
if x=y then return 1 /*X things are the same as chunk size.*/
if x-y<y then y=x-y /*switch things around for speed. */
call .combPerm /*call subroutine to do heavy lifting. */
return _/!(y) /*just perform one last division. */
do j=5 to 15000 by 1000; _= /*show a few permutations, big numbers.*/
do k=1 to j for 5 by j%10 /*step through some J permutations. */
_=_ 'P('j","k')='perm(j,k)" " /*add an extra blank between numbers. */
end /*k*/
say strip(_) /*show the permutations horizontally. */
end /*j*/
say /*display a blank line for readability.*/
do j=100 to 1000 by 100; _= /*show a few combinations, big numbers.*/
do k= 1 to j by j%5 /*step through some combinations. */
_=_ 'C('j","k')='comb(j,k)" " /*add an extra blank between numbers. */
end /*k*/
say strip(_) /*show the combinations horizontally. */
end /*j*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
perm: procedure; parse arg x,y; call .combPerm; return _
.combPerm: _=1; do j=x-y+1 to x; _=_*j; end; return _
!: procedure; parse arg x; !=1; do j=2 to x; !=!*j; end; return !
/*──────────────────────────────────────────────────────────────────────────────────────*/
comb: procedure; parse arg x,y /*arguments: X things, Y at-a-time.*/
if y >x then return 0 /*oops-say, an error, too big a chunk.*/
if x =y then return 1 /*X things are the same as chunk size.*/
if x-y <y then y=x - y /*switch things around for speed. */
call .combPerm /*call subroutine to do heavy lifting. */
return _ / !(y) /*just perform one last division. */

View file

@ -34,5 +34,5 @@ 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:
#Fixnum has no maximum:
p 15000.permutation(74) #=> 896237613852967826239917238565433149353074416025197784301593335243699358040738127950872384197159884905490054194835376498534786047382445592358843238688903318467070575184552953997615178973027752714539513893159815472948987921587671399790410958903188816684444202526779550201576117111844818124800000000000000000000

View file

@ -0,0 +1 @@
(1..60).to_a.combination(53).size #=> 386206920