This commit is contained in:
Ingy döt Net 2013-04-10 16:57:12 -07:00
parent 518da4a923
commit 764da6cbbb
6144 changed files with 83610 additions and 11 deletions

View file

@ -0,0 +1,14 @@
Given non-negative integers <tt>m</tt> and <tt>n</tt>, generate all size <tt>m</tt> [http://mathworld.wolfram.com/Combination.html combinations] of the integers from 0 to <tt>n-1</tt> in sorted order (each combination is sorted and the entire table is sorted).
For example, <tt>3 comb 5</tt> is
0 1 2
0 1 3
0 1 4
0 2 3
0 2 4
0 3 4
1 2 3
1 2 4
1 3 4
2 3 4
If it is more "natural" in your language to start counting from <tt>1</tt> instead of <tt>0</tt> the combinations can be of the integers from <tt>1</tt> to <tt>n</tt>.

View file

@ -0,0 +1,2 @@
---
note: Discrete math

View file

@ -0,0 +1,54 @@
MODE DATA = INT;
PRIO C = 7;
# Calculate the number of combinations anticipated #
OP C = (INT n, k)INT:
CASE k + 1 IN
# case 0: # 1,
# case 1: # n
OUT (n - 1) C (k - 1) * n OVER k
ESAC;
PROC combinations = (INT m, []DATA list)[,]DATA: (
CASE m IN
# case 1: # ( # transpose list #
[UPB list,1]DATA out;
out[,1]:=list;
out
)
OUT
[UPB list C m, m]DATA out;
INT index out := 1;
FOR i TO UPB list DO
DATA x = list[i];
[,]DATA y = combinations(m - 1, list[i+1:]);
FOR suffix TO UPB y DO
out[index out,1 ] := x;
out[index out,2:] := y[suffix,];
index out +:= 1
OD
OD;
out
ESAC
);
PRIO COMB = 7;
OP COMB = (INT n, k)[,]INT: (
[k]DATA list; # create a list to recombine #
FOR i TO UPB list DO list[i]:=i OD;
combinations(n,list)
);
INT m = 3;
#IF formatted transput possible THEN#
FORMAT data repr = $d$;
FORMAT list repr = $"("n(m-1)(f(data repr)",")f(data repr)")"$;
printf ((list repr, 3 COMB 5, $l$));
#ELSE#
[,]DATA result = 3 COMB 5;
FOR row TO UPB result DO
print ((result[row,], new line))
OD
#FI#

View file

@ -0,0 +1,37 @@
BEGIN {
## Default values for r and n (Choose 3 from pool of 5). Can
## alternatively be set on the command line:-
## awk -v r=<number of items being chosen> -v n=<how many to choose from> -f <scriptname>
if (length(r) == 0) r = 3
if (length(n) == 0) n = 5
for (i=1; i <= r; i++) { ## First combination of items:
A[i] = i
if (i < r ) printf i OFS
else print i}
## While 1st item is less than its maximum permitted value...
while (A[1] < n - r + 1) {
## loop backwards through all items in the previous
## combination of items until an item is found that is
## less than its maximum permitted value:
for (i = r; i >= 1; i--) {
## If the equivalently positioned item in the
## previous combination of items is less than its
## maximum permitted value...
if (A[i] < n - r + i) {
## increment the current item by 1:
A[i]++
## Save the current position-index for use
## outside this "for" loop:
p = i
break}}
## Put consecutive numbers in the remainder of the array,
## counting up from position-index p.
for (i = p + 1; i <= r; i++) A[i] = A[i - 1] + 1
## Print the current combination of items:
for (i=1; i <= r; i++) {
if (i < r) printf A[i] OFS
else print A[i]}}
exit}

View file

@ -0,0 +1,56 @@
with Ada.Text_IO; use Ada.Text_IO;
procedure Test_Combinations is
generic
type Integers is range <>;
package Combinations is
type Combination is array (Positive range <>) of Integers;
procedure First (X : in out Combination);
procedure Next (X : in out Combination);
procedure Put (X : Combination);
end Combinations;
package body Combinations is
procedure First (X : in out Combination) is
begin
X (1) := Integers'First;
for I in 2..X'Last loop
X (I) := X (I - 1) + 1;
end loop;
end First;
procedure Next (X : in out Combination) is
begin
for I in reverse X'Range loop
if X (I) < Integers'Val (Integers'Pos (Integers'Last) - X'Last + I) then
X (I) := X (I) + 1;
for J in I + 1..X'Last loop
X (J) := X (J - 1) + 1;
end loop;
return;
end if;
end loop;
raise Constraint_Error;
end Next;
procedure Put (X : Combination) is
begin
for I in X'Range loop
Put (Integers'Image (X (I)));
end loop;
end Put;
end Combinations;
type Five is range 0..4;
package Fives is new Combinations (Five);
use Fives;
X : Combination (1..3);
begin
First (X);
loop
Put (X); New_Line;
Next (X);
end loop;
exception
when Constraint_Error =>
null;
end Test_Combinations;

View file

@ -0,0 +1 @@
type Five is range 0..4;

View file

@ -0,0 +1,27 @@
on comb(n, k)
set c to {}
repeat with i from 1 to k
set end of c to i's contents
end repeat
set r to {c's contents}
repeat while my next_comb(c, k, n)
set end of r to c's contents
end repeat
return r
end comb
on next_comb(c, k, n)
set i to k
set c's item i to (c's item i) + 1
repeat while (i > 1 and c's item i n - k + 1 + i)
set i to i - 1
set c's item i to (c's item i) + 1
end repeat
if (c's item 1 > n - k + 1) then return false
repeat with i from i + 1 to k
set c's item i to (c's item (i - 1)) + 1
end repeat
return true
end next_comb
return comb(5, 3)

View file

@ -0,0 +1 @@
{{1, 2, 3}, {1, 2, 4}, {1, 2, 5}, {1, 3, 4}, {1, 3, 5}, {1, 4, 5}, {2, 3, 4}, {2, 3, 5}, {2, 4, 5}, {3, 4, 5}}

View file

@ -0,0 +1,26 @@
MsgBox % Comb(1,1)
MsgBox % Comb(3,3)
MsgBox % Comb(3,2)
MsgBox % Comb(2,3)
MsgBox % Comb(5,3)
Comb(n,t) { ; Generate all n choose t combinations of 1..n, lexicographically
IfLess n,%t%, Return
Loop %t%
c%A_Index% := A_Index
i := t+1, c%i% := n+1
Loop {
Loop %t%
i := t+1-A_Index, c .= c%i% " "
c .= "`n" ; combinations in new lines
j := 1, i := 2
Loop
If (c%j%+1 = c%i%)
c%j% := j, ++j, ++i
Else Break
If (j > t)
Return c
c%j% += 1
}
}

View file

@ -0,0 +1,45 @@
INSTALL @lib$+"SORTLIB"
sort% = FN_sortinit(0,0)
M% = 3
N% = 5
C% = FNfact(N%)/(FNfact(M%)*FNfact(N%-M%))
DIM s$(C%)
PROCcomb(M%, N%, s$())
CALL sort%, s$(0)
FOR I% = 0 TO C%-1
PRINT s$(I%)
NEXT
END
DEF PROCcomb(C%, N%, s$())
LOCAL I%, U%
FOR U% = 0 TO 2^N%-1
IF FNbits(U%) = C% THEN
s$(I%) = FNlist(U%)
I% += 1
ENDIF
NEXT
ENDPROC
DEF FNbits(U%)
LOCAL N%
WHILE U%
N% += 1
U% = U% AND (U%-1)
ENDWHILE
= N%
DEF FNlist(U%)
LOCAL N%, s$
WHILE U%
IF U% AND 1 s$ += STR$(N%) + " "
N% += 1
U% = U% >> 1
ENDWHILE
= s$
DEF FNfact(N%)
IF N%<=1 THEN = 1 ELSE = N%*FNfact(N%-1)

View file

@ -0,0 +1,24 @@
(comb=
bvar combination combinations list m n pat pvar var
. !arg:(?m.?n)
& ( pat
= ?
& !combinations (.!combination):?combinations
& ~
)
& :?list:?combination:?combinations
& whl
' ( !m+-1:~<0:?m
& chu$(utf$a+!m):?var
& glf$('(%@?.$var)):(=?pvar)
& '(? ()$pvar ()$pat):(=?pat)
& glf$('(!.$var)):(=?bvar)
& ( '$combination:(=)
& '$bvar:(=?combination)
| '($bvar ()$combination):(=?combination)
)
)
& whl
' (!n+-1:~<0:?n&!n !list:?list)
& !list:!pat
| !combinations);

View file

@ -0,0 +1,23 @@
#include <algorithm>
#include <iostream>
#include <string>
void comb(int N, int K)
{
std::string bitmask(K, 1); // K leading 1's
bitmask.resize(N, 0); // N-K trailing 0's
// print integers and permute bitmask
do {
for (int i = 0; i < N; ++i) // [0..N-1] integers
{
if (bitmask[i]) std::cout << " " << i;
}
std::cout << std::endl;
} while (std::prev_permutation(bitmask.begin(), bitmask.end()));
}
int main()
{
comb(5, 3);
}

View file

@ -0,0 +1,29 @@
#include <stdio.h>
/* Type marker stick: using bits to indicate what's chosen. The stick can't
* handle more than 32 items, but the idea is there; at worst, use array instead */
typedef unsigned long marker;
marker one = 1;
void comb(int pool, int need, marker chosen, int at)
{
if (pool < need + at) return; /* not enough bits left */
if (!need) {
/* got all we needed; print the thing. if other actions are
* desired, we could have passed in a callback function. */
for (at = 0; at < pool; at++)
if (chosen & (one << at)) printf("%d ", at);
printf("\n");
return;
}
/* if we choose the current item, "or" (|) the bit to mark it so. */
comb(pool, need - 1, chosen | (one << at), at + 1);
comb(pool, need, chosen, at + 1); /* or don't choose it, go to next */
}
int main()
{
comb(5, 3, 0, 0);
return 0;
}

View file

@ -0,0 +1,26 @@
#include <stdio.h>
void comb(int m, int n, unsigned char *c)
{
int i;
for (i = 0; i < n; i++) c[i] = n - i;
while (1) {
for (i = n; i--;)
printf("%d%c", c[i], i ? ' ': '\n');
/* this check is not strictly necessary, but if m is not close to n,
it makes the whole thing quite a bit faster */
if (c[i]++ < m) continue;
for (i = 0; c[i] >= m - i;) if (++i >= n) return;
for (c[i]++; i; i--) c[i-1] = c[i] + 1;
}
}
int main()
{
unsigned char buf[100];
comb(5, 3, buf);
return 0;
}

View file

@ -0,0 +1,20 @@
(defn combinations
"If m=1, generate a nested list of numbers [0,n)
If m>1, for each x in [0,n), and for each list in the recursion on [x+1,n), cons the two"
[m n]
(letfn [(comb-aux
[m start]
(if (= 1 m)
(for [x (range start n)]
(list x))
(for [x (range start n)
xs (comb-aux (dec m) (inc x))]
(cons x xs))))]
(comb-aux m 0)))
(defn print-combinations
[m n]
(doseq [line (combinations m n)]
(doseq [n line]
(printf "%s " n))
(printf "%n")))

View file

@ -0,0 +1,25 @@
combinations = (n, p) ->
return [ [] ] if p == 0
i = 0
combos = []
combo = []
while combo.length < p
if i < n
combo.push i
i += 1
else
break if combo.length == 0
i = combo.pop() + 1
if combo.length == p
combos.push clone combo
i = combo.pop() + 1
combos
clone = (arr) -> (n for n in arr)
N = 5
for i in [0..N]
console.log "------ #{N} #{i}"
for combo in combinations N, i
console.log combo

View file

@ -0,0 +1,39 @@
> coffee combo.coffee
------ 5 0
[]
------ 5 1
[ 0 ]
[ 1 ]
[ 2 ]
[ 3 ]
[ 4 ]
------ 5 2
[ 0, 1 ]
[ 0, 2 ]
[ 0, 3 ]
[ 0, 4 ]
[ 1, 2 ]
[ 1, 3 ]
[ 1, 4 ]
[ 2, 3 ]
[ 2, 4 ]
[ 3, 4 ]
------ 5 3
[ 0, 1, 2 ]
[ 0, 1, 3 ]
[ 0, 1, 4 ]
[ 0, 2, 3 ]
[ 0, 2, 4 ]
[ 0, 3, 4 ]
[ 1, 2, 3 ]
[ 1, 2, 4 ]
[ 1, 3, 4 ]
[ 2, 3, 4 ]
------ 5 4
[ 0, 1, 2, 3 ]
[ 0, 1, 2, 4 ]
[ 0, 1, 3, 4 ]
[ 0, 2, 3, 4 ]
[ 1, 2, 3, 4 ]
------ 5 5
[ 0, 1, 2, 3, 4 ]

View file

@ -0,0 +1,18 @@
(defun map-combinations (m n fn)
"Call fn with each m combination of the integers from 0 to n-1 as a list. The list may be destroyed after fn returns."
(let ((combination (make-list m)))
(labels ((up-from (low)
(let ((start (1- low)))
(lambda () (incf start))))
(mc (curr left needed comb-tail)
(cond
((zerop needed)
(funcall fn combination))
((= left needed)
(map-into comb-tail (up-from curr))
(funcall fn combination))
(t
(setf (first comb-tail) curr)
(mc (1+ curr) (1- left) (1- needed) (rest comb-tail))
(mc (1+ curr) (1- left) needed comb)))))
(mc 0 n m combination))))

View file

@ -0,0 +1,9 @@
(defun comb (m list fn)
(labels ((comb1 (l c m)
(when (>= (length l) m)
(if (zerop m) (return-from comb1 (funcall fn c)))
(comb1 (cdr l) c m)
(comb1 (cdr l) (cons (first l) c) (1- m)))))
(comb1 list nil m)))
(comb 3 '(0 1 2 3 4 5) #'print)

View file

@ -0,0 +1,15 @@
import std.stdio;
T[][] comb(T)(in T[] arr, in int k) pure nothrow {
if (k == 0) return [[]];
typeof(return) result;
foreach (i, x; arr)
foreach (suffix; arr[i + 1 .. $].comb(k - 1))
result ~= x ~ suffix;
return result;
}
void main() {
//import std.stdio: writeln;
[0, 1, 2, 3].comb(2).writeln();
}

View file

@ -0,0 +1,13 @@
import std.stdio, std.algorithm, std.range;
T[][] comb(T)(in T[] s, in int m) /*pure nothrow*/ {
if (!m) return [[]];
if (s.empty) return [];
return s[1 .. $].comb(m - 1).map!(x => s[0] ~ x)().array() ~
s[1 .. $].comb(m);
}
void main() {
//import std.stdio: writeln;
iota(4).array().comb(2).writeln();
}

View file

@ -0,0 +1,126 @@
module combinations3;
ulong binomial(long n, long k) pure nothrow
in {
assert(n > 0, "binomial: n must be > 0.");
} body {
if (k < 0 || k > n)
return 0;
if (k > (n / 2))
k = n - k;
ulong result = 1;
foreach (ulong d; 1 .. k + 1) {
result *= n;
n--;
result /= d;
}
return result;
}
struct Combinations(T, bool copy=true) {
// Algorithm by Knuth, Pre-fascicle 3A, draft of
// section 7.2.1.3: "Generating all partitions".
T[] items;
int k;
size_t len = -1; // computed lazily
this(in T[] items, in int k)
in {
assert(items.length, "combinations: items can't be empty.");
} body {
this.items = items.dup;
this.k = k;
}
@property size_t length() /*logic_const*/ {
if (len == -1) // set cache
len = cast(size_t)binomial(items.length, k);
return len;
}
int opApply(int delegate(ref T[]) dg) {
if (k == items.length)
return dg(items); // yield items
auto outarr = new T[k];
if (k == 0)
return dg(outarr); // yield []
if (k < 0 || k > items.length)
return 0; // yield nothing
int result, x;
immutable n = items.length;
auto c = new uint[k + 3]; // c[0] isn'k used
foreach (j; 1 .. k + 1)
c[j] = j - 1;
c[k + 1] = n;
c[k + 2] = 0;
int j = k;
while (true) {
// The following lines equal to:
//int pos;
//foreach (i; 1 .. k +1)
// outarr[pos++] = items[c[i]];
auto outarr_ptr = outarr.ptr;
auto c_ptr = &(c[1]);
auto c_ptrkp1 = &(c[k + 1]);
while (c_ptr != c_ptrkp1)
*outarr_ptr++ = items[*c_ptr++];
static if (copy) {
auto outarr2 = outarr.dup;
result = dg(outarr2); // yield outarr2
} else {
result = dg(outarr); // yield outarr
}
if (j > 0) {
x = j;
c[j] = x;
j--;
continue;
}
if ((c[1] + 1) < c[2]) {
c[1]++;
continue;
} else
j = 2;
while (true) {
c[j - 1] = j - 2;
x = c[j] + 1;
if (x == c[j + 1])
j++;
else
break;
}
if (j > k)
return result; // End
c[j] = x;
j--;
}
}
}
Combinations!(T,copy) combinations(bool copy=true, T)
(in T[] items, in int k)
in {
assert(items.length, "combinations: items can't be empty.");
} body {
return Combinations!(T, copy)(items, k);
}
// compile with -version=combinations3_main to run main
version(combinations3_main) void main() {
import std.stdio, std.array;
writeln(array(combinations([1, 2, 3, 4], 2)));
}

View file

@ -0,0 +1,100 @@
module combinations4;
import std.stdio, std.algorithm, std.conv;
ulong choose(int n, int k) nothrow
in {
assert(n >= 0 && k >= 0, "choose: no negative input.");
} body {
static ulong[][] cache;
if (n < k)
return 0;
else if (n == k)
return 1;
while (n >= cache.length)
cache ~= [1UL]; // = choose(m, 0);
auto kmax = min(k, n - k);
while(kmax >= cache[n].length) {
immutable h = cache[n].length;
cache[n] ~= choose(n - 1, h - 1) + choose(n - 1, h);
}
return cache[n][kmax];
}
int largestV(in int p, in int q, in long r) nothrow
in {
assert(p > 0 && q >= 0 && r >= 0, "largestV: no negative input.");
} body {
auto v = p - 1;
while (choose(v, q) > r)
v--;
return v;
}
struct Comb {
immutable int n, m;
@property size_t length() const /*nothrow*/ {
return to!size_t(choose(n, m));
}
int[] opIndex(in size_t idx) const {
if (m < 0 || n < 0)
return [];
if (idx >= length)
throw new Exception("Out of bound");
ulong x = choose(n, m) - 1 - idx;
int a = n, b = m;
auto res = new int[m];
foreach (i; 0 .. m) {
a = largestV(a, b, x);
x = x - choose(a, b);
b = b - 1;
res[i] = n - 1 - a;
}
return res;
}
int opApply(int delegate(ref int[]) dg) const {
int[] yield;
foreach (i; 0 .. length) {
yield = this[i];
if (dg(yield))
break;
}
return 0;
}
static auto On(T)(in T[] arr, in int m) {
auto comb = Comb(arr.length, m);
return new class {
@property size_t length() const /*nothrow*/ {
return comb.length;
}
int opApply(int delegate(ref T[]) dg) const {
auto yield = new T[m];
foreach (c; comb) {
foreach (idx; 0 .. m)
yield[idx] = arr[c[idx]];
if (dg(yield))
break;
}
return 0;
}
};
}
}
version(combinations4_main)
void main() {
foreach (c; Comb.On([1, 2, 3], 2))
writeln(c);
}

View file

@ -0,0 +1,13 @@
def combinations(m, range) {
return if (m <=> 0) { [[]] } else {
def combGenerator {
to iterate(f) {
for i in range {
for suffix in combinations(m.previous(), range & (int > i)) {
f(null, [i] + suffix)
}
}
}
}
}
}

View file

@ -0,0 +1,9 @@
-module(comb).
-compile(export_all).
comb(0,_) ->
[[]];
comb(_,[]) ->
[];
comb(N,[H|T]) ->
[[H|L] || L <- comb(N-1,T)]++comb(N,T).

View file

@ -0,0 +1,89 @@
program Combinations
use iso_fortran_env
implicit none
type comb_result
integer, dimension(:), allocatable :: combs
end type comb_result
type(comb_result), dimension(:), pointer :: r
integer :: i, j
call comb(5, 3, r)
do i = 0, choose(5, 3) - 1
do j = 2, 0, -1
write(*, "(I4, ' ')", advance="no") r(i)%combs(j)
end do
deallocate(r(i)%combs)
write(*,*) ""
end do
deallocate(r)
contains
function choose(n, k, err)
integer :: choose
integer, intent(in) :: n, k
integer, optional, intent(out) :: err
integer :: imax, i, imin, ie
ie = 0
if ( (n < 0 ) .or. (k < 0 ) ) then
write(ERROR_UNIT, *) "negative in choose"
choose = 0
ie = 1
else
if ( n < k ) then
choose = 0
else if ( n == k ) then
choose = 1
else
imax = max(k, n-k)
imin = min(k, n-k)
choose = 1
do i = imax+1, n
choose = choose * i
end do
do i = 2, imin
choose = choose / i
end do
end if
end if
if ( present(err) ) err = ie
end function choose
subroutine comb(n, k, co)
integer, intent(in) :: n, k
type(comb_result), dimension(:), pointer, intent(out) :: co
integer :: i, j, s, ix, kx, hm, t
integer :: err
hm = choose(n, k, err)
if ( err /= 0 ) then
nullify(co)
return
end if
allocate(co(0:hm-1))
do i = 0, hm-1
allocate(co(i)%combs(0:k-1))
end do
do i = 0, hm-1
ix = i; kx = k
do s = 0, n-1
if ( kx == 0 ) exit
t = choose(n-(s+1), kx-1)
if ( ix < t ) then
co(i)%combs(kx-1) = s
kx = kx - 1
else
ix = ix - t
end if
end do
end do
end subroutine comb
end program Combinations

View file

@ -0,0 +1,32 @@
program combinations
implicit none
integer, parameter :: m_max = 3
integer, parameter :: n_max = 5
integer, dimension (m_max) :: comb
character (*), parameter :: fmt = '(i0' // repeat (', 1x, i0', m_max - 1) // ')'
call gen (1)
contains
recursive subroutine gen (m)
implicit none
integer, intent (in) :: m
integer :: n
if (m > m_max) then
write (*, fmt) comb
else
do n = 1, n_max
if ((m == 1) .or. (n > comb (m - 1))) then
comb (m) = n
call gen (m + 1)
end if
end do
end if
end subroutine gen
end program combinations

View file

@ -0,0 +1,10 @@
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5

View file

@ -0,0 +1,29 @@
package main
import (
"fmt"
)
func main() {
comb(5, 3, func(c []int) {
fmt.Println(c)
})
}
func comb(n, m int, emit func([]int)) {
s := make([]int, m)
last := m - 1
var rc func(int, int)
rc = func(i, next int) {
for j := next; j < n; j++ {
s[i] = j
if i == last {
emit(s)
} else {
rc(i+1, j+1)
}
}
return
}
rc(0, 0)
}

View file

@ -0,0 +1,4 @@
comb :: Int -> [a] -> [[a]]
comb 0 _ = [[]]
comb _ [] = []
comb m (x:xs) = map (x:) (comb (m-1) xs) ++ comb m xs

View file

@ -0,0 +1,5 @@
import Data.List (tails)
comb :: Int -> [a] -> [[a]]
comb 0 _ = [[]]
comb m l = [x:ys | x:xs <- tails l, ys <- comb (m-1) xs]

View file

@ -0,0 +1 @@
comb0 m n = comb m [0..n-1]

View file

@ -0,0 +1 @@
comb1 m n = comb m [1..n]

View file

@ -0,0 +1,2 @@
import Data.List (sort, subsequences)
comb m n = sort . filter ((==m) . length) $ subsequences [0..n-1]

View file

@ -0,0 +1 @@
comb m n = filter ((==m . length) $ filterM (const [True, False]) [0..n-1]

View file

@ -0,0 +1,30 @@
import java.util.Collections;
import java.util.LinkedList;
public class Comb{
public static void main(String[] args){
System.out.println(comb(3,5));
}
public static String bitprint(int u){
String s= "";
for(int n= 0;u > 0;++n, u>>= 1)
if((u & 1) > 0) s+= n + " ";
return s;
}
public static int bitcount(int u){
int n;
for(n= 0;u > 0;++n, u&= (u - 1));//Turn the last set bit to a 0
return n;
}
public static LinkedList<String> comb(int c, int n){
LinkedList<String> s= new LinkedList<String>();
for(int u= 0;u < 1 << n;u++)
if(bitcount(u) == c) s.push(bitprint(u));
Collections.sort(s);
return s;
}
}

View file

@ -0,0 +1,18 @@
function bitprint(u) {
var s="";
for (var n=0; u; ++n, u>>=1)
if (u&1) s+=n+" ";
return s;
}
function bitcount(u) {
for (var n=0; u; ++n, u=u&(u-1));
return n;
}
function comb(c,n) {
var s=[];
for (var u=0; u<1<<n; u++)
if (bitcount(u)==c)
s.push(bitprint(u))
return s.sort();
}
comb(3,5)

View file

@ -0,0 +1,25 @@
function combinations(arr, k){
var i,
subI,
ret = [],
sub,
next;
for(i = 0; i < arr.length; i++){
if(k === 1){
ret.push( [ arr[i] ] );
}else{
sub = combinations(arr.slice(i+1, arr.length), k-1);
for(subI = 0; subI < sub.length; subI++ ){
next = sub[subI];
next.unshift(arr[i]);
ret.push( next );
}
}
}
return ret;
}
combinations([0,1,2,3,4], 3);
// produces: [[0, 1, 2], [0, 1, 3], [0, 1, 4], [0, 2, 3], [0, 2, 4], [0, 3, 4], [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]
combinations(["Crosby", "Stills", "Nash", "Young"], 3);
// produces: [["Crosby", "Stills", "Nash"], ["Crosby", "Stills", "Young"], ["Crosby", "Nash", "Young"], ["Stills", "Nash", "Young"]]

View file

@ -0,0 +1,45 @@
-- Recursive version
function map(f, a, ...) if a then return f(a), map(f, ...) end end
function incr(k) return function(a) return k > a and a or a+1 end end
function combs(m, n)
if m * n == 0 then return {{}} end
local ret, old = {}, combs(m-1, n-1)
for i = 1, n do
for k, v in ipairs(old) do ret[#ret+1] = {i, map(incr(i), unpack(v))} end
end
return ret
end
for k, v in ipairs(combs(3, 5)) do print(unpack(v)) end
-- Iterative version
function icombs(a,b)
if a==0 then return end
local taken = {} local slots = {}
for i=1,a do slots[i]=0 end
for i=1,b do taken[i]=false end
local index = 1
while index > 0 do repeat
repeat slots[index] = slots[index] + 1
until slots[index] > b or not taken[slots[index]]
if slots[index] > b then
slots[index] = 0
index = index - 1
if index > 0 then
taken[slots[index]] = false
end
break
else
taken[slots[index]] = true
end
if index == a then
for i=1,a do io.write(slots[i]) io.write(" ") end
io.write("\n")
taken[slots[index]] = false
break
end
index = index + 1
until true end
end
icombs(3, 5)

View file

@ -0,0 +1,14 @@
>> nchoosek((0:4),3)
ans =
0 1 2
0 1 3
0 1 4
0 2 3
0 2 4
0 3 4
1 2 3
1 2 4
1 3 4
2 3 4

View file

@ -0,0 +1,4 @@
use Math::Combinatorics;
@n = (0 .. 4);
print join("\n", map { join(" ", @{$_}) } combine(3, @n)), "\n";

View file

@ -0,0 +1,12 @@
(de comb (M Lst)
(cond
((=0 M) '(NIL))
((not Lst))
(T
(conc
(mapcar
'((Y) (cons (car Lst) Y))
(comb (dec M) (cdr Lst)) )
(comb M (cdr Lst)) ) ) ) )
(comb 3 (1 2 3 4 5))

View file

@ -0,0 +1,7 @@
:- use_module(library(clpfd)).
comb_clpfd(L, M, N) :-
length(L, M),
L ins 1..N,
chain(L, #<),
label(L).

View file

@ -0,0 +1,12 @@
?- comb_clpfd(L, 3, 5), writeln(L), fail.
[1,2,3]
[1,2,4]
[1,2,5]
[1,3,4]
[1,3,5]
[1,4,5]
[2,3,4]
[2,3,5]
[2,4,5]
[3,4,5]
false.

View file

@ -0,0 +1,10 @@
comb_Prolog(L, M, N) :-
length(L, M),
fill(L, 1, N).
fill([], _, _).
fill([H | T], Min, Max) :-
between(Min, Max, H),
H1 is H + 1,
fill(T, H1, Max).

View file

@ -0,0 +1,3 @@
:- use_module(library(clpfd)).
comb_lstcomp(N, M, V) :-
V <- {L & length(L, N), L ins 1..M & all_distinct(L), chain(L, #<), label(L)}.

View file

@ -0,0 +1,3 @@
>>> from itertools import combinations
>>> list(combinations(range(5),3))
[(0, 1, 2), (0, 1, 3), (0, 1, 4), (0, 2, 3), (0, 2, 4), (0, 3, 4), (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]

View file

@ -0,0 +1,6 @@
def comb(m, lst):
if m == 0:
return [[]]
else:
return [[x] + suffix for i, x in enumerate(lst)
for suffix in comb(m - 1, lst[i + 1:])]

View file

@ -0,0 +1,2 @@
>>> comb(3, range(5))
[[0, 1, 2], [0, 1, 3], [0, 1, 4], [0, 2, 3], [0, 2, 4], [0, 3, 4], [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]

View file

@ -0,0 +1,6 @@
def comb(m, s):
if m == 0: return [[]]
if s == []: return []
return [s[:1] + a for a in comb(m-1, s[1:])] + comb(m, s[1:])
print comb(3, range(5))

View file

@ -0,0 +1 @@
print(combn(0:4, 3))

View file

@ -0,0 +1,2 @@
r <- combn(0:4, 3)
for(i in 1:choose(5,3)) print(r[,i])

View file

@ -0,0 +1,27 @@
/*REXX program shows combination sets for X things taken Y at a time*/
@abc='abcdefghijklmnopqrstuvwxyz'; @abcU=@abc; upper @abcU; @digs=123456789
parse arg x y symbols .; if x=='' | x==',' then x=5
if y=='' | y==',' then y=3
if symbols=='' then symbols=@digs||@abc||@abcU /*symbol table string.*/
say "────────────" x 'things taken' y "at a time:"
say "────────────" combN(x,y) 'combinations.'
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────COMBN subroutine────────────────────*/
combN: procedure expose symbols; parse arg x,y; base=x+1; bbase=base-y
!.=0; do i=1 for y; !.i=i
end /*i*/
do j=1; L=; do d=1 for y
L=L word(substr(symbols,!.d,1) !.d,1)
end /*d*/
say L
!.y=!.y+1; if !.y==base then if .combUp(y-1) then leave
end /*j*/
return j
.combUp: procedure expose !. y bbase; parse arg d; if d==0 then return 1
p=!.d; do u=d to y; !.u=p+1
if !.u==bbase+u then return .combUp(u-1)
p=!.u
end /*u*/
return 0

View file

@ -0,0 +1,5 @@
def comb(m, n)
(0...n).to_a.combination(m).to_a
end
comb(3, 5) # => [[0, 1, 2], [0, 1, 3], [0, 1, 4], [0, 2, 3], [0, 2, 4], [0, 3, 4], [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]

View file

@ -0,0 +1,8 @@
implicit def toComb(m: Int) = new AnyRef {
def comb(n: Int) = recurse(m, List.range(0, n))
private def recurse(m: Int, l: List[Int]): List[List[Int]] = (m, l) match {
case (0, _) => List(Nil)
case (_, Nil) => Nil
case _ => (recurse(m - 1, l.tail) map (l.head :: _)) ::: recurse(m, l.tail)
}
}

View file

@ -0,0 +1,8 @@
(define (comb m lst)
(cond ((= m 0) '(()))
((null? lst) '())
(else (append (map (lambda (y) (cons (car lst) y))
(comb (- m 1) (cdr lst)))
(comb m (cdr lst))))))
(comb 3 '(0 1 2 3 4))

View file

@ -0,0 +1,15 @@
(0 to: 4)
combinations: 3 atATimeDo: [ :x |
':-)' logCr: x ].
"output on Transcript:
#(0 1 2)
#(0 1 3)
#(0 1 4)
#(0 2 3)
#(0 2 4)
#(0 3 4)
#(1 2 3)
#(1 2 4)
#(1 3 4)
#(2 3 4)"

View file

@ -0,0 +1,21 @@
proc comb {m n} {
set set [list]
for {set i 0} {$i < $n} {incr i} {lappend set $i}
return [combinations $set $m]
}
proc combinations {list size} {
if {$size == 0} {
return [list [list]]
}
set retval {}
for {set i 0} {($i + $size) <= [llength $list]} {incr i} {
set firstElement [lindex $list $i]
set remainingElements [lrange $list [expr {$i + 1}] end]
foreach subset [combinations $remainingElements [expr {$size - 1}]] {
lappend retval [linsert $subset 0 $firstElement]
}
}
return $retval
}
comb 3 5 ;# ==> {0 1 2} {0 1 3} {0 1 4} {0 2 3} {0 2 4} {0 3 4} {1 2 3} {1 2 4} {1 3 4} {2 3 4}