Permutation test: Difference between revisions

m
m (→‎{{header|REXX}}: removed STYLE from the PRE html tag.)
m (→‎{{header|Wren}}: Minor tidy)
 
(46 intermediate revisions by 25 users not shown)
Line 2:
A new medical treatment was tested on a population of <math>n + m</math>
volunteers, with each volunteer randomly assigned either to a group of
<math>n</math> treatment subjects, or to a group of <math>m</math> control subjects. Members of
the treatment group were given the treatment, and members of the
control group were given a placebo. The effect of the treatment or
placebo on each volunteer was measured and reported in this table.
 
Members of the treatment group were given the treatment,
{| style="text-align: left; width: 50%;" border="4" cellpadding="2" cellspacing="2"
and members of the control group were given a placebo.
The effect of the treatment or placebo on each volunteer
was measured and reported in this table.
 
:::::::{| style="text-align: left; width: 25%;" border="4" cellpadding="2" cellspacing="2"
|+ Table of experimental results
|- style="background-color: rgb(255, 204, 255);"
Line 42 ⟶ 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 49 ⟶ 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 113 ⟶ 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 132 ⟶ 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 169 ⟶ 206:
end Last;
 
end Iterate_Subsets;</langsyntaxhighlight>
 
Finally, here is the output:
 
{{out}}
<pre>Less or Equal: 87.2 80551
More: 12.8 11827
</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 217 ⟶ 286:
N% = (N% + (N% >>> 4)) AND &0F0F0F0F
N% += N% >>> 8 : N% += N% >>> 16
= N% AND &7F</langsyntaxhighlight>
{{out}}
'''Output:'''
<pre>
Percentage groupings <= actual experiment: 87.1970296
Line 225 ⟶ 294:
 
=={{header|C}}==
<langsyntaxhighlight Clang="c">#include <stdio.h>
 
int data[] = { 85, 88, 75, 66, 25, 29, 83, 39, 97,
Line 253 ⟶ 322:
100 * le / total, le, 100 * gt / total, gt);
return 0;
}</syntaxhighlight>
}</lang>Output:<lang><= : 87.197168% 80551
Output:<syntaxhighlight lang="text"><= : 87.197168% 80551
> : 12.802832% 11827</lang>
> : 12.802832% 11827</syntaxhighlight>
 
=={{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 280 ⟶ 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 298 ⟶ 455:
immutable under = permutationTest(treatmentGroup, controlGroup);
writefln("Under =%6.2f%%\nOver =%6.2f%%", under, 100.0 - under);
}</langsyntaxhighlight>
{{out}}
<pre>Under = 87.20%
Line 305 ⟶ 462:
Alternative version:
{{trans|C}}
<syntaxhighlight lang="d">void main() @safe {
<lang d>import std.stdio, std.algorithm, std.range;
import std.stdio, std.algorithm, std.range;
 
void main() {
immutable treatment = [85, 88, 75, 66, 25, 29, 83, 39, 97];
immutable control = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98];
Line 313 ⟶ 470:
immutable sTreat = treatment.sum;
 
T pick(T)(in size_t at, in size_t remain, in T accu) pure nothrow @safe @nogc {
if (remain == 0)
return accu > sTreat;
Line 328 ⟶ 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}}
<syntaxhighlight lang="elixir">defmodule Permutation do
def statistic(ab, a) do
sumab = Enum.sum(ab)
suma = Enum.sum(a)
suma / length(a) - (sumab - suma) / (length(ab) - length(a))
end
def test(a, b) do
ab = a ++ b
tobs = statistic(ab, a)
{under, count} = Enum.reduce(comb(ab, length(a)), {0,0}, fn perm, {under, count} ->
if statistic(ab, perm) <= tobs, do: {under+1, count+1},
else: {under , count+1}
end)
under * 100.0 / count
end
defp comb(_, 0), do: [[]]
defp comb([], _), do: []
defp comb([h|t], m) do
(for l <- comb(t, m-1), do: [h|l]) ++ comb(t, m)
end
end
 
treatmentGroup = [85, 88, 75, 66, 25, 29, 83, 39, 97]
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]</syntaxhighlight>
 
{{out}}
<pre>
under = 87.20%, over = 12.80%
</pre>
 
=={{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 384 ⟶ 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 459 ⟶ 781:
}
rc(0, 0)
}</langsyntaxhighlight>
{{out}}
Output:
<pre>
differences <= observed: 87.197168%
Line 467 ⟶ 789:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">binomial n m = (f !! n) `div` (f !! m) `div` (f !! (n - m))
where f = scanl (*) 1 [1..]
 
Line 487 ⟶ 809:
[68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
in do putStr "> : "; print r
putStr "<=: "; print $ 100 - r</langsyntaxhighlight>
{{out}}
output:<pre>
<pre>
> : 12.80283184307952
<=: 87.19716815692048
Line 494 ⟶ 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 512 ⟶ 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 540 ⟶ 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 550 ⟶ 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%</syntaxhighlight>
 
=={{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>
 
<lang>under: 87.1972%
over: 12.8028%</lang>
=={{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 566 ⟶ 925:
( .[1:]|combination(r))
end;
</syntaxhighlight>
</lang>
'''Part 2: Permutation Test'''
<syntaxhighlight lang ="jq"># a should be the treatment group and b theshould controlbe grouparrays:
def permutationTest(a; b):
 
def normalize(a;b): # mainly to avoid having to compute $sumab
# avg(a) - avg(b) (assuming ab==a+b)
(a|add) as $sa
| (b|add) as $sb
| (($sa + $sb)/((a|length) + (b|length))) as $avg
| [(a | map(.-$avg)), (b | map(.-$avg))];
 
# avg(a) - avg(b) (assuming ab==a+b and avg(ab) is 0)
def statistic(ab; a):
(aba | add) as $sumabsuma
|# (a ab| add) asshould be 0, by $sumanormalization
| ($suma / (a|length)) -+
(($sumab - $suma) / ((ab|length) - (a|length)));
normalize(a;b)
(a + b) as $ab # pooled observations
| statistic($ab; a + b) as $t_observedab # observed difference in means # pooled observations
| .[0] as $a | .[1] as $b
| reduce ($ab|combination(a|length)) as $perm # for each combination...
| statistic([0,0]$ab; $a) as $t_observed # observed difference in # state: [under,count]means
| reduce ($ab|combination($a|length)) as $perm # for each combination...
([0,0]; # state: [under,count]
if statistic($ab; $perm) <= $t_observed then .[0] += 1 else . end
| .[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
% under=87.1971681569204814304271579813
% over=12.802831843079517856957284201869
 
=={{header|MathematicaJulia}}==
{{works with|Julia|0.6}}
<lang mathematica>"<=: " <> ToString[#1] <> " " <> ToString[100. #1/#2] <> "%\n >: " <>
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
 
meandiff(a::Vector{T}, b::Vector{T}) where T <: Real = mean(a) - mean(b)
 
function bifurcate(a::AbstractVector, sel::Vector{T}) where T <: Integer
x = a[sel]
asel = trues(length(a))
asel[sel] = false
y = a[asel]
return x, y
end
 
function permutation_test(treated::Vector{T}, control::Vector{T}) where T <: Real
effect0 = meandiff(treated, control)
pool = vcat(treated, control)
tlen = length(treated)
plen = length(pool)
better = worse = 0
for subset in combinations(1:plen, tlen)
t, c = bifurcate(pool, subset)
if effect0 < meandiff(t, c)
better += 1
else
worse += 1
end
end
return better, worse
end</syntaxhighlight>
 
'''Main'''
<syntaxhighlight lang="julia">const treated = [85, 88, 75, 66, 25, 29, 83, 39, 97]
const control = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
 
(better, worse) = permutation_test(treated, control)
 
tot = better + worse
 
println("Permutation test using the following data:")
println("Treated: ", treated)
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)
print(@sprintf("%8d, %5.2f%% showed equalivalent or worse results.", worse, 100 * worse / tot))</syntaxhighlight>
 
{{out}}
<pre>Permutation test using the following data:
Treated: [85, 88, 75, 66, 25, 29, 83, 39, 97]
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|M2000 Interpreter}}==
{{trans|C}}
<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}}
Output:
<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}"
Output:
echo fmt" > : {100.0 * float(gt) / total:.6f}% {gt}"</syntaxhighlight>
<pre>under = 87.85%, over = 12.15%</pre>
{{out}}
<pre>
<= : 87.197168% 80551
> : 12.802832% 11827
</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">#!/usr/bin/perl
use warnings;
use strict;
Line 728 ⟶ 1,261:
92
28
98</langsyntaxhighlight>
{{out}}
equal 313 0.339%
Line 734 ⟶ 1,267:
greater 11827 12.803%
 
=={{header|Perl 6Phix}}==
{{Trans|C}}
{{works with|Rakudo|2013.05}}
<!--<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>proto combine (Int, @) {*}
<syntaxhighlight lang="picolisp">(load "@lib/simul.l") # For 'subsets'
multi combine (0, @) { [] }
multi combine ($, []) { () }
multi combine ($n, [$head, *@tail]) {
gather {
take [$head, @$_] for combine($n-1, @tail);
take [ @$_ ] for combine($n , @tail);
}
}
 
(scl 2)
sub stats ( @test, @all ) {
(([+] @test) / +@test ) - ([+] @all, (@test X* -1)) / (@all - @test)
}
 
(de _stat (A)
(let (LenA (length A) SumA (apply + A))
(-
(*/ SumA LenA)
(*/ (- SumAB SumA) (- LenAB LenA)) ) ) )
 
(de permutationTest (A B)
my @treated = <85 88 75 66 25 29 83 39 97>;
(let
my @control = <68 41 10 49 16 65 32 92 28 98>;
(AB (append A B)
my @all = @treated, @control;
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 $base = stats( @treated, @all );
*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) )
my @trials = 0, 0, 0;
 
map { @trials[ 1 + ( stats( $_, @all ) <=> $base ) ]++ }, combine( +@treated, @all );
 
(let N (permutationTest *TreatmentGroup *ControlGroup)
say 'Counts: <, =, > ', @trials;
(prinl "under = " (round N) "%, over = " (round (- 100.0 N)) "%") )</syntaxhighlight>
say 'Less than : %', 100 * @trials[0] / [+] @trials;
{{out}}
say 'Equal to : %', 100 * @trials[1] / [+] @trials;
<pre>under = 87.85%, over = 12.15%</pre>
say 'Greater than : %', 100 * @trials[2] / [+] @trials;
say 'Less or Equal: %', 100 * ( [+] @trials[0,1] ) / [+] @trials;</lang>
 
'''Output'''
<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 790 ⟶ 1,344:
the treatment group or the control group
 
<syntaxhighlight lang="purebasic">
<lang PureBasic>
 
Define.f meanTreated,meanControl,diffInMeans
Line 882 ⟶ 1,436:
Debug StrF(100*diffLessOrEqual/TotalComBinations,2)+" "+Str(diffLessOrEqual)
Debug StrF(100*diffGreater /TotalComBinations,2)+" "+Str(diffGreater)
</syntaxhighlight>
 
{{out}}
 
</lang>
 
'''Sample Output'''
<pre>
87.20 80551
12.80 11827
</pre>
 
 
 
=={{header|Python}}==
{{trans|Tcl}}
<langsyntaxhighlight lang="python">from itertools import combinations as comb
 
def statistic(ab, a):
Line 915 ⟶ 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 934 ⟶ 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 C version, with some generalizations and optimization.
<lang rexx>/*REXX program does 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
total=1; do j=19 to m+1 by -1 ; total=total*j ; end
do k= 9 to 1 by -1 ; total=total/k ; end
gt=pick(n+m, n, 0)
le=total-gt
say "<= " format(100*le/total,,3)'%' le /*show 3 decimal places.*/
say " > " format(100*gt/total,,3)'%' gt
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────PICK subroutine─────────────────────*/
pick: procedure expose #. treat; parse arg it,rest,eff
if rest==0 then return eff>treat
if it>rest then q=pick(it-1, rest, eff)
else q=0
itP=it-1
return pick(itP, rest-1, eff+#.itP) + q</lang>
'''output''' 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 991 ⟶ 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,027 ⟶ 1,532:
more (real->decimal-string (* 100. (/ more sum)) 2)
leq (real->decimal-string (* 100. (/ leq sum)) 2))))
</syntaxhighlight>
</lang>
 
{{out}}
'''Sample Output'''
<pre>
<=: 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,056 ⟶ 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,062 ⟶ 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,102 ⟶ 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
> : 12.802832% 11827
 
=={{header|Sidef}}==
{{trans|Ruby}}
<syntaxhighlight 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, {|*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))</syntaxhighlight>
{{out}}
<pre>
under=87.20%, over=12.80%
<= : 87.197168% 80551
> : 12.802832% 11827
</pre>
 
=={{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,157 ⟶ 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}}
Output:
<pre>under=86.90%, over=13.10%</pre>
 
=={{header|Ursala}}==
<langsyntaxhighlight Ursalalang="ursala">#import std
#import nat
#import flo
Line 1,182 ⟶ 1,882:
#show+
 
t = --* *-'%'@lrNCC printf/$'%0.2f' times/$100. f(treatment_group,control_group)</langsyntaxhighlight>
{{out}}
output:
<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,202 ⟶ 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