Permutation test: Difference between revisions

m
m (→‎{{header|REXX}}: added/changed whitespace and comments.)
m (→‎{{header|Wren}}: Minor tidy)
 
(35 intermediate revisions by 19 users not shown)
Line 9:
was measured and reported in this table.
 
:::::::{| style="text-align: left; width: 5025%;" border="4" cellpadding="2" cellspacing="2"
|+ Table of experimental results
|- style="background-color: rgb(255, 204, 255);"
Line 44:
* Report the percentage of alternative groupings for which the difference in means is less or equal to the actual experimentally observed difference in means, and the percentage for which it is greater.
* Note that they should sum to 100%.
 
 
Extremely dissimilar values are evidence of an effect not entirely due
Line 51 ⟶ 52:
that's easier than loading them at run time. Test your solution on the
data given above.
<br><br>
 
=={{header|11l}}==
{{trans|Kotlin}}
 
<syntaxhighlight lang="11l">V data = [85, 88, 75, 66, 25, 29, 83, 39, 97,
68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
 
F pick(at, remain, accu, treat)
I remain == 0
R I accu > treat {1} E 0
R pick(at - 1, remain - 1, accu + :data[at - 1], treat) +
(I at > remain {pick(at - 1, remain, accu, treat)} E 0)
 
V treat = 0
V total = 1.0
L(i) 0..8
treat += data[i]
L(i) (19..11).step(-1)
total *= i
L(i) (9..1).step(-1)
total /= i
 
V gt = pick(19, 9, 0, treat)
V le = Int(total - gt)
 
print(‘<= : #.6% #.’.format(100 * le / total, le))
print(‘ > : #.6% #.’.format(100 * gt / total, gt))</syntaxhighlight>
 
{{out}}
<pre>
<= : 87.197168% 80551
> : 12.802832% 11827
</pre>
 
=={{header|Ada}}==
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO; with Iterate_Subsets;
 
procedure Permutation_Test is
Line 115 ⟶ 150:
New_Line;
end;
end Permutation_Test;</langsyntaxhighlight>
 
This solution uses an auxiliary package Iterate_Subsets. Here is the Spec:
<langsyntaxhighlight Adalang="ada">generic
Subset_Size, More_Elements: Positive;
package Iterate_Subsets is
Line 134 ⟶ 169:
 
end Iterate_Subsets;
</syntaxhighlight>
</lang>
 
And here is the implementation:
 
<langsyntaxhighlight Adalang="ada">package body Iterate_Subsets is
 
function First return Subset is
Line 171 ⟶ 206:
end Last;
 
end Iterate_Subsets;</langsyntaxhighlight>
 
{{out}}
Line 178 ⟶ 213:
</pre>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f PERMUTATION_TEST.AWK
# converted from C
BEGIN {
# "treatment..................control......................"
n = split("85,88,75,66,25,29,83,39,97,68,41,10,49,16,65,32,92,28,98",data,",")
for (i=1; i<=n; i++) { # make AWK array look like a C array
data[i-1] = data[i]
}
delete data[n]
total = 1
for (i=0; i<9; i++) { treat += data[i] }
for (i=19; i>10; i--) { total *= i }
for (i=9; i>0; i--) { total /= i }
gt = pick(19,9,0,treat)
le = total - gt
printf("<= : %9.6f%% %6d\n",100*le/total,le)
printf(" > : %9.6f%% %6d\n",100*gt/total,gt)
exit(0)
}
function pick(at,remain,accu,treat) {
if (!remain) {
return (accu > treat) ? 1 : 0
}
return pick(at-1,remain-1,accu+data[at-1],treat) + ( (at > remain) ? pick(at-1,remain,accu,treat) : 0 )
}
</syntaxhighlight>
{{out}}
<pre>
<= : 87.197168% 80551
> : 12.802832% 11827
</pre>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> ntreated% = 9
nplacebo% = 10
DIM results%(ntreated% + nplacebo% - 1)
Line 218 ⟶ 286:
N% = (N% + (N% >>> 4)) AND &0F0F0F0F
N% += N% >>> 8 : N% += N% >>> 16
= N% AND &7F</langsyntaxhighlight>
{{out}}
<pre>
Line 226 ⟶ 294:
 
=={{header|C}}==
<langsyntaxhighlight Clang="c">#include <stdio.h>
 
int data[] = { 85, 88, 75, 66, 25, 29, 83, 39, 97,
Line 254 ⟶ 322:
100 * le / total, le, 100 * gt / total, gt);
return 0;
}</langsyntaxhighlight>
Output:<syntaxhighlight lang="text"><= : 87.197168% 80551
> : 12.802832% 11827</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
{{trans|Java}}
<syntaxhighlight lang="cs">using System;
using System.Collections.Generic;
 
namespace PermutationTest {
class Program {
static readonly List<int> DATA = new List<int>{
85, 88, 75, 66, 25, 29, 83, 39, 97,
68, 41, 10, 49, 16, 65, 32, 92, 28, 98
};
 
static int Pick(int at, int remain, int accu, int treat) {
if (remain == 0) {
return (accu > treat) ? 1 : 0;
}
return Pick(at - 1, remain - 1, accu + DATA[at - 1], treat)
+ ((at > remain) ? Pick(at - 1, remain, accu, treat) : 0);
}
 
static void Main() {
int treat = 0;
double total = 1.0;
for (int i = 0; i <= 8; i++) {
treat += DATA[i];
}
for (int i = 19; i >= 11; i--) {
total *= i;
}
for (int i = 9; i >= 1; --i) {
total /= i;
}
int gt = Pick(19, 9, 0, treat);
int le = (int) (total - gt);
Console.WriteLine("<= {0}% {1}", 100.0 * le / total, le);
Console.WriteLine(" > {0}% {1}", 100.0 * gt / total, gt);
}
}
}</syntaxhighlight>
{{out}}
<pre>&lt;= 87.1971681569205% 80551
&gt; 12.8028318430795% 11827</pre>
 
=={{header|C++}}==
This is a translaion of C
<syntaxhighlight lang="cpp">#include<iostream>
#include<vector>
#include<numeric>
#include<functional>
 
class
{
public:
int64_t operator()(int n, int k){ return partial_factorial(n, k) / factorial(n - k);}
private:
int64_t partial_factorial(int from, int to) { return from == to ? 1 : from * partial_factorial(from - 1, to); }
int64_t factorial(int n) { return n == 0 ? 1 : n * factorial(n - 1);}
}combinations;
 
int main()
{
static constexpr int treatment = 9;
const std::vector<int> data{ 85, 88, 75, 66, 25, 29, 83, 39, 97,
68, 41, 10, 49, 16, 65, 32, 92, 28, 98 };
 
int treated = std::accumulate(data.begin(), data.begin() + treatment, 0);
 
std::function<int (int, int, int)> pick;
pick = [&](int n, int from, int accumulated)
{
if(n == 0)
return accumulated > treated ? 1 : 0;
else
return pick(n - 1, from - 1, accumulated + data[from - 1]) +
(from > n ? pick(n, from - 1, accumulated) : 0);
};
 
int total = combinations(data.size(), treatment);
int greater = pick(treatment, data.size(), 0);
int lesser = total - greater;
 
std::cout << "<= : " << 100.0 * lesser / total << "% " << lesser << std::endl
<< " > : " << 100.0 * greater / total << "% " << greater << std::endl;
}</syntaxhighlight>
Output:<syntaxhighlight lang="text"><= : 87.197168% 80551
> : 12.802832% 11827</syntaxhighlight>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun perm-test (s1 s2)
(let ((more 0) (leq 0)
(all-data (append s1 s2))
Line 282 ⟶ 437:
(format t "<=: ~a ~6f%~% >: ~a ~6f%~%"
x (* 100e0 (/ x s))
y (* 100e0 (/ y s))))</langsyntaxhighlight>output<syntaxhighlight lang="text"><=: 80551 87.197%
>: 11827 12.803%</langsyntaxhighlight>
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.array, combinations3;
 
auto permutationTest(T)(in T[] a, in T[] b) pure nothrow @safe {
Line 300 ⟶ 455:
immutable under = permutationTest(treatmentGroup, controlGroup);
writefln("Under =%6.2f%%\nOver =%6.2f%%", under, 100.0 - under);
}</langsyntaxhighlight>
{{out}}
<pre>Under = 87.20%
Line 307 ⟶ 462:
Alternative version:
{{trans|C}}
<langsyntaxhighlight lang="d">void main() @safe {
import std.stdio, std.algorithm, std.range;
 
Line 330 ⟶ 485:
writefln(" > : %2.2f%% %d", 100.0 * gt / t, gt);
writefln("<= : %2.2f%% %d", 100.0 * le / t, le);
}</langsyntaxhighlight>
{{out}}
<pre> > : 12.80% 11827
<= : 87.20% 80551</pre>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{Trans|Go}}
<syntaxhighlight lang="delphi">
program Permutation_test;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils;
 
procedure Comb(n, m: Integer; emit: TProc<TArray<Integer>>);
var
s: TArray<Integer>;
last: Integer;
 
procedure rc(i, next: Integer);
begin
for var j := next to n - 1 do
begin
s[i] := j;
if i = last then
emit(s)
else
rc(i + 1, j + 1);
end;
end;
 
begin
SetLength(s, m);
last := m - 1;
rc(0, 0);
end;
 
begin
var tr: TArray<Integer> := [85, 88, 75, 66, 25, 29, 83, 39, 97];
var ct: TArray<Integer> := [68, 41, 10, 49, 16, 65, 32, 92, 28, 98];
 
// collect all results in a single list
var all: TArray<Integer> := concat(tr, ct);
 
// compute sum of all data, useful as intermediate result
var sumAll := 0;
for var r in all do
inc(sumAll, r);
 
// closure for computing scaled difference.
// compute results scaled by len(tr)*len(ct).
// this allows all math to be done in integers.
var sd :=
function(trc: TArray<Integer>): Integer
begin
var sumTr := 0;
for var x in trc do
inc(sumTr, all[x]);
result := sumTr * length(ct) - (sumAll - sumTr) * length(tr);
end;
 
// compute observed difference, as an intermediate result
var a: TArray<Integer>;
SetLength(a, length(tr));
for var i := 0 to High(a) do
a[i] := i;
 
var sdObs := sd(a);
 
// iterate over all combinations. for each, compute (scaled)
// difference and tally whether leq or gt observed difference.
var nLe, nGt: Integer;
 
comb(length(all), length(tr),
procedure(c: TArray<Integer>)
begin
if sd(c) > sdObs then
inc(nGt)
else
inc(nle);
end);
 
// print results as percentage
var pc := 100 / (nLe + nGt);
writeln(format('differences <= observed: %f%%', [nle * pc]));
writeln(format('differences > observed: %f%%', [ngt * pc]));
 
{$IFNDEF UNIX} readln; {$ENDIF}
end.</syntaxhighlight>
 
=={{header|Elixir}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="elixir">defmodule Permutation do
def statistic(ab, a) do
sumab = Enum.sum(ab)
Line 364 ⟶ 605:
controlGroup = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
under = Permutation.test(treatmentGroup, controlGroup)
:io.fwrite "under = ~.2f%, over = ~.2f%~n", [under, 100-under]</langsyntaxhighlight>
 
{{out}}
Line 372 ⟶ 613:
 
=={{header|GAP}}==
<langsyntaxhighlight lang="gap">a := [85, 88, 75, 66, 25, 29, 83, 39, 97];
b := [68, 41, 10, 49, 16, 65, 32, 92, 28, 98];
 
Line 422 ⟶ 663:
# in order, % less or greater than original diff
PermTest(a, b);
[ "87.197", "12.802" ]</langsyntaxhighlight>
 
 
=={{header|FreeBASIC}}==
{{trans|Phix}}
<syntaxhighlight lang="freebasic">
Dim Shared datos(18) As Integer => {85, 88, 75, 66, 25, 29, 83, 39, 97,_
68, 41, 10, 49, 16, 65, 32, 92, 28, 98}
 
Function pick(at As Integer, remain As Integer, accu As Integer, treat As Integer) As Integer
If remain = 0 Then
If accu > treat Then Return 1 Else Return 0
End If
Dim a As Integer
If at > remain Then a = pick(at-1, remain, accu, treat) Else a = 0
Return pick(at-1, remain-1, accu+datos(at), treat) + a
End Function
 
Dim As Integer treat = 0, le, gt, total = 1, i
 
For i = 1 To 9
treat += datos(i)
Next i
For i = 19 To 11 Step -1
total *= i
Next i
For i = 9 To 1 Step -1
total /= i
Next i
 
gt = pick(19, 9, 0, treat)
le = total - gt
 
Print Using "<= : ##.######% #####"; 100*le/total; le
Print Using " > : ##.######% #####"; 100*gt/total; gt
Sleep
</syntaxhighlight>
{{out}}
<pre>
<= : 92.076035% 85058
> : 7.923965% 7320
</pre>
 
 
=={{header|Go}}==
A version doing all math in integers until computing final percentages.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 497 ⟶ 781:
}
rc(0, 0)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 505 ⟶ 789:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">binomial n m = (f !! n) `div` (f !! m) `div` (f !! (n - m))
where f = scanl (*) 1 [1..]
 
Line 525 ⟶ 809:
[68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
in do putStr "> : "; print r
putStr "<=: "; print $ 100 - r</langsyntaxhighlight>
{{out}}
<pre>
Line 533 ⟶ 817:
 
Somewhat faster, this goes from top down:
<langsyntaxhighlight lang="haskell">binomial n m = (f !! n) `div` (f !! m) `div` (f !! (n - m))
where f = scanl (*) 1 [1..]
 
Line 551 ⟶ 835:
(a, b) = perms [85, 88, 75, 66, 25, 29, 83, 39, 97]
[68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
lt = (fromIntegral a) / (fromIntegral b) * 100</langsyntaxhighlight>
 
In cases where the sample data are a large number of relatively small positive integers, counting number of partial sums is a lot faster:
<langsyntaxhighlight lang="haskell">combs maxsum len x = foldl f [(0,0,1)] x where
f a n = merge a (map (addNum n) $ filter (\(l,_,_) -> l < len) a)
addNum n (a,s,c)
Line 579 ⟶ 863:
-- how many combinations are less than current sum
main = print$ permtest [85, 88, 75, 66, 25, 29, 83, 39, 97]
[68, 41, 10, 49, 16, 65, 32, 92, 28, 98]</langsyntaxhighlight>
 
=={{header|J}}==
<langsyntaxhighlight lang="j">require'stats'
trmt=: 0.85 0.88 0.75 0.66 0.25 0.29 0.83 0.39 0.97
ctrl=: 0.68 0.41 0.1 0.49 0.16 0.65 0.32 0.92 0.28 0.98
Line 589 ⟶ 873:
all=: trmt(#@[ ({. difm }.) |:@([ (comb ~.@,"1 i.@])&# ,) { ,) ctrl
smoutput 'under: ','%',~":100*mean all <: result
smoutput 'over: ','%',~":100*mean all > result</langsyntaxhighlight>
 
Result:
<syntaxhighlight lang="text">under: 87.1972%
over: 12.8028%</langsyntaxhighlight>
 
=={{header|Java}}==
{{trans|Kotlin}}
<syntaxhighlight lang="java">public class PermutationTest {
private static final int[] data = new int[]{
85, 88, 75, 66, 25, 29, 83, 39, 97,
68, 41, 10, 49, 16, 65, 32, 92, 28, 98
};
 
private static int pick(int at, int remain, int accu, int treat) {
if (remain == 0) return (accu > treat) ? 1 : 0;
return pick(at - 1, remain - 1, accu + data[at - 1], treat)
+ ((at > remain) ? pick(at - 1, remain, accu, treat) : 0);
}
 
public static void main(String[] args) {
int treat = 0;
double total = 1.0;
for (int i = 0; i <= 8; ++i) {
treat += data[i];
}
for (int i = 19; i >= 11; --i) {
total *= i;
}
for (int i = 9; i >= 1; --i) {
total /= i;
}
int gt = pick(19, 9, 0, treat);
int le = (int) (total - gt);
System.out.printf("<= : %f%% %d\n", 100.0 * le / total, le);
System.out.printf(" > : %f%% %d\n", 100.0 * gt / total, gt);
}
}</syntaxhighlight>
{{out}}
<pre><= : 87.197168% 80551
> : 12.802832% 11827</pre>
 
=={{header|jq}}==
{{works with|jq|1.4}}
'''Part 1: Combinations'''
<langsyntaxhighlight lang="jq"># combination(r) generates a stream of combinations of r items from the input array.
def combination(r):
if r > length or r < 0 then empty
Line 604 ⟶ 925:
( .[1:]|combination(r))
end;
</syntaxhighlight>
</lang>
'''Part 2: Permutation Test'''
<langsyntaxhighlight lang="jq"># a and b should be arrays:
def permutationTest(a; b):
 
Line 631 ⟶ 952:
| .[1] += 1 )
| .[0] * 100.0 / .[1] # under/count
;</langsyntaxhighlight>
'''Example:'''
<langsyntaxhighlight lang="jq">def treatmentGroup: [85, 88, 75, 66, 25, 29, 83, 39, 97];
def controlGroup: [68, 41, 10, 49, 16, 65, 32, 92, 28, 98];
 
permutationTest(treatmentGroup; controlGroup) as $under
| "% under=\($under)", "% over=\(100 - $under)"</langsyntaxhighlight>
{{out}}
$ jq -n -r -f permutation_test.jq
Line 644 ⟶ 965:
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
The primary function for this solution is <tt>perm_sig_test</tt>, which relies on Julia's <tt>combinations</tt> built-in function to provide all of the possible study arm assignments. <tt>bifurcate</tt> splits the pooled results into "treatment" and "control" groups according to the indices provided by <tt>combinations</tt>.
The primary function for this solution is <tt>permutation_test</tt>, which relies on Julia's <tt>combinations</tt> (from <tt>Combinatorics</tt> module) function to provide all of the possible study arm assignments. <tt>bifurcate</tt> splits the pooled results into "treatment" and "control" groups according to the indices provided by <tt>combinations</tt>.
 
'''Functions'''
<syntaxhighlight lang="julia">using Combinatorics
<lang Julia>
delta_mean{T<:Real}(a::Array{T,1}, b::Array{T,1}) = mean(a) - mean(b)
 
meandiff(a::Vector{T}, b::Vector{T}) where T <: Real = mean(a) - mean(b)
function bifurcate{T<:Integer}(a::AbstractVector, sel::Array{T,1})
 
x = a[sel]
function bifurcate(a::AbstractVector, sel::Vector{T}) where T <: Integer
asel = trues(length(a))
x = a[sel]
asel = trues(length(a))
asel[sel] = false
y = a[asel]
return (x, y)
end
 
function perm_sig_test{T<:Real}permutation_test(treattreated::ArrayVector{T,1}, control::ArrayVector{T,1}) where T <: Real
base_effecteffect0 = delta_meanmeandiff(treattreated, control)
pool = [treatvcat(treated, control])
tlen = length(treattreated)
plen = length(pool)
better = worse = 0
for subset in combinations(1:plen, tlen)
worse = 0
for s in combinations t, c = bifurcate(1:plenpool, tlensubset)
(t,if c)effect0 =< bifurcatemeandiff(poolt, sc)
if base_effect < delta_mean(t, c)
better += 1
else
Line 673 ⟶ 995:
end
end
return (better, worse)
end</syntaxhighlight>
end
</lang>
 
'''Main'''
<syntaxhighlight lang="julia">const treated = [85, 88, 75, 66, 25, 29, 83, 39, 97]
<lang Julia>
treatconst control = [8568, 41, 8810, 7549, 6616, 2565, 2932, 8392, 3928, 9798]
control = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
 
(better, worse) = perm_sig_testpermutation_test(treattreated, control)
 
tot = better + worse
 
println("Permutation test using the following data:")
println("Treated: ", treattreated)
println("Control: ", control)
println("\nThere are $tot different permuted groups of these data.")
 
@printf("%8d, %5.2f%% showed better than actual results.\n", better, 100 * better / tot)
println()
print(@sprintf("%8d, %5.2f%% showed equalivalent or worse results.", worse, 100 * worse / tot))</syntaxhighlight>
println("There are ", tot, " different permuted groups of these data.")
print(@sprintf("%8d, %5.2f%% ", better, 100better/tot))
println("showed better than actual results.")
print(@sprintf("%8d, %5.2f%% ", worse, 100worse/tot))
println("showed equalivalent or worse results.")
</lang>
 
{{out}}
<pre>Permutation test using the following data:
<pre>
Treated: [85, 88, 75, 66, 25, 29, 83, 39, 97]
Permutation test using the following data:
TreatedControl: [8568,88 41,75 10,66 49,25 16,29 65,83 32,39 92,97 28, 98]
Control: [68,41,10,49,16,65,32,92,28,98]
 
There are 92378 different permuted groups of these data.
11827, 12.80% showed better than actual results.
80551, 87.20% showed equalivalent or worse results.</pre>
 
=={{header|Kotlin}}==
{{trans|C}}
<syntaxhighlight lang="scala">// version 1.1.2
 
val data = intArrayOf(
85, 88, 75, 66, 25, 29, 83, 39, 97,
68, 41, 10, 49, 16, 65, 32, 92, 28, 98
)
 
fun pick(at: Int, remain: Int, accu: Int, treat: Int): Int {
if (remain == 0) return if (accu > treat) 1 else 0
return pick(at - 1, remain - 1, accu + data[at - 1], treat) +
if (at > remain) pick(at - 1, remain, accu, treat) else 0
}
 
fun main(args: Array<String>) {
var treat = 0
var total = 1.0
for (i in 0..8) treat += data[i]
for (i in 19 downTo 11) total *= i
for (i in 9 downTo 1) total /= i
val gt = pick(19, 9, 0, treat)
val le = (total - gt).toInt()
System.out.printf("<= : %f%% %d\n", 100.0 * le / total, le)
System.out.printf(" > : %f%% %d\n", 100.0 * gt / total, gt)
}</syntaxhighlight>
 
{{out}}
<pre>
<= : 87.197168% 80551
> : 12.802832% 11827
</pre>
 
=={{header|MathematicaM2000 Interpreter}}==
{{trans|C}}
<lang mathematica>"<=: " <> ToString[#1] <> " " <> ToString[100. #1/#2] <> "%\n >: " <>
<syntaxhighlight lang="m2000 interpreter">
Module Checkit {
Global data(), treat=0
data()=(85, 88, 75, 66, 25, 29, 83, 39, 97,68, 41, 10, 49, 16, 65, 32, 92, 28, 98)
Function pick(at, remain, accu) {
If remain Else =If(accu>treat->1,0):Exit
=pick(at-1,remain-1,accu+data(at-1))+If(at>remain->pick(at-1, remain, accu),0)
}
total=1
For i=0 to 8 {treat+=data(i)}
For i=19 to 11 {total*=i}
For i=9 to 1 {total/=i}
gt=pick(19,9,0)
le=total-gt
Print Format$("<= : {0:1}% {1}", 100*le/total, le)
Print Format$(" > : {0:1}% {1}", 100*gt/total, gt)
}
Checkit
</syntaxhighlight>
{{out}}
<pre><= : 87.2% 80551
> : 12.8% 11827
</pre>
 
Slower version, using a lambda function with a series of inner lambda functions to return each combination at a time.
 
<syntaxhighlight lang="m2000 interpreter">
Module CheckThis {
Function CombinationsStep (a, nn) {
c1=lambda (&f, &a) ->{=car(a) : a=cdr(a) : f=len(a)=0}
m=len(a)
c=c1
n=m-nn+1
p=2
while m>n {
c1=lambda c2=c,n=p, z=(,) (&f, &m) ->{if len(z)=0 then z=cdr(m)
=cons(car(m),c2(&f, &z)):if f then z=(,) : m=cdr(m) : f=len(m)+len(z)<n
}
c=c1
p++
m--
}
=lambda c, a (&f) ->c(&f, &a)
}
treated=(85, 88, 75, 66, 25, 29, 83, 39, 97)
placebo=(68, 41, 10, 49, 16, 65, 32, 92, 28, 98)
treat=0
m=each(treated): while m {treat+=array(m)}
total=1
for i=len(placebo)+1 to len(placebo) +len(treated):total*=i:next i
for i=len(placebo)-1 to 1: total/=i:next i
d=total div 10**int(log(total))
k=false
StepA=CombinationsStep(cons(treated, placebo),len(treated))
counter=0
gt=0
While not k {
comb=StepA(&k)
accu=0
m=each(comb)
while m {accu+=array(m)}
gt+=if(accu>treat->1,0)
counter++
if counter mod d=0 then Print over str$(counter/total," #0.0%"): Refresh 1000
}
print over str$(counter/total," #0.0%")
print
lt=total-gt
print Format$("less or equal={0:1}%, greater={1:1}%, total={2}",lt/total*100, gt/total*100, total)
}
CheckThis
</syntaxhighlight>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">"<=: " <> ToString[#1] <> " " <> ToString[100. #1/#2] <> "%\n >: " <>
ToString[#2 - #1] <> " " <> ToString[100. (1 - #1/#2)] <> "%" &[
Count[Total /@ Subsets[Join[#1, #2], {Length@#1}],
n_ /; n <= Total@#1],
Binomial[Length@#1 + Length@#2, Length@#1]] &[{85, 88, 75, 66, 25,
29, 83, 39, 97}, {68, 41, 10, 49, 16, 65, 32, 92, 28, 98}]</langsyntaxhighlight>
{{out}}
<pre><=: 80551 87.1972%
>: 11827 12.8028%</pre>
 
=={{header|PicoLispNim}}==
{{trans|C}}
<lang PicoLisp>(load "@lib/simul.l") # For 'subsets'
<syntaxhighlight lang="nim">import strformat
 
const data = [85, 88, 75, 66, 25,
(scl 2)
29, 83, 39, 97, 68,
41, 10, 49, 16, 65,
32, 92, 28, 98]
 
func pick(at, remain, accu, treat: int): int =
(de _stat (A)
if remain == 0:
(let (LenA (length A) SumA (apply + A))
return if accu > treat: 1 else: 0
(-
return pick(at - 1, remain - 1, accu + data[at - 1], treat) +
(*/ SumA LenA)
(if at > remain: pick(*/at (- SumAB1, SumA)remain, (- LenABaccu, LenA)treat) ) )else: 0)
 
(de permutationTest (A B)
(let
(AB (append A B)
SumAB (apply + AB)
LenAB (length AB)
Tobs (_stat A)
Count 0 )
(*/
(sum
'((Perm)
(inc 'Count)
(and (>= Tobs (_stat Perm)) 1) )
(subsets (length A) AB) )
100.0
Count ) ) )
 
var treat = 0
(setq
var le, gt = 0
*TreatmentGroup (0.85 0.88 0.75 0.66 0.25 0.29 0.83 0.39 0.97)
var total = 1.0
*ControlGroup (0.68 0.41 0.10 0.49 0.16 0.65 0.32 0.92 0.28 0.98) )
for i in countup(0, 8):
treat += data[i]
for i in countdown(19, 11):
total *= float(i)
for i in countdown(9, 1):
total /= float(i)
 
gt = pick(19, 9, 0, treat)
(let N (permutationTest *TreatmentGroup *ControlGroup)
le = int(total - float(gt))
(prinl "under = " (round N) "%, over = " (round (- 100.0 N)) "%") )</lang>
echo fmt"<= : {100.0 * float(le) / total:.6f}% {le}"
echo fmt" > : {100.0 * float(gt) / total:.6f}% {gt}"</syntaxhighlight>
{{out}}
<pre>
<pre>under = 87.85%, over = 12.15%</pre>
<= : 87.197168% 80551
> : 12.802832% 11827
</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">#!/usr/bin/perl
use warnings;
use strict;
Line 840 ⟶ 1,261:
92
28
98</langsyntaxhighlight>
{{out}}
equal 313 0.339%
Line 846 ⟶ 1,267:
greater 11827 12.803%
 
=={{header|Perl 6Phix}}==
{{Trans|C}}
{{works with|rakudo|2015-09-30}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">constant</span> <span style="color: #000000;">data</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">85</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">88</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">75</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">66</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">25</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">29</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">83</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">39</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">97</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">68</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">41</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">49</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">16</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">65</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">32</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">92</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">28</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">98</span> <span style="color: #0000FF;">}</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">pick</span><span style="color: #0000FF;">(</span><span style="color: #004080;">int</span> <span style="color: #000000;">at</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">int</span> <span style="color: #000000;">remain</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">int</span> <span style="color: #000000;">accu</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">int</span> <span style="color: #000000;">treat</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">remain</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">accu</span><span style="color: #0000FF;">></span><span style="color: #000000;">treat</span><span style="color: #0000FF;">?</span><span style="color: #000000;">1</span><span style="color: #0000FF;">:</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">pick</span><span style="color: #0000FF;">(</span><span style="color: #000000;">at</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">remain</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">accu</span><span style="color: #0000FF;">+</span><span style="color: #000000;">data</span><span style="color: #0000FF;">[</span><span style="color: #000000;">at</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">treat</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span>
<span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">at</span><span style="color: #0000FF;">></span><span style="color: #000000;">remain</span><span style="color: #0000FF;">?</span><span style="color: #000000;">pick</span><span style="color: #0000FF;">(</span><span style="color: #000000;">at</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">remain</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">accu</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">treat</span><span style="color: #0000FF;">):</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">int</span> <span style="color: #000000;">treat</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">le</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">gt</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">total</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">;</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> <span style="color: #000000;">treat</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">data</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">19</span> <span style="color: #008080;">to</span> <span style="color: #000000;">11</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> <span style="color: #000000;">total</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">i</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">9</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> <span style="color: #000000;">total</span> <span style="color: #0000FF;">/=</span> <span style="color: #000000;">i</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">gt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pick</span><span style="color: #0000FF;">(</span><span style="color: #000000;">19</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">treat</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">le</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">total</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">gt</span><span style="color: #0000FF;">;</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"&lt;= : %f%% %d\n &gt; : %f%% %d\n"</span><span style="color: #0000FF;">,</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">100</span><span style="color: #0000FF;">*</span><span style="color: #000000;">le</span><span style="color: #0000FF;">/</span><span style="color: #000000;">total</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">le</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">100</span><span style="color: #0000FF;">*</span><span style="color: #000000;">gt</span><span style="color: #0000FF;">/</span><span style="color: #000000;">total</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">gt</span><span style="color: #0000FF;">})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
<= : 87.197168% 80551
> : 12.802832% 11827
</pre>
 
=={{header|PicoLisp}}==
<lang perl6>sub stats ( @test, @all ) {
<syntaxhighlight lang="picolisp">(load "@lib/simul.l") # For 'subsets'
(([+] @test) / +@test ) - ([+] flat @all, (@test X* -1)) / (@all - @test)
}
 
(scl 2)
 
(de _stat (A)
my int @treated = <85 88 75 66 25 29 83 39 97>;
(let (LenA (length A) SumA (apply + A))
my int @control = <68 41 10 49 16 65 32 92 28 98>;
(-
my int @all = flat @treated, @control;
(*/ SumA LenA)
(*/ (- SumAB SumA) (- LenAB LenA)) ) ) )
 
(de permutationTest (A B)
my $base = stats( @treated, @all );
(let
(AB (append A B)
SumAB (apply + AB)
LenAB (length AB)
Tobs (_stat A)
Count 0 )
(*/
(sum
'((Perm)
(inc 'Count)
(and (>= Tobs (_stat Perm)) 1) )
(subsets (length A) AB) )
100.0
Count ) ) )
 
(setq
my @trials = 0, 0, 0;
*TreatmentGroup (0.85 0.88 0.75 0.66 0.25 0.29 0.83 0.39 0.97)
 
*ControlGroup (0.68 0.41 0.10 0.49 0.16 0.65 0.32 0.92 0.28 0.98) )
@trials[ 1 + ( stats( $_, @all ) <=> $base ) ]++ for @all.combinations(+@treated);
 
say 'Counts: <, =, > ', @trials;
say 'Less than : %', 100 * @trials[0] / [+] @trials;
say 'Equal to : %', 100 * @trials[1] / [+] @trials;
say 'Greater than : %', 100 * @trials[2] / [+] @trials;
say 'Less or Equal: %', 100 * ( [+] @trials[0,1] ) / [+] @trials;</lang>
 
(let N (permutationTest *TreatmentGroup *ControlGroup)
(prinl "under = " (round N) "%, over = " (round (- 100.0 N)) "%") )</syntaxhighlight>
{{out}}
<pre>under = 87.85%, over = 12.15%</pre>
<pre>
Counts: <, =, > 80238 313 11827
Less than : %86.858343
Equal to : %0.338825
Greater than : %12.802832
Less or Equal: %87.197168
</pre>
 
=={{header|PureBasic}}==
Line 890 ⟶ 1,344:
the treatment group or the control group
 
<syntaxhighlight lang="purebasic">
<lang PureBasic>
 
Define.f meanTreated,meanControl,diffInMeans
Line 982 ⟶ 1,436:
Debug StrF(100*diffLessOrEqual/TotalComBinations,2)+" "+Str(diffLessOrEqual)
Debug StrF(100*diffGreater /TotalComBinations,2)+" "+Str(diffGreater)
</syntaxhighlight>
</lang>
 
{{out}}
Line 989 ⟶ 1,443:
12.80 11827
</pre>
 
 
=={{header|Python}}==
{{trans|Tcl}}
<langsyntaxhighlight lang="python">from itertools import combinations as comb
 
def statistic(ab, a):
Line 1,012 ⟶ 1,465:
controlGroup = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
under = permutationTest(treatmentGroup, controlGroup)
print("under=%.2f%%, over=%.2f%%" % (under, 100. - under))</langsyntaxhighlight>
{{out}}
<pre>under=89.11%, over=10.89%</pre>
 
The above solution does a different thing than the other solutions. I'm not really sure why. If you want to do the same thing as the other solutions, then this is the solution:
<langsyntaxhighlight lang="python">from itertools import combinations as comb
 
def permutationTest(a, b):
Line 1,031 ⟶ 1,484:
controlGroup = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
under = permutationTest(treatmentGroup, controlGroup)
print("under=%.2f%%, over=%.2f%%" % (under, 100. - under))</langsyntaxhighlight>
{{out}}
<pre>under=87.20%, over=12.80%</pre>
 
=={{header|REXX}}==
This REXX program is modeled after the &nbsp; '''C''' &nbsp; version, with some generalizations and optimization added.
<lang rexx>/*REXX program performs a permutation test on N + M subjects (volunteers): */
/* ↑ ↑ */
/* │ │ */
/* │ └─────control population. */
/* └────────treatment population. */
n=9
data=85 88 75 66 25 29 83 39 97 68 41 10 49 16 65 32 92 28 98
w=words(data); m=w-n
say 'volunteer population given treatment:' right(n,length(w))
say ' control population given a placebo:' right(m,length(w))
say
say 'treatment population efficacy % (percentages):' subword(data,1,n)
say ' control population placebo % (percentages):' subword(data,n+1)
say
do v= 0 for w ; #.v=word(data,v+1) ; end
treat=0; do i= 0 to n-1 ; treat=treat+#.i ; end
tot=1; do j=19 to m+1 by -1 ; tot=tot*j ; end
do k= 9 to 1 by -1 ; tot=tot/k ; end
gt=picker(n+m, n, 0)
le=tot-gt
say "<= " format(100*le/tot,,3)'%' le /*display number with 3 decimal places.*/
say " > " format(100*gt/tot,,3)'%' gt /* " " " " " " */
exit /*stick a fork in it, we're all done. */
/*────────────────────────────────────────────────────────────────────────────*/
picker: procedure expose #. treat; parse arg it,rest,eff
if rest==0 then return eff>treat
if it>rest then q=picker(it-1, rest, eff)
else q=0
itP=it-1
return picker(itP, rest-1, eff+#.itP) + q</lang>
'''output''' &nbsp; using the default input:
<pre>
volunteer population given treatment: 9
control population given a placebo: 10
 
treatment population efficacy % (percentages): 85 88 75 66 25 29 83 39 97
control population placebo % (percentages): 68 41 10 49 16 65 32 92 28 98
 
<= 87.197% 80551
> 12.803% 11827
</pre>
 
=={{header|R}}==
 
<langsyntaxhighlight lang="r">permutation.test <- function(treatment, control) {
perms <- combinations(length(treatment)+length(control),
length(treatment),
Line 1,088 ⟶ 1,497:
p <- mean(rowMeans(perms) <= mean(treatment))
c(under=p, over=(1-p))
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="r">> permutation.test(c(85, 88, 75, 66, 25, 29, 83, 39, 97),
+ c(68, 41, 10, 49, 16, 65, 32, 92, 28, 98))
under over
0.8719717 0.1280283 </langsyntaxhighlight>
 
 
=={{header|Racket}}==
{{trans|Common Lisp}}
 
<langsyntaxhighlight Racketlang="racket">#lang racket/base
 
(define-syntax-rule (inc! x)
Line 1,124 ⟶ 1,532:
more (real->decimal-string (* 100. (/ more sum)) 2)
leq (real->decimal-string (* 100. (/ leq sum)) 2))))
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,130 ⟶ 1,538:
<=: 80551 87.20%
>: 11827 12.80%
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
The use of <code>.race</code> to allow concurrent calculations means that multiple 'workers' will be updating <code>@trials</code> simultaneously. To avoid race conditions, the <code>⚛++</code> operator is used, which guarantees safe updates without the use of locks. That is turn requires declaring that array as being composed of <code>atomicint</code>.
{{works with|Rakudo|2018.09}}
 
<syntaxhighlight lang="raku" line>sub stats ( @test, @all ) {
([+] @test / +@test) - ([+] flat @all, (@test X* -1)) / @all - @test
}
 
my int @treated = <85 88 75 66 25 29 83 39 97>;
my int @control = <68 41 10 49 16 65 32 92 28 98>;
my int @all = flat @treated, @control;
 
my $base = stats( @treated, @all );
 
my atomicint @trials[3] = 0, 0, 0;
 
@all.combinations(+@treated).race.map: { @trials[ 1 + ( stats( $_, @all ) <=> $base ) ]⚛++ }
 
say 'Counts: <, =, > ', @trials;
say 'Less than : %', 100 * @trials[0] / [+] @trials;
say 'Equal to : %', 100 * @trials[1] / [+] @trials;
say 'Greater than : %', 100 * @trials[2] / [+] @trials;
say 'Less or Equal: %', 100 * ( [+] @trials[0,1] ) / [+] @trials;</syntaxhighlight>
 
{{out}}
<pre>
Counts: <, =, > 80238 313 11827
Less than : %86.858343
Equal to : %0.338825
Greater than : %12.802832
Less or Equal: %87.197168
</pre>
 
=={{header|REXX}}==
This REXX program is modeled after the &nbsp; '''C''' &nbsp; version, with some generalizations and optimization added.
<syntaxhighlight lang="rexx">/*REXX program performs a permutation test on N + M subjects (volunteers): */
/* ↑ ↑ */
/* │ │ */
/* │ └─────control population. */
/* └────────treatment population. */
n= 9 /*define the number of the control pop.*/
data= 85 88 75 66 25 29 83 39 97 68 41 10 49 16 65 32 92 28 98
w= words(data); m= w - n /*w: volunteers + control population*/
L= length(w) /*L: used to align some output numbers*/
say '# of volunteers & control population: ' w
say 'volunteer population given treatment: ' right(n, L)
say ' control population given a placebo: ' right(m, L)
say
say 'treatment population efficacy % (percentages): ' subword(data, 1, n)
say ' control population placebo % (percentages): ' subword(data, n+1 )
say
do v= 0 for w ; #.v= word(data, v+1) ; end
treat= 0; do i= 0 to n-1 ; treat= treat + #.i ; end
tot= 1; do j= w to m+1 by -1 ; tot= tot * j ; end
do k=w%2 to 1 by -1 ; tot= tot / k ; end
 
GT= picker(n+m, n, 0) /*compute the GT value from PICKER func*/
LE= tot - GT /* " " LE " via subtraction.*/
say "<= " format(100 * LE / tot, ,3)'%' LE /*display number with 3 decimal places.*/
say " > " format(100 * GT / tot, ,3)'%' GT /* " " " " " " */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
picker: procedure expose #. treat; parse arg it,rest,eff /*get the arguments.*/
if rest==0 then return eff > treat /*is REST = to zero?*/
if it>rest then q= picker(it-1, rest, eff) /*maybe recurse. */
else q= 0
itP= it - 1 /*set temporary var.*/
return picker(itP, rest - 1, eff + #.itP) + q /*recurse. */</syntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
<pre>
# of volunteers & control population: 19
volunteer population given treatment: 9
control population given a placebo: 10
 
treatment population efficacy % (percentages): 85 88 75 66 25 29 83 39 97
control population placebo % (percentages): 68 41 10 49 16 65 32 92 28 98
 
<= 87.197% 80551
> 12.803% 11827
</pre>
 
=={{header|Ruby}}==
{{trans|Python}}
<langsyntaxhighlight lang="ruby">def statistic(ab, a)
sumab, suma = ab.inject(:+).to_f, a.inject(:+).to_f
suma / a.size - (sumab - suma) / (ab.size - a.size)
Line 1,153 ⟶ 1,643:
controlGroup = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
under = permutationTest(treatmentGroup, controlGroup)
puts "under=%.2f%%, over=%.2f%%" % [under, 100 - under]</langsyntaxhighlight>
 
{{out}}
Line 1,159 ⟶ 1,649:
under=87.20%, over=12.80%
</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">
fn main() {
let treatment = vec![85, 88, 75, 66, 25, 29, 83, 39, 97];
let control = vec![68, 41, 10, 49, 16, 65, 32, 92, 28, 98];
 
let mut data_set = control.clone();
data_set.extend_from_slice(&treatment);
 
let greater = combinations(treatment.iter().sum(), treatment.len() as i64, &data_set) as f64;
let lesser = combinations(control.iter().sum(), control.len() as i64, &data_set) as f64;
let total = binomial(data_set.len() as i64, treatment.len() as i64) as f64;
 
println!("<= : {}%", (lesser / total * 100.0));
println!(" > : {}%", (greater / total * 100.0));
}
 
fn factorial(x: i64) -> i64 {
let mut product = 1;
for a in 1..(x + 1) {
product *= a;
}
product
}
 
fn binomial(n: i64, k: i64) -> i64 {
let numerator = factorial(n);
let denominator = factorial(k) * factorial(n - k);
numerator / denominator
}
 
fn combinations(total: i64, number: i64, data: &[i64]) -> i64 {
if total < 0 {
return binomial(data.len() as i64, number);
}
 
if number == 0 {
return 0;
}
 
if number > data.len() as i64 {
return 0;
}
 
if number == data.len() as i64 {
if total < data.iter().sum() {
return 1;
} else {
return 0;
}
}
 
let tail = &data[1..];
combinations(total - data[0], number - 1, &tail) + combinations(total, number, &tail)
}
</syntaxhighlight>
{{out}}
<pre>
<= : 86.8583428954946%
> : 12.80283184307952%
</pre>
 
=={{header|Scala}}==
===Imperative version (Ugly, side effects)===
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/69o8tJX/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/jpUyNPetRXabZkEKc68FAA Scastie (remote JVM)].
<syntaxhighlight lang="scala">object PermutationTest extends App {
private val data =
Array(85, 88, 75, 66, 25, 29, 83, 39, 97, 68, 41, 10, 49, 16, 65, 32, 92, 28, 98)
private var (total, treat) = (1.0, 0)
 
private def pick(at: Int, remain: Int, accu: Int, treat: Int): Int = {
if (remain == 0) return if (accu > treat) 1 else 0
 
pick(at - 1, remain - 1, accu + data(at - 1), treat) +
(if (at > remain) pick(at - 1, remain, accu, treat) else 0)
}
 
for (i <- 0 to 8) treat += data(i)
for (j <- 19 to 11 by -1) total *= j
for (g <- 9 to 1 by -1) total /= g
 
private val gt = pick(19, 9, 0, treat)
private val le = (total - gt).toInt
 
println(f"<= : ${100.0 * le / total}%f%% ${le}%d")
println(f" > : ${100.0 * gt / total}%f%% ${gt}%d")
 
}</syntaxhighlight>
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "float.s7i";
 
Line 1,199 ⟶ 1,778:
writeln("<= : " <& 100.0 * flt(le) / flt(total) digits 6 <& "% " <& le);
writeln(" > : " <& 100.0 * flt(gt) / flt(total) digits 6 <& "% " <& gt);
end func;</langsyntaxhighlight>
 
{{out}}
<= : 87.197168% 80551
<pre>
<= > : 8712.197168802832% 8055111827
> : 12.802832% 11827
</pre>
 
=={{header|Sidef}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="ruby">func statistic(ab, a) {
var(sumab, suma) = (ab.sum, a.sum);
suma/a.size - ((sumab-suma) / (ab.size-a.size))
}
 
func permutationTest(a, b) {
var ab = (a + b);
var tobs = statistic(ab, a);
var under = (var count = 0);
ab.combinations(a.len).each, { |*perm|
statistic(ab, perm) <= tobs && (under += 1);
count += 1;
};)
under * 100 / count;
}
 
var treatmentGroup = [85, 88, 75, 66, 25, 29, 83, 39, 97];
var controlGroup = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98];
var under = permutationTest(treatmentGroup, controlGroup);
say ("under=%.2f%%, over=%.2f%%" % (under, 100 - under));</langsyntaxhighlight>
{{out}}
<pre>
Line 1,235 ⟶ 1,811:
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
# Difference of means; note that the first list must be the concatenation of
Line 1,281 ⟶ 1,857:
set count [tcl::mathfunc::double $count]
list [expr {$overcount / $count}] [expr {$undercount / $count}]
}</langsyntaxhighlight>
Demonstration code:
<langsyntaxhighlight lang="tcl">set treatmentGroup {0.85 0.88 0.75 0.66 0.25 0.29 0.83 0.39 0.97}
set controlGroup {0.68 0.41 0.10 0.49 0.16 0.65 0.32 0.92 0.28 0.98}
lassign [permutationTest $treatmentGroup $controlGroup] over under
puts [format "under=%.2f%%, over=%.2f%%" [expr {$under*100}] [expr {$over*100}]]</langsyntaxhighlight>
{{out}}
<pre>under=86.90%, over=13.10%</pre>
 
=={{header|Ursala}}==
<langsyntaxhighlight Ursalalang="ursala">#import std
#import nat
#import flo
Line 1,306 ⟶ 1,882:
#show+
 
t = --* *-'%'@lrNCC printf/$'%0.2f' times/$100. f(treatment_group,control_group)</langsyntaxhighlight>
{{out}}
<pre>
12.80%
87.20%</pre>
 
=={{header|Wren}}==
{{trans|C}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
 
var data = [85, 88, 75, 66, 25, 29, 83, 39, 97, 68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
 
var pick // recursive
pick = Fn.new { |at, remain, accu, treat|
if (remain == 0) return (accu > treat) ? 1 : 0
return pick.call(at-1, remain-1, accu + data[at-1], treat) +
((at > remain) ? pick.call(at-1, remain, accu, treat) : 0)
}
 
var treat = 0
var total = 1
for (i in 0..8) treat = treat + data[i]
for (i in 19..11) total = total * i
for (i in 9..1) total = total / i
var gt = pick.call(19, 9, 0, treat)
var le = (total - gt).truncate
Fmt.print("<= : $f\% $d", 100 * le / total, le)
Fmt.print(" > : $f\% $d", 100 * gt / total, gt)</syntaxhighlight>
 
{{out}}
<pre>
<= : 87.197168% 80551
> : 12.802832% 11827
</pre>
 
=={{header|XPL0}}==
{{trans|C}}
<syntaxhighlight lang "XPL0">include xpllib; \For Print
 
int Data;
 
func Pick(At, Remain, Accu, Treat);
int At, Remain, Accu, Treat;
[if Remain = 0 then return if Accu > Treat then 1 else 0;
return Pick(At-1, Remain-1, Accu + Data(At-1), Treat) +
(if At > Remain then Pick(At-1, Remain, Accu, Treat) else 0);
];
 
int Treat, GT, LE, I;
real Total;
[Treat:= 0; Total:= 1.;
Data:= [85, 88, 75, 66, 25, 29, 83, 39, 97,
68, 41, 10, 49, 16, 65, 32, 92, 28, 98];
for I:= 0 to 8 do Treat:= Treat + Data(I);
for I:= 19 downto 11 do Total:= Total * float(I);
for I:= 9 downto 1 do Total:= Total / float(I);
GT:= Pick(19, 9, 0, Treat);
LE:= (fix(Total) - GT);
Print("<= : %f% %d\n", 100. * float(LE) / Total, LE);
Print(" > : %f% %d\n", 100. * float(GT) / Total, GT);
]</syntaxhighlight>
{{out}}
<pre>
<= : 87.19717% 80551
> : 12.80283% 11827
</pre>
 
=={{header|zkl}}==
A solution that is not going to scale gracefully at all.
{{trans|D}}
<langsyntaxhighlight lang="zkl">fcn permutationTest(a,b){
ab := a.extend(b);
tObs := a.sum(0);
Line 1,326 ⟶ 1,964:
controlGroup := T(68, 41, 10, 49, 16, 65, 32, 92, 28, 98);
under := permutationTest(treatmentGroup, controlGroup);
println("Under =%6.2f%%\nOver =%6.2f%%".fmt(under, 100.0 - under));</langsyntaxhighlight>
{{out}}
<pre>
9,482

edits