2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -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]] <big> (<sup>n</sup>C<sub>k</sub>) </big> and [[wp:Permutation|permutation]] <big> (<sup>n</sup>P<sub>k</sub>) </big> 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]].
|
||||
* 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]].
|
||||
|
||||
|
||||
;Related task:
|
||||
* [[Evaluate binomial coefficients]]
|
||||
|
||||
'''See Also:'''
|
||||
* [[Evaluate binomial coefficients]]
|
||||
{{Template:Combinations and permutations}}
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -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))) )))
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
(1..60).to_a.combination(53).size #=> 386206920
|
||||
Loading…
Add table
Add a link
Reference in a new issue