Averages/Mode
You are encouraged to solve this task according to the task description, using any language you may know.
If it is not appropriate or possible to support a general collection, use a vector (array), if possible. If it is not appropriate or possible to support an unspecified value type, use integers.
[edit] ActionScript
This implementation does not work with arbitrary collections. However, it works with arrays containing mixed data, including strings and other arrays.
function Mode(arr:Array):Array {
//Create an associative array to count how many times each element occurs,
//an array to contain the modes, and a variable to store how many times each mode appears.
var count:Array = new Array();
var modeList:Array;
var maxCount:uint=0;
for (var i:String in arr) {
//Record how many times an element has occurred. Note that each element in the cuont array
//has to be initialized explicitly, since it is an associative array.
if (count[arr[i]]==undefined) {
count[arr[i]]=1;
} else {
count[arr[i]]++;
}
//If this is now the most common element, clear the list of modes, and add this element.
if(count[arr[i]] > maxCount)
{
maxCount=count[arr[i]];
modeList = new Array();
modeList.push(arr[i]);
}
//If this is a mode, add it to the list.
else if(count[arr[i]] == maxCount){
modeList.push(arr[i]);
}
}
return modeList;
}
[edit] Ada
mode.ads:
generic
type Element_Type is private;
type Element_Array is array (Positive range <>) of Element_Type;
package Mode is
function Get_Mode (Set : Element_Array) return Element_Array;
end Mode;
mode.adb:
with Ada.Containers.Indefinite_Vectors;
package body Mode is
-- map Count to Elements
package Count_Vectors is new Ada.Containers.Indefinite_Vectors
(Element_Type => Element_Array,
Index_Type => Positive);
procedure Add (To : in out Count_Vectors.Vector; Item : Element_Type) is
use type Count_Vectors.Cursor;
Position : Count_Vectors.Cursor := To.First;
Found : Boolean := False;
begin
while not Found and then Position /= Count_Vectors.No_Element loop
declare
Elements : Element_Array := Count_Vectors.Element (Position);
begin
for I in Elements'Range loop
if Elements (I) = Item then
Found := True;
end if;
end loop;
end;
if not Found then
Position := Count_Vectors.Next (Position);
end if;
end loop;
if Position /= Count_Vectors.No_Element then
-- element found, remove it and insert to next count
declare
New_Position : Count_Vectors.Cursor :=
Count_Vectors.Next (Position);
begin
-- remove from old position
declare
Old_Elements : Element_Array :=
Count_Vectors.Element (Position);
New_Elements : Element_Array (1 .. Old_Elements'Length - 1);
New_Index : Positive := New_Elements'First;
begin
for I in Old_Elements'Range loop
if Old_Elements (I) /= Item then
New_Elements (New_Index) := Old_Elements (I);
New_Index := New_Index + 1;
end if;
end loop;
To.Replace_Element (Position, New_Elements);
end;
-- new position not already there?
if New_Position = Count_Vectors.No_Element then
declare
New_Array : Element_Array (1 .. 1) := (1 => Item);
begin
To.Append (New_Array);
end;
else
-- add to new position
declare
Old_Elements : Element_Array :=
Count_Vectors.Element (New_Position);
New_Elements : Element_Array (1 .. Old_Elements'Length + 1);
begin
New_Elements (1 .. Old_Elements'Length) := Old_Elements;
New_Elements (New_Elements'Last) := Item;
To.Replace_Element (New_Position, New_Elements);
end;
end if;
end;
else
-- element not found, add to count 1
Position := To.First;
if Position = Count_Vectors.No_Element then
declare
New_Array : Element_Array (1 .. 1) := (1 => Item);
begin
To.Append (New_Array);
end;
else
declare
Old_Elements : Element_Array :=
Count_Vectors.Element (Position);
New_Elements : Element_Array (1 .. Old_Elements'Length + 1);
begin
New_Elements (1 .. Old_Elements'Length) := Old_Elements;
New_Elements (New_Elements'Last) := Item;
To.Replace_Element (Position, New_Elements);
end;
end if;
end if;
end Add;
function Get_Mode (Set : Element_Array) return Element_Array is
Counts : Count_Vectors.Vector;
begin
for I in Set'Range loop
Add (Counts, Set (I));
end loop;
return Counts.Last_Element;
end Get_Mode;
end Mode;
example use:
with Ada.Text_IO;
with Mode;
procedure Main is
type Int_Array is array (Positive range <>) of Integer;
package Int_Mode is new Mode (Integer, Int_Array);
Test_1 : Int_Array := (1, 2, 3, 1, 2, 4, 2, 5, 2, 3, 3, 1, 3, 6);
Result : Int_Array := Int_Mode.Get_Mode (Test_1);
begin
Ada.Text_IO.Put ("Input: ");
for I in Test_1'Range loop
Ada.Text_IO.Put (Integer'Image (Test_1 (I)));
if I /= Test_1'Last then
Ada.Text_IO.Put (",");
end if;
end loop;
Ada.Text_IO.New_Line;
Ada.Text_IO.Put ("Result:");
for I in Result'Range loop
Ada.Text_IO.Put (Integer'Image (Result (I)));
if I /= Result'Last then
Ada.Text_IO.Put (",");
end if;
end loop;
Ada.Text_IO.New_Line;
end Main;
- Output:
Input: 1, 2, 3, 1, 2, 4, 2, 5, 2, 3, 3, 1, 3, 6 Result: 2, 3
[edit] AutoHotkey
Search autohotkey.com: [1]
Source: AutoHotkey forum by Laszlo
MsgBox % Mode("1 2 3")
MsgBox % Mode("1 2 0 3 0.0")
MsgBox % Mode("0.1 2.2 -0.1 0.22e1 2.20 0.1")
Mode(a, d=" ") { ; the number that occurs most frequently in a list delimited by d (space)
Sort a, ND%d%
Loop Parse, a, %d%
If (V != A_LoopField) {
If (Ct > MxCt)
MxV := V, MxCt := Ct
V := A_LoopField, Ct := 1
}
Else Ct++
Return Ct>MxCt ? V : MxV
}
[edit] AWK
#!/usr/bin/gawk -f
{
# compute histogram
histo[$1] += 1;
};
function mode(HIS) {
# Computes the mode from Histogram A
max = 0;
n = 0;
for (k in HIS) {
val = HIS[k];
if (HIS[k] > max) {
max = HIS[k];
n = 1;
List[n] = k;
} else if (HIS[k] == max) {
List[++n] = k;
}
}
for (k=1; k<=n; k++) {
o = o""OFS""List[k];
}
return o;
}
END {
print mode(histo);
};
cat modedata.txt 0 3 6 aa 3 6 aa 3 aa 6 7 1 as@mini10:~/src/RosettaCode$ ./mode.awk modedata.txt 6 aa 3
[edit] BBC BASIC
DIM a(10), b(4)
a() = 1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17
b() = 1, 2, 4, 4, 1
DIM modes(10)
PRINT "Mode(s) of a() = " ;
FOR i% = 1 TO FNmodes(a(), modes())
PRINT ; modes(i%) " " ;
NEXT
PRINT "Mode(s) of b() = " ;
FOR i% = 1 TO FNmodes(b(), modes())
PRINT ; modes(i%) " " ;
NEXT
END
DEF FNmodes(a(), m())
LOCAL I%, J%, N%, c%(), max%
N% = DIM(a(),1)
IF N% = 0 THEN m(1) = a(0) : = 1
DIM c%(N%)
FOR I% = 0 TO N%-1
FOR J% = I%+1 TO N%
IF a(I%) = a(J%) c%(I%) += 1
NEXT
IF c%(I%) > max% max% = c%(I%)
NEXT I%
J% = 0
FOR I% = 0 TO N%
IF c%(I%) = max% J% += 1 : m(J%) = a(I%)
NEXT
= J%
- Output:
Mode(s) of a() = 6 Mode(s) of b() = 1 4
[edit] C
Using an array of doubles. If another data type is desired, the cmp_dbl and vcount definitions should be changed accordingly.
#include <stdio.h>
#include <stdlib.h>
typedef struct { double v; int c; } vcount;
int cmp_dbl(const void *a, const void *b)
{
double x = *(const double*)a - *(const double*)b;
return x < 0 ? -1 : x > 0;
}
int vc_cmp(const void *a, const void *b)
{
return ((const vcount*)b)->c - ((const vcount*)a)->c;
}
int get_mode(double* x, int len, vcount **list)
{
int i, j;
vcount *vc;
/* sort values */
qsort(x, len, sizeof(double), cmp_dbl);
/* count occurence of each value */
for (i = 0, j = 1; i < len - 1; i++, j += (x[i] != x[i + 1]));
*list = vc = malloc(sizeof(vcount) * j);
vc[0].v = x[0];
vc[0].c = 1;
/* generate list value-count pairs */
for (i = j = 0; i < len - 1; i++, vc[j].c++)
if (x[i] != x[i + 1]) vc[++j].v = x[i + 1];
/* sort that by count in descending order */
qsort(vc, j + 1, sizeof(vcount), vc_cmp);
/* the number of entries with same count as the highest */
for (i = 0; i <= j && vc[i].c == vc[0].c; i++);
return i;
}
int main()
{
double values[] = { 1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 12, 12, 17 };
# define len sizeof(values)/sizeof(double)
vcount *vc;
int i, n_modes = get_mode(values, len, &vc);
printf("got %d modes:\n", n_modes);
for (i = 0; i < n_modes; i++)
printf("\tvalue = %g, count = %d\n", vc[i].v, vc[i].c);
free(vc);
return 0;
}
- Output:
got 2 modes:
value = 6, count = 4
value = 12, count = 4
[edit] C++
#include <iterator>
#include <utility>
#include <algorithm>
#include <list>
#include <iostream>
// helper struct
template<typename T> struct referring
{
referring(T const& t): value(t) {}
template<typename Iter>
bool operator()(std::pair<Iter, int> const& p) const
{
return *p.first == value;
}
T const& value;
};
// requires:
// FwdIterator is a ForwardIterator
// The value_type of FwdIterator is EqualityComparable
// OutIterator is an output iterator
// the value_type of FwdIterator is convertible to the value_type of OutIterator
// [first, last) is a valid range
// provides:
// the mode is written to result
template<typename FwdIterator, typename OutIterator>
void mode(FwdIterator first, FwdIterator last, OutIterator result)
{
typedef typename std::iterator_traits<FwdIterator>::value_type value_type;
typedef std::list<std::pair<FwdIterator, int> > count_type;
typedef typename count_type::iterator count_iterator;
// count elements
count_type counts;
while (first != last)
{
count_iterator element = std::find_if(counts.begin(), counts.end(),
referring<value_type>(*first));
if (element == counts.end())
counts.push_back(std::make_pair(first, 1));
else
++element->second;
++first;
}
// find maximum
int max = 0;
for (count_iterator i = counts.begin(); i != counts.end(); ++i)
if (i->second > max)
max = i->second;
// copy corresponding elements to output sequence
for (count_iterator i = counts.begin(); i != counts.end(); ++i)
if (i->second == max)
*result++ = *i->first;
}
// example usage
int main()
{
int values[] = { 1, 2, 3, 1, 2, 4, 2, 5, 2, 3, 3, 1, 3, 6 };
median(values, values + sizeof(values)/sizeof(int),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;
}
- Output:
2 3
[edit] C#
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Test
{
class Program
{
static void Main(string[] args)
{
/*
* We Use Linq To Determine The Mode
*/
List<int> myList = new List<int>() { 1, 1, 2, 4, 4 };
var query = from numbers in myList //select the numbers
group numbers by numbers //group them together so we can get the count
into groupedNumbers
select new { Number = groupedNumbers.Key, Count = groupedNumbers.Count() }; //so we got a query
//find the max of the occurence of the mode
int max = query.Max(g => g.Count);
IEnumerable<int> modes = query.Where(x => x.Count == max).Select(x => x.Number);//match the frequence and select the number
foreach (var item in modes)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
}
}
[edit] Clojure
(defn modes [coll]
(let [distrib (frequencies coll)
[value freq] [first second] ; name the key/value pairs in the distrib (map) entries
sorted (sort-by (comp - freq) distrib)
maxfq (freq (first sorted))]
(map value (take-while #(= maxfq (freq %)) sorted))))
[edit] CoffeeScript
mode = (arr) ->
# returns an array with the modes of arr, i.e. the
# elements that appear most often in arr
counts = {}
for elem in arr
counts[elem] ||= 0
counts[elem] += 1
max = 0
for key, cnt of counts
max = cnt if cnt > max
(key for key, cnt of counts when cnt == max)
console.log mode [1, 2, 2, 2, 3, 3, 3, 4, 4]
[edit] Common Lisp
The following returns a list of the modes of a sequence as the primary value, and the frequency as the secondary value. E.g., (mode '(a b c d a b c a b)) produces (A B) and 3. hash-table-options can be used to customize the hash table, e.g., to specify the test by which elements are compared.
(defun mode (sequence &rest hash-table-options)
(let ((frequencies (apply #'make-hash-table hash-table-options)))
(map nil (lambda (element)
(incf (gethash element frequencies 0)))
sequence)
(let ((modes '())
(hifreq 0 ))
(maphash (lambda (element frequency)
(cond ((> frequency hifreq)
(setf hifreq frequency
modes (list element)))
((= frequency hifreq)
(push element modes))))
frequencies)
(values modes hifreq))))
[edit] D
The mode function returns a range of all the mode items:
import std.stdio, std.algorithm, std.array;
auto mode(T)(T[] items) /*pure nothrow*/ {
int[T] aa;
foreach (item; items)
aa[item]++;
immutable m = aa.byValue.reduce!max;
return aa.byKey.filter!(k => aa[k] == m);
}
void main() {
auto data = [1, 2, 3, 1, 2, 4, 2, 5, 3, 3, 1, 3, 6];
writeln("Mode: ", data.mode);
data ~= 2;
writeln("Mode: ", data.mode);
}
- Output:
Mode: [3] Mode: [2, 3]
[edit] E
pragma.enable("accumulator")
def mode(values) {
def counts := [].asMap().diverge()
var maxCount := 0
for v in values {
maxCount max= (counts[v] := counts.fetch(v, fn{0}) + 1)
}
return accum [].asSet() for v => ==maxCount in counts { _.with(v) }
}
? mode([1,1,2,2,3,3,4,4,4,5,5,6,6,7,8,8,9,9,0,0,0])
# value: [4, 0].asSet()
In the line "maxCount max= (counts[v] := counts.fetch(v, fn{0}) + 1)", max= is an update-assignment operation like +=. (The parentheses are unnecessary.) A more verbose version would be:
def newCount := counts.fetch(v, fn { 0 }) + 1
counts[v] := newCount
maxCount := maxCount.max(newCount)
In for loops, each key and value from the collection are pattern matched against the specified key pattern => value pattern. In "for v => ==maxCount in counts", the == is a pattern-match operator which fails unless the value examined is equal to the specified value; so this selects only the input values (keys in counts) whose counts are equal to the maximum count.
[edit] Elena
#define std'dictionary'*.
#define std'basic'*.
#define std'patterns'*.
#define std'routines'*.
#define std'collections'*.
#subject mode.
#symbol ModeValue : anArray =
[
#var aCountMap := Dictionary.
Scan::anArray run: anItem =
[
#if aCountMap@anItem += 1
| [
aCountMap append &dictionary_key:anItem &content:Integer::1.
].
].
aCountMap~esort run: aPair = (aPair former > aPair later).
#var aResult := List.
#var aMax := aCountMap first_item content.
Scan::aCountMap run: anItem =
[
#if (aMax == anItem)?
[ aResult += anItem dictionary_key. ].
].
^ aResult.
].
#symbol Program =
[
#var anArray1 := (1, 1, 2, 4, 4).
#var anArray2 := (1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17).
#var aMode1 := ModeValue::anArray1.
#var aMode2 := ModeValue::anArray2.
'program'output << "mode of (" << anArray1 << ") is (" << aMode1 << ")%n".
'program'output << "mode of (" << anArray2 << ") is (" << aMode2 << ")%n".
].
[edit] Erlang
-module( mode ).
-export( [example/0, values/1] ).
example() ->
Set = [1, 2, "qwe", "asd", 1, 2, "qwe", "asd", 2, "qwe"],
io:fwrite( "In ~p the mode(s) is(are): ~p~n", [Set, values(Set)] ).
values( Set ) ->
Dict = lists:foldl( fun values_count/2, dict:new(), Set ),
[X || {X, _Y} <- dict:fold( fun keep_maxs/3, [{0, 0}], Dict )].
keep_maxs( Key, Value, [{_Max_key, Max_value} | _] ) when Value > Max_value ->
[{Key, Value}];
keep_maxs( Key, Value, [{_Max_key, Max_value} | _]=Maxs ) when Value =:= Max_value ->
[{Key, Value} | Maxs];
keep_maxs( _Key, _Value, Maxs ) ->
Maxs.
values_count( Value, Dict ) -> dict:update_counter( Value, 1, Dict ).
- Output:
12> mode:example(). In [1, 2, "qwe", "asd", 1, 2, "qwe", "asd", 2, "qwe"] the mode(s) is(are): ["qwe", 2]
[edit] Euphoria
include misc.e
function mode(sequence s)
sequence uniques, counts, modes
integer j,max
uniques = {}
counts = {}
for i = 1 to length(s) do
j = find(s[i], uniques)
if j then
counts[j] += 1
else
uniques = append(uniques, s[i])
counts = append(counts, 1)
end if
end for
max = counts[1]
for i = 2 to length(counts) do
if counts[i] > max then
max = counts[i]
end if
end for
j = 1
modes = {}
while j <= length(s) do
j = find_from(max, counts, j)
if j = 0 then
exit
end if
modes = append(modes, uniques[j])
j += 1
end while
return modes
end function
constant s = { 1, "blue", 2, 7.5, 5, "green", "red", 5, 2, "blue", "white" }
pretty_print(1,mode(s),{3})
- Output:
{
"blue",
2,
5
}
[edit] F#
The Unchecked.defaultof became available in version 1.9.4 I think.
let mode (l:'a seq) =
l
|> Seq.countBy (fun item -> item) // Count individual items
|> Seq.fold // Find max counts
(fun (cp, lst) (item, c) -> // State is (count, list of items with that count)
if c > cp then (c, [item]) // New max - keep count and a list of the single item
elif c = cp then (c, item :: lst) // New element with max count - prepend it to the list
else (cp,lst)) // else just keep old count/list
(0, [Unchecked.defaultof<'a>]) // Start with a count of 0 and a dummy item
|> snd // From (count, list) we just want the second item (the list)
Example usage:
> mode ["a"; "b"; "c"; "c"];;
val it : string list = ["c"]
> mode ["a"; "b"; "c"; "c";"a"];;
val it : string list = ["c"; "a"]
> mode [1;2;1;3;2;0;0];;
val it : int list = [0; 2; 1]
[edit] Factor
Factor has the word mode in math.statistics vocabulary.
{ 11 9 4 9 4 9 } mode ! 9
[edit] Fortran
For the Qsort_Module see Sorting_algorithms/Quicksort#Fortran
program mode_test
use Qsort_Module only Qsort => sort
implicit none
integer, parameter :: S = 10
integer, dimension(S) :: a1 = (/ -1, 7, 7, 2, 2, 2, -1, 7, -3, -3 /)
integer, dimension(S) :: a2 = (/ 1, 1, 1, 1, 1, 0, 2, 2, 2, 2 /)
integer, dimension(S) :: a3 = (/ 0, 0, -1, -1, 9, 9, 3, 3, 7, 7 /)
integer, dimension(S) :: o
integer :: l, trash
print *, stat_mode(a1)
trash = stat_mode(a1, o, l)
print *, o(1:l)
trash = stat_mode(a2, o, l)
print *, o(1:l)
trash = stat_mode(a3, o, l)
print *, o(1:l)
contains
! stat_mode returns the lowest (if not unique) mode
! others can hold other modes, if the mode is not unique
! if others is provided, otherslen should be provided too, and
! it says how many other modes are there.
! ok can be used to know if the return value has a meaning
! or the mode can't be found (void arrays)
integer function stat_mode(a, others, otherslen, ok)
integer, dimension(:), intent(in) :: a
logical, optional, intent(out) :: ok
integer, dimension(size(a,1)), optional, intent(out) :: others
integer, optional, intent(out) :: otherslen
! ta is a copy of a, we sort ta modifying it, freq
! holds the frequencies and idx the index (for ta) so that
! the value appearing freq(i)-time is ta(idx(i))
integer, dimension(size(a, 1)) :: ta, freq, idx
integer :: rs, i, tm, ml, tf
if ( present(ok) ) ok = .false.
select case ( size(a, 1) )
case (0) ! no mode... ok is false
return
case (1)
if ( present(ok) ) ok = .true.
stat_mode = a(1)
return
case default
if ( present(ok) ) ok = .true.
ta = a ! copy the array
call sort(ta) ! sort it in place (cfr. sort algos on RC)
freq = 1
idx = 0
rs = 1 ! rs will be the number of different values
do i = 2, size(ta, 1)
if ( ta(i-1) == ta(i) ) then
freq(rs) = freq(rs) + 1
else
idx(rs) = i-1
rs = rs + 1
end if
end do
idx(rs) = i-1
ml = maxloc(freq(1:rs), 1) ! index of the max value of freq
tf = freq(ml) ! the max frequency
tm = ta(idx(ml)) ! the value with that freq
! if we want all the possible modes, we provide others
if ( present(others) ) then
i = 1
others(1) = tm
do
freq(ml) = 0
ml = maxloc(freq(1:rs), 1)
if ( tf == freq(ml) ) then ! the same freq
i = i + 1 ! as the max one
others(i) = ta(idx(ml))
else
exit
end if
end do
if ( present(otherslen) ) then
otherslen = i
end if
end if
stat_mode = tm
end select
end function stat_mode
end program mode_test
[edit] Haskell
import Prelude (foldr, maximum, (==), (+))
import Data.Map (insertWith', empty, filter, elems, keys)
mode :: (Ord a) => [a] -> [a]
mode xs = keys (filter (== maximum (elems counts)) counts)
where counts = foldr (\x -> insertWith' (+) x 1) empty xs
counts is a map from each value found in xs to the number of occurrences (foldr traverses the list, insertWith' increments the count). This map is then filtered to only those entries whose count is the maximum count, and their keys (the values from the input list) are returned.
> mode [1,2,3,3,2,1,1] [1] > mode [1,2,3,3,2,1] [1,2,3]
Alternately:
import Data.List (group, sort)
mode :: (Ord a) => [a] -> [a]
mode xs = map fst $ filter ((==best).snd) counts
where counts = map (\l -> (head l, length l)) . group . sort $ xs
best = maximum (map snd counts)
Another version that does not require an orderable type:
import Data.List (partition)
mode :: (Eq a) => [a] -> [a]
mode = snd . modesWithCount
where modesWithCount :: (Eq a) => [a] -> (Int, [a])
modesWithCount [] = (0,[])
modesWithCount l@(x:_) | length xs > best = (length xs, [x])
| length xs < best = (best, modes)
| otherwise = (best, x:modes)
where (xs, notxs) = partition (== x) l
(best, modes) = modesWithCount notxs
[edit] GAP
mode := function(v)
local c, m;
c := Collected(SortedList(v));
m := Maximum(List(c, x -> x[2]));
return List(Filtered(c, x -> x[2] = m), y -> y[1]);
end;
mode([ 7, 5, 6, 1, 5, 5, 7, 12, 17, 6, 6, 5, 12, 3, 6 ]);
# [ 5, 6 ]
[edit] Go
Fixed collection type, fixed value type. In Go it is appropriate to program directly with built in types when possible.
package main
import "fmt"
func main() {
fmt.Println(mode([]int{2, 7, 1, 8, 2}))
fmt.Println(mode([]int{2, 7, 1, 8, 2, 8}))
}
func mode(a []int) []int {
m := make(map[int]int)
for _, v := range a {
m[v]++
}
var mode []int
var n int
for k, v := range m {
switch {
case v < n:
case v > n:
n = v
mode = append(mode[:0], k)
default:
mode = append(mode, k)
}
}
return mode
}
- Output:
[2] [2 8]
Fixed collection type, unspecified value type. An empty interface can hold any type. A slice []interface can hold a mix of types. It's not too much more source code, although there is some overhead to support this generality.
package main
import "fmt"
func main() {
fmt.Println(mode([]interface{}{.2, .7, .1, .8, .2}))
fmt.Println(mode([]interface{}{"two", 7, 1, 8, "two", 8}))
}
func mode(a []interface{}) []interface{} {
m := make(map[interface{}]int)
for _, v := range a {
m[v]++
}
var mode []interface{}
var n int
for k, v := range m {
switch {
case v < n:
case v > n:
n = v
mode = append(mode[:0], k)
default:
mode = append(mode, k)
}
}
return mode
}
- Output:
[0.2] [two 8]
General collection, fixed value type. The other kind of generality mentioned in the task requires more code. In Go this is done with an interface to define generalized collection methods. Here, the only method we need to demonstrate is iteration over the collection, so the interface has only one method. Any number of types then can implement the interface. Note that the mode function now takes an object of this interface type. In effect, it becomes a generic function, oblivious to the implementation of the collection, and accessing it only through its methods.
package main
import "fmt"
// interface type
type intCollection interface {
iterator() func() (int, bool)
}
// concrete type implements interface
type intSlice []int
// method on concrete type satisfies interface method
func (s intSlice) iterator() func() (int, bool) {
i := 0
return func() (int, bool) {
if i >= len(s) {
return 0, false
}
v := s[i]
i++
return v, true
}
}
func main() {
fmt.Println(mode(intSlice{2, 7, 1, 8, 2}))
fmt.Println(mode(intSlice{2, 7, 1, 8, 2, 8}))
}
// mode is now a generic function, in a sense.
// It knows what to do with an intCollection,
// but does not know the underlying concrete type.
func mode(a intCollection) []int {
m := make(map[int]int)
i := a.iterator()
for {
v, ok := i()
if !ok {
break
}
m[v]++
}
var mode []int
var n int
for k, v := range m {
switch {
case v < n:
case v > n:
n = v
mode = append(mode[:0], k)
default:
mode = append(mode, k)
}
}
return mode
}
- Output:
[2] [8 2]
General collection, unspecified value type, Finally, the two kinds of generality can be combined. The iterator returned by the interface method now returns an empty interface rather than an int. The intSlice concrete type of the previous example is retained, but now it must satisfy this interface method that uses interface{} instead of int. runeList is added to illustrate how multiple types can satisfy the same interface.
package main
import "fmt"
type collection interface {
iterator() func() (interface{}, bool)
}
type intSlice []int
func (s intSlice) iterator() func() (interface{}, bool) {
i := 0
return func() (interface{}, bool) {
if i >= len(s) {
return 0, false
}
v := s[i]
i++
return v, true
}
}
type runeList string
func (s runeList) iterator() func() (interface{}, bool) {
c := make(chan rune)
go func() {
for _, r := range s {
c <- r
}
close(c)
}()
return func() (interface{}, bool) {
r, ok := <-c
return string(r), ok
}
}
func main() {
fmt.Println(mode(intSlice{2, 7, 1, 8, 2}))
fmt.Println(mode(runeList("Enzyklopädie")))
}
func mode(a collection) []interface{} {
m := make(map[interface{}]int)
i := a.iterator()
for {
v, ok := i()
if !ok {
break
}
m[v]++
}
var mode []interface{}
var n int
for k, v := range m {
switch {
case v < n:
case v > n:
n = v
mode = append(mode[:0], k)
default:
mode = append(mode, k)
}
}
return mode
}
- Output:
("Enzyklopädie" has no repeated letters. All are modal.)
[2] [e d i k l o n p y z E ä]
[edit] Groovy
Solution, both "collection type" and "element type" agnostic:
def mode(Iterable col) {
assert col
def m = [:]
col.each {
m[it] = m[it] == null ? 1 : m[it] + 1
}
def keys = m.keySet().sort { -m[it] }
keys.findAll { m[it] == m[keys[0]] }
}
Test:
def random = new Random()
def sourceList = [ 'Lamp', 42.0, java.awt.Color.RED, new Date(), ~/pattern/]
(0..10).each {
def a = (0..10).collect { sourceList[random.nextInt(5)] }
println "${mode(a)} == mode(${a})"
}
- Output:
[pattern] == mode([pattern, pattern, pattern, Lamp, pattern, Fri Oct 28 23:43:20 CDT 2011, java.awt.Color[r=255,g=0,b=0], Lamp, Lamp, Lamp, pattern]) [Lamp] == mode([Lamp, Fri Oct 28 23:43:20 CDT 2011, Lamp, java.awt.Color[r=255,g=0,b=0], 42.0, java.awt.Color[r=255,g=0,b=0], Fri Oct 28 23:43:20 CDT 2011, Lamp, pattern, pattern, 42.0]) [java.awt.Color[r=255,g=0,b=0]] == mode([java.awt.Color[r=255,g=0,b=0], java.awt.Color[r=255,g=0,b=0], 42.0, 42.0, Fri Oct 28 23:43:20 CDT 2011, Fri Oct 28 23:43:20 CDT 2011, 42.0, java.awt.Color[r=255,g=0,b=0], pattern, pattern, java.awt.Color[r=255,g=0,b=0]]) [Fri Oct 28 23:43:20 CDT 2011] == mode([Fri Oct 28 23:43:20 CDT 2011, pattern, 42.0, Fri Oct 28 23:43:20 CDT 2011, Lamp, pattern, Fri Oct 28 23:43:20 CDT 2011, java.awt.Color[r=255,g=0,b=0], 42.0, 42.0, Fri Oct 28 23:43:20 CDT 2011]) [Fri Oct 28 23:43:20 CDT 2011, Lamp] == mode([42.0, Fri Oct 28 23:43:20 CDT 2011, Lamp, Lamp, Fri Oct 28 23:43:20 CDT 2011, Fri Oct 28 23:43:20 CDT 2011, 42.0, Lamp, java.awt.Color[r=255,g=0,b=0], Lamp, Fri Oct 28 23:43:20 CDT 2011]) [java.awt.Color[r=255,g=0,b=0]] == mode([Fri Oct 28 23:43:20 CDT 2011, java.awt.Color[r=255,g=0,b=0], java.awt.Color[r=255,g=0,b=0], pattern, 42.0, java.awt.Color[r=255,g=0,b=0], java.awt.Color[r=255,g=0,b=0], 42.0, pattern, Fri Oct 28 23:43:20 CDT 2011, pattern]) [42.0, java.awt.Color[r=255,g=0,b=0]] == mode([42.0, java.awt.Color[r=255,g=0,b=0], pattern, Fri Oct 28 23:43:20 CDT 2011, Lamp, java.awt.Color[r=255,g=0,b=0], Lamp, Fri Oct 28 23:43:20 CDT 2011, java.awt.Color[r=255,g=0,b=0], 42.0, 42.0]) [Fri Oct 28 23:43:20 CDT 2011] == mode([java.awt.Color[r=255,g=0,b=0], pattern, Fri Oct 28 23:43:20 CDT 2011, Lamp, 42.0, Fri Oct 28 23:43:20 CDT 2011, Fri Oct 28 23:43:20 CDT 2011, pattern, java.awt.Color[r=255,g=0,b=0], Lamp, Fri Oct 28 23:43:20 CDT 2011]) [Fri Oct 28 23:43:20 CDT 2011] == mode([Fri Oct 28 23:43:20 CDT 2011, pattern, Fri Oct 28 23:43:20 CDT 2011, java.awt.Color[r=255,g=0,b=0], pattern, Fri Oct 28 23:43:20 CDT 2011, 42.0, java.awt.Color[r=255,g=0,b=0], Lamp, Fri Oct 28 23:43:20 CDT 2011, 42.0]) [pattern] == mode([42.0, pattern, pattern, Lamp, 42.0, Lamp, Fri Oct 28 23:43:20 CDT 2011, java.awt.Color[r=255,g=0,b=0], pattern, 42.0, pattern]) [Lamp, 42.0] == mode([Fri Oct 28 23:43:20 CDT 2011, pattern, Lamp, Lamp, Lamp, java.awt.Color[r=255,g=0,b=0], Fri Oct 28 23:43:20 CDT 2011, 42.0, 42.0, pattern, 42.0])
[edit] Icon and Unicon
The mode procedure generates all n mode values if the collection is n-modal.
procedure main(args)
every write(!mode(args))
end
procedure mode(A)
hist := table(0)
every hist[!A] +:= 1
hist := sort(hist, 2)
modeCnt := hist[*hist][2]
every modeP := hist[*hist to 1 by -1] do {
if modeCnt = modeP[2] then suspend modeP[1]
else fail
}
end
- Sample outputs:
->am 3 1 4 1 5 9 7 6 1 ->am 3 1 4 1 5 9 7 6 3 3 1 ->
[edit] J
mode=: ~. #~ ( = >./ )@( #/.~ )
Example:
mode 1 1 2 2 3 3 4 4 4 5 5 6 6 7 8 8 9 9 0 0 0 4 0
[edit] Java
import java.util.*;
public class Mode {
public static <T> List<T> mode(List<? extends T> coll) {
Map<T, Integer> seen = new HashMap<T, Integer>();
int max = 0;
List<T> maxElems = new ArrayList<T>();
for (T value : coll) {
if (seen.containsKey(value))
seen.put(value, seen.get(value) + 1);
else
seen.put(value, 1);
if (seen.get(value) > max) {
max = seen.get(value);
maxElems.clear();
maxElems.add(value);
} else if (seen.get(value) == max) {
maxElems.add(value);
}
}
return maxElems;
}
public static void main(String[] args) {
System.out.println(mode(Arrays.asList(1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17))); // prints [6]
System.out.println(mode(Arrays.asList(1, 1, 2, 4, 4))); // prints [1, 4]
}
}
[edit] JavaScript
function mode(ary) {
var counter = {};
var mode = [];
var max = 0;
for (var i in ary) {
if (!(ary[i] in counter))
counter[ary[i]] = 0;
counter[ary[i]]++;
if (counter[ary[i]] == max)
mode.push(ary[i]);
else if (counter[ary[i]] > max) {
max = counter[ary[i]];
mode = [ary[i]];
}
}
return mode;
}
mode([1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17]); // [6]
mode([1, 2, 4, 4, 1]); // [1,4]
[edit] K
mode: {(?x)@&n=|/n:#:'=x}
mode 1 1 1 1 2 2 2 3 3 3 3 4 4 3 2 4 4 4
3 4
[edit] Lua
function mode (numlist)
if type(numlist) ~= 'table' then return numlist end
local sets = {}
local mode
local modeValue = 0
table.foreach(numlist,function(i,v) if sets[v] then sets[v] = sets[v] + 1 else sets[v] = 1 end end)
for i,v in next,sets do
if v > modeValue then
modeValue = v
mode = i
else
if v == modeValue then
if type(mode) == 'table' then
table.insert(mode,i)
else
mode = {mode,i}
end
end
end
end
return mode
end
result = mode({1,3,6,6,6,6,7,7,12,12,17})
print(result)
result = mode({1, 1, 2, 4, 4})
if type(result) == 'table' then
for i,v in next,result do io.write(v..' ') end
print ()
end
[edit] Mathematica
Built-in function commonest returns a list of the most common element(s), even is there is only one 'commonest' number. Example for multiple 'commonest' numbers and a single 'commonest' number:
Commonest[{b, a, c, 2, a, b, 1, 2, 3}]
Commonest[{1, 3, 2, 3}]
- Output:
{b,a,2}
{3}
[edit] MATLAB
function modeValue = findmode(setOfValues)
modeValue = mode(setOfValues);
end
[edit] MUMPS
MODE(X)
;X is assumed to be a list of numbers separated by "^"
;I is a loop index
;L is the length of X
;Y is a new array
;ML is the list of modes
;LOC is a placeholder to shorten the statement
Q:'$DATA(X) "No data"
Q:X="" "Empty Set"
NEW Y,I,L,LOC
SET L=$LENGTH(X,"^"),ML=""
FOR I=1:1:L SET LOC=+$P(X,"^",I),Y(LOC)=$S($DATA(Y(LOC)):Y(LOC)+1,1:1)
SET I="",I=$O(Y(I)),ML=I ;Prime the pump, rather than test for no data
FOR S I=$O(Y(I)) Q:I="" S ML=$SELECT(Y($P(ML,"^"))>Y(I):ML,Y($P(ML,"^"))<Y(I):I,Y($P(ML,"^"))=Y(I):ML_"^"_I)
QUIT ML
USER>W $$MODE^ROSETTA("1^2^3^2")
2
USER>W $$MODE^ROSETTA("1^2^3^2^3")
2^3
USER>W $$MODE^ROSETTA("")
Empty Set
[edit] NetRexx
/* NetRexx */
options replace format comments java crossref symbols nobinary
run_samples()
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method mode(lvector = java.util.List) public static returns java.util.List
seen = 0
modes = ''
modeMax = 0
loop v_ = 0 to lvector.size() - 1
mv = Rexx lvector.get(v_)
seen[mv] = seen[mv] + 1
select
when seen[mv] > modeMax then do
modeMax = seen[mv]
modes = ''
nx = 1
modes[0] = nx
modes[nx] = mv
end
when seen[mv] = modeMax then do
nx = modes[0] + 1
modes[0] = nx
modes[nx] = mv
end
otherwise do
nop
end
end
end v_
modeList = ArrayList(modes[0])
loop v_ = 1 to modes[0]
val = modes[v_]
modeList.add(val)
end v_
return modeList
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method mode(rvector = Rexx[]) public static returns java.util.List
return mode(ArrayList(Arrays.asList(rvector)))
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method show_mode(lvector = java.util.List) public static returns java.util.List
modes = mode(lvector)
say 'Vector:' (Rexx lvector).space(0)', Mode(s):' (Rexx modes).space(0)
return modes
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method show_mode(rvector = Rexx[]) public static returns java.util.List
return show_mode(ArrayList(Arrays.asList(rvector)))
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method run_samples() public static
show_mode([Rexx 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]) -- 10 9 8 7 6 5 4 3 2 1
show_mode([Rexx 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0.11]) -- 0
show_mode([Rexx 30, 10, 20, 30, 40, 50, -100, 4.7, -11e+2]) -- 30
show_mode([Rexx 30, 10, 20, 30, 40, 50, -100, 4.7, -11e+2, -11e+2]) -- 30 -11e2
show_mode([Rexx 1, 8, 6, 0, 1, 9, 4, 6, 1, 9, 9, 9]) -- 9
show_mode([Rexx 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) -- 1 2 3 4 5 6 7 8 9 10 11
show_mode([Rexx 8, 8, 8, 2, 2, 2]) -- 8 2
show_mode([Rexx 'cat', 'kat', 'Cat', 'emu', 'emu', 'Kat']) -- emu
show_mode([Rexx 0, 1, 2, 3, 3, 3, 4, 4, 4, 4, 1, 0]) -- 4
show_mode([Rexx 2, 7, 1, 8, 2]) -- 2
show_mode([Rexx 2, 7, 1, 8, 2, 8]) -- 8 2
show_mode([Rexx 'E', 'n', 'z', 'y', 'k', 'l', 'o', 'p', 'ä', 'd', 'i', 'e']) -- E n z y k l o p ä d i e
show_mode([Rexx 'E', 'n', 'z', 'y', 'k', 'l', 'o', 'p', 'ä', 'd', 'i', 'e', 'ä']) -- ä
show_mode([Rexx 3, 1, 4, 1, 5, 9, 7, 6]) -- 1
show_mode([Rexx 3, 1, 4, 1, 5, 9, 7, 6, 3]) -- 3, 1
show_mode([Rexx 1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17]) -- 6
show_mode([Rexx 1, 1, 2, 4, 4]) -- 4 1
return
Output:
Vector: [10,9,8,7,6,5,4,3,2,1], Mode(s): [10,9,8,7,6,5,4,3,2,1] Vector: [10,9,8,7,6,5,4,3,2,1,0,0,0,0,0.11], Mode(s): [0] Vector: [30,10,20,30,40,50,-100,4.7,-1100], Mode(s): [30] Vector: [30,10,20,30,40,50,-100,4.7,-1100,-1100], Mode(s): [30,-1100] Vector: [1,8,6,0,1,9,4,6,1,9,9,9], Mode(s): [9] Vector: [1,2,3,4,5,6,7,8,9,10,11], Mode(s): [1,2,3,4,5,6,7,8,9,10,11] Vector: [8,8,8,2,2,2], Mode(s): [8,2] Vector: [cat,kat,Cat,emu,emu,Kat], Mode(s): [emu] Vector: [0,1,2,3,3,3,4,4,4,4,1,0], Mode(s): [4] Vector: [2,7,1,8,2], Mode(s): [2] Vector: [2,7,1,8,2,8], Mode(s): [2,8] Vector: [E,n,z,y,k,l,o,p,ä,d,i,e], Mode(s): [E,n,z,y,k,l,o,p,ä,d,i,e] Vector: [E,n,z,y,k,l,o,p,ä,d,i,e,ä], Mode(s): [ä] Vector: [3,1,4,1,5,9,7,6], Mode(s): [1] Vector: [3,1,4,1,5,9,7,6,3], Mode(s): [1,3] Vector: [1,3,6,6,6,6,7,7,12,12,17], Mode(s): [6] Vector: [1,1,2,4,4], Mode(s): [1,4]
[edit] Objeck
use Collection;
class Mode {
function : Main(args : String[]) ~ Nil {
Print(Mode([1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17]));
Print(Mode([1, 2, 4, 4, 1]));
}
function : Mode(coll : Int[]) ~ IntVector {
seen := IntMap->New();
max := 0;
maxElems := IntVector->New();
each(i : coll) {
value := coll[i];
featched := seen->Find(value)->As(IntHolder);
if(featched <> Nil) {
seen->Remove(value);
seen->Insert(value, IntHolder->New(featched->Get() + 1));
}
else {
seen->Insert(value, IntHolder->New(1));
};
featched := seen->Find(value)->As(IntHolder);
if(featched->Get() > max) {
max := featched->Get();
maxElems->Empty();
maxElems->AddBack(value);
}
else if(featched->Get() = max) {
maxElems->AddBack(value);
};
};
return maxElems;
}
function : Print(out : IntVector) ~ Nil {
'['->Print();
each(i : out) {
out->Get(i)->Print();
if(i + 1 < out->Size()) {
", "->Print();
};
};
']'->PrintLine();
}
}
[edit] Objective-C
#import <Foundation/Foundation.h>
@interface NSArray (Mode)
- (NSArray *)mode;
@end
@implementation NSArray (Mode)
- (NSArray *)mode {
NSCountedSet *seen = [NSCountedSet setWithArray:self];
int max = 0;
NSMutableArray *maxElems = [NSMutableArray array];
NSEnumerator *enm = [seen objectEnumerator];
id obj;
while( (obj = [enm nextObject]) ) {
int count = [seen countForObject:obj];
if (count > max) {
max = count;
[maxElems removeAllObjects];
[maxElems addObject:obj];
} else if (count == max) {
[maxElems addObject:obj];
}
}
return maxElems;
}
@end
[edit] OCaml
let mode lst =
let seen = Hashtbl.create 42 in
List.iter (fun x ->
let old = if Hashtbl.mem seen x then
Hashtbl.find seen x
else 0 in
Hashtbl.replace seen x (old + 1))
lst;
let best = Hashtbl.fold (fun _ -> max) seen 0 in
Hashtbl.fold (fun k v acc ->
if v = best then k :: acc
else acc)
seen []
# mode [1;3;6;6;6;6;7;7;12;12;17];; - : int list = [6] # mode [1;1;2;4;4];; - : int list = [4; 1]
[edit] Octave
Of course Octave has the mode function; but it returns only the "lowest" mode if multiple modes are available.
function m = mode2(v)
sv = sort(v);
% build two vectors, vals and c, so that
% c(i) holds how many times vals(i) appears
i = 1; c = []; vals = [];
while (i <= numel(v) )
tc = sum(sv==sv(i)); % it would be faster to count
% them "by hand", since sv is sorted...
c = [c, tc];
vals = [vals, sv(i)];
i += tc;
endwhile
% stack vals and c building a 2-rows matrix x
x = cat(1,vals,c);
% sort the second row (frequencies) into t (most frequent
% first) and take the "original indices" i ...
[t, i] = sort(x(2,:), "descend");
% ... so that we can use them to sort columns according
% to frequencies
nv = x(1,i);
% at last, collect into m (the result) all the values
% having the same bigger frequency
r = t(1); i = 1;
m = [];
while ( t(i) == r )
m = [m, nv(i)];
i++;
endwhile
endfunction
a = [1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17];
mode2(a)
mode(a)
a = [1, 1, 2, 4, 4];
mode2(a) % returns 1 and 4
mode(a) % returns 1 only
[edit] ooRexx
See the example at REXX, Version 2 for a version that returns multiple mode values.
-- will work with just about any collection...
call testMode .array~of(10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
call testMode .list~of(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, .11)
call testMode .queue~of(30, 10, 20, 30, 40, 50, -100, 4.7, -11e2)
::routine testMode
use arg list
say "list =" list~makearray~toString("l", ", ")
say "mode =" mode(list)
say
::routine mode
use arg list
-- this is a good application for a bag
-- add all of the items to the bag
collector = .bag~new
collector~putAll(list)
-- now get a list of unique items
indexes = .set~new~~putall(collector)
count = 0 -- this is used to keep track of the maximums
-- now see how many of each element we ended up with
loop index over indexes
items = collector~allat(index)
newCount = items~items
if newCount > count then do
mode = items[1]
count = newCount
end
end
return mode
[edit] Oz
declare
fun {Mode Xs}
Freq = {Dictionary.new}
for X in Xs do
Freq.X := {CondSelect Freq X 0} + 1
end
MaxCount = {FoldL {Dictionary.items Freq} Max 0}
in
for Value#Count in {Dictionary.entries Freq} collect:C do
if Count == MaxCount then
{C Value}
end
end
end
in
{Show {Mode [1 2 3 3 2 1 1]}}
{Show {Mode [1 2 3 3 2 1]}}
[edit] PARI/GP
mode(v)={
my(count=1,r=1,b=v[1]);
v=vecsort(v);
for(i=2,#v,
if(v[i]==v[i-1],
count++
,
if(count>r,
r=count;
b=v[i-1]
);
count=1
)
);
if(count>r,v[#v],b)
};
[edit] Perl
use strict;
use List::Util qw(max);
sub mode
{
my %c;
foreach my $e ( @_ ) {
$c{$e}++;
}
my $best = max(values %c);
return grep { $c{$_} == $best } keys %c;
}
print "$_ " foreach mode(1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17);
print "\n";
print "$_ " foreach mode(1, 1, 2, 4, 4);
print "\n";
[edit] Perl 6
sub mode (@a) {
my %counts;
++%counts{$_} for @a;
my $max = [max] values %counts;
return map { .key }, grep { .value == $max }, %counts.pairs;
}
[edit] PHP
Note: this function only works with strings and integers, as those are the only things that can be used as keys of an (associative) array in PHP.
<?php
function mode($arr) {
$count = array_count_values($arr);
$best = max($count);
return array_keys($count, $best);
}
print_r(mode(array(1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17)));
print_r(mode(array(1, 1, 2, 4, 4)));
?>
[edit] PicoLisp
(de modes (Lst)
(let A NIL
(for X Lst
(accu 'A X 1) )
(mapcar car
(maxi cdar
(by cdr group A) ) ) ) )
- Output:
: (modes (1 3 6 6 6 6 7 7 12 12 17))
-> (6)
: (modes (1 1 2 4 4))
-> (4 1)
: (modes (chop "ABRAHAMASANTACLARA"))
-> ("A")
: (modes (1 4 A 3 2 7 1 B B 3 6 2 4 C C 5 2 5 B A 3 2 C 3 5 5 4 C 7 7))
-> (5 C 2 3)
[edit] PowerShell
$data = @(1,1,1,2,3,4,5,5,6,7,7,7)
$groups = $data | group-object | sort-object count -Descending
$groups | ? {$_.Count -eq $groups[0].Count}
- Output:
Count Name Group
----- ---- -----
3 7 {7, 7, 7}
3 1 {1, 1, 1}
[edit] PureBasic
Procedure mean(Array InArray(1))
Structure MyMean
Value.i
Cnt.i
EndStructure
Protected i, max, found
Protected NewList MyDatas.MyMean()
Repeat
found=#False
ForEach MyDatas()
If InArray(i)=MyDatas()\Value
MyDatas()\Cnt+1
found=#True
Break
EndIf
Next
If Not found
AddElement(MyDatas())
MyDatas()\Value=InArray(i)
MyDatas()\cnt+1
EndIf
If MyDatas()\Cnt>max
max=MyDatas()\Cnt
EndIf
i+1
Until i>ArraySize(InArray())
ForEach MyDatas()
If MyDatas()\Cnt=max
For i=1 To max
Print(Str(MyDatas()\Value)+" ")
Next
EndIf
Next
EndProcedure
[edit] Python
The following solutions require that the elements be hashable.
>>> from collections import defaultdict
>>> def modes(values):
count = defaultdict(int)
for v in values:
count[v] +=1
best = max(count.values())
return [k for k,v in count.items() if v == best]
>>> modes([1,3,6,6,6,6,7,7,12,12,17])
[6]
>>> modes((1,1,2,4,4))
[1, 4]
>>> from collections import Counter
>>> def modes(values):
count = Counter(values)
best = max(count.values())
return [k for k,v in count.items() if v == best]
>>> modes([1,3,6,6,6,6,7,7,12,12,17])
[6]
>>> modes((1,1,2,4,4))
[1, 4]
If you just want one mode (instead of all of them), here's a one-liner for that:
def onemode(values):
return max(set(values), key=values.count)
[edit] R
statmode <- function(v) {
a <- sort(table(v), decreasing=TRUE)
r <- c()
for(i in 1:length(a)) {
if ( a[[1]] == a[[i]] ) {
r <- c(r, as.integer(names(a)[i]))
} else break; # since it's sorted, once we find
# a different value, we can stop
}
r
}
print(statmode(c(1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17)))
print(statmode(c(1, 1, 2, 4, 4)))
[edit] Racket
Returns values of list of modes and their frequencies of appearance.
#lang racket
(define (mode seq)
(define frequencies (make-hash))
(for ([s seq])
(hash-update! frequencies
s
(lambda (freq) (add1 freq))
0))
(for/fold ([ms null]
[freq 0])
([(k v) (in-hash frequencies)])
(cond [(> v freq)
(values (list k) v)]
[(= v freq)
(values (cons k ms) freq)]
[else
(values ms freq)])))
[edit] REXX
[edit] Version 1
Returns one mode value
/*REXX program finds the mode (most occurring element) of a vector. */
/*────────vector────────── ───show vector─── ────show result────── */
v='1 8 6 0 1 9 4 6 1 9 9 9' ; say 'vector='v; say 'mode='mode(v); say
v='1 2 3 4 5 6 7 8 9 10 11' ; say 'vector='v; say 'mode='mode(v); say
v='8 8 8 2 2 2' ; say 'vector='v; say 'mode='mode(v); say
v='cat kat Cat emu emu Kat' ; say 'vector='v; say 'mode='mode(v); say
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────MAKEARRAY subroutine────────────────*/
makeArray: procedure expose @.; parse arg v; @.0=words(v) /*make array*/
do k=1 for @.0; @.k=word(v,k); end /*k*/
return
/*──────────────────────────────────ESORT subroutine────────────────────*/
esort: procedure expose @.; h=@.0 /*exchange sort.*/
do while h>1; h=h%2
do i=1 for @.0-h; j=i; k=h+i
do while @.k<@.j;t=@.j;@.j=@.k;@.k=t;if h>=j then leave;j=j-h;k=k-h;end
end /*i*/
end /*while h>1*/
return
/*──────────────────────────────────MODE subroutine─────────────────────*/
mode: procedure expose @.; parse arg x /*finds the MODE of a vector. */
call makeArray x /*make an array out of the vector*/
call esort @.0 /*sort the array elements. */
?=@.1 /*assume 1st element is the mode.*/
freq=1 /*the frequency of the occurance.*/
do j=1 for @.0; _=j-freq
if @.j==@._ then do
freq=freq+1 /*bump the frequency count. */
?=@.j /*this is the one. */
end
end /*j*/
return ?
output
vector=1 8 6 0 1 9 4 6 1 9 9 9 mode=9 vector=1 2 3 4 5 6 7 8 9 10 11 mode=1 vector=8 8 8 2 2 2 mode=2 vector=cat kat Cat emu emu Kat mode=emu
[edit] Version 2
Displays all modes if there are more than one.
/* Rexx */
-- ~~ main ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
call run_samples
return
exit
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- returns a comma separated string of mode values from a comma separated input vector string
mode:
procedure
parse arg lvector
drop vector.
vector. = ''
call makeStem lvector -- this call creates the "vector." stem from the input string
seen. = 0
modes. = ''
modeMax = 0
do v_ = 1 to vector.0
mv = vector.v_
seen.mv = seen.mv + 1
select
when seen.mv > modeMax then do
modeMax = seen.mv
drop modes.
modes. = ''
nx = 1
modes.0 = nx
modes.nx = mv
end
when seen.mv = modeMax then do
nx = modes.0 + 1
modes.0 = nx
modes.nx = mv
end
otherwise do
nop
end
end
end v_
lmodes = ''
do e_ = 1 to modes.0
lmodes = lmodes modes.e_
end e_
lmodes = strip(space(lmodes, 1, ','))
return lmodes
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- pretty-print
show_mode:
procedure
parse arg lvector
lmodes = mode(lvector)
say 'Vector: ['space(lvector, 0)'], Mode(s): ['space(lmodes, 0)']'
return modes
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- load the "vector." stem from the comma separated input vector string
makeStem:
procedure expose vector.
vector.0 = 0
parse arg lvector
do v_ = 1 while lvector \= ''
parse var lvector val ',' lvector
vector.0 = v_
vector.v_ = strip(val)
vector = strip(lvector)
end v_
return vector.0
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
run_samples:
procedure
call show_mode '10, 9, 8, 7, 6, 5, 4, 3, 2, 1' -- 10 9 8 7 6 5 4 3 2 1
call show_mode '10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0.11' -- 0
call show_mode '30, 10, 20, 30, 40, 50, -100, 4.7, -11e+2' -- 30
call show_mode '30, 10, 20, 30, 40, 50, -100, 4.7, -11e+2, -11e+2' -- 30 -11e2
call show_mode '1, 8, 6, 0, 1, 9, 4, 6, 1, 9, 9, 9' -- 9
call show_mode '1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11' -- 1 2 3 4 5 6 7 8 9 10 11
call show_mode '8, 8, 8, 2, 2, 2' -- 8 2
call show_mode 'cat, kat, Cat, emu, emu, Kat' -- emu
call show_mode '0, 1, 2, 3, 3, 3, 4, 4, 4, 4, 1, 0' -- 4
call show_mode '2, 7, 1, 8, 2' -- 2
call show_mode '2, 7, 1, 8, 2, 8' -- 8 2
call show_mode 'E, n, z, y, k, l, o, p, ä, d, i, e' -- E n z y k l o p ä d i e
call show_mode 'E, n, z, y, k, l, o, p, ä, d, i, e, ä' -- ä
call show_mode '3, 1, 4, 1, 5, 9, 7, 6' -- 1
call show_mode '3, 1, 4, 1, 5, 9, 7, 6, 3' -- 3, 1
call show_mode '1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17' -- 6
call show_mode '1, 1, 2, 4, 4' -- 4 1
return
Output:
Vector: [10,9,8,7,6,5,4,3,2,1], Mode(s): [10,9,8,7,6,5,4,3,2,1] Vector: [10,9,8,7,6,5,4,3,2,1,0,0,0,0,0.11], Mode(s): [0] Vector: [30,10,20,30,40,50,-100,4.7,-11e+2], Mode(s): [30] Vector: [30,10,20,30,40,50,-100,4.7,-11e+2,-11e+2], Mode(s): [30,-11e+2] Vector: [1,8,6,0,1,9,4,6,1,9,9,9], Mode(s): [9] Vector: [1,2,3,4,5,6,7,8,9,10,11], Mode(s): [1,2,3,4,5,6,7,8,9,10,11] Vector: [8,8,8,2,2,2], Mode(s): [8,2] Vector: [cat,kat,Cat,emu,emu,Kat], Mode(s): [emu] Vector: [0,1,2,3,3,3,4,4,4,4,1,0], Mode(s): [4] Vector: [2,7,1,8,2], Mode(s): [2] Vector: [2,7,1,8,2,8], Mode(s): [2,8] Vector: [E,n,z,y,k,l,o,p,ä,d,i,e], Mode(s): [E,n,z,y,k,l,o,p,ä,d,i,e] Vector: [E,n,z,y,k,l,o,p,ä,d,i,e,ä], Mode(s): [ä] Vector: [3,1,4,1,5,9,7,6], Mode(s): [1] Vector: [3,1,4,1,5,9,7,6,3], Mode(s): [1,3] Vector: [1,3,6,6,6,6,7,7,12,12,17], Mode(s): [6] Vector: [1,1,2,4,4], Mode(s): [1,4]
[edit] Ruby
Here's two methods, the first more Ruby-ish, the second perhaps a bit more efficient.
def mode(ary)
seen = Hash.new(0)
ary.each {|value| seen[value] += 1}
max = seen.values.max
seen.find_all {|key,value| value == max}.map {|key,value| key}
end
def mode_one_pass(ary)
seen = Hash.new(0)
max = 0
max_elems = []
ary.each do |value|
seen[value] += 1
if seen[value] > max
max = seen[value]
max_elems = [value]
elsif seen[value] == max
max_elems << value
end
end
max_elems
end
p mode([1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17]) # => [6]
p mode([1, 1, 2, 4, 4]) # => [1, 4]
p mode_one_pass([1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17]) # => [6]
p mode_one_pass([1, 1, 2, 4, 4]) # => [1, 4]
If you just want one mode (instead of all of them), here's a one-liner for that:
def one_mode(ary)
ary.max_by { |x| ary.count(x) }
end
[edit] Scala
Receiving any collection is easy. Returning the result in the same collection takes some doing.
import scala.collection.breakOut
import scala.collection.generic.CanBuildFrom
def mode
[T, CC[X] <: Seq[X]](coll: CC[T])
(implicit o: T => Ordered[T], cbf: CanBuildFrom[Nothing, T, CC[T]])
: CC[T] = {
val grouped = coll.groupBy(x => x).mapValues(_.size).toSeq
val max = grouped.map(_._2).max
grouped.filter(_._2 == max).map(_._1)(breakOut)
}
[edit] Scheme
(define (mode collection)
(define (helper collection counts)
(if (null? collection)
counts
(helper (remove (car collection) collection)
(cons (cons (car collection)
(appearances (car collection) collection)) counts))))
(map car
(filter (lambda (x) (= (cdr x) (apply max (map cdr (helper collection '())))))
(helper collection '())))
[edit] Seed7
The example below defines the template function createModeFunction, which defines the function mode.
The template createModeFunction is instantiated explicit with createModeFunction(integer).
Additionally to mode the function str is defined.
The function str is used by the template function
enable_output to allow writing arrays.
This way the main function can just write the mode.
$ include "seed7_05.s7i";
const proc: createModeFunction (in type: elemType) is func
begin
const func array elemType: mode (in array elemType: data) is func
result
var array elemType: maxElems is 0 times elemType.value;
local
var hash [elemType] integer: counts is (hash [elemType] integer).value;
var elemType: aValue is elemType.value;
var integer: maximum is 0;
begin
for aValue range data do
if aValue in counts then
incr(counts[aValue]);
else
counts @:= [aValue] 1;
end if;
if counts[aValue] > maximum then
maximum := counts[aValue];
maxElems := [] (aValue);
elsif counts[aValue] = maximum then
maxElems &:= aValue;
end if;
end for;
end func;
const func string: str (in array elemType: data) is func
result
var string: result is "";
local
var elemType: anElement is elemType.value;
begin
for anElement range data do
result &:= " " & str(anElement);
end for;
result := result[2 ..];
end func;
enable_output(array elemType);
end func;
createModeFunction(integer);
const proc: main is func
begin
writeln(mode([] (1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17)));
writeln(mode([] (1, 1, 2, 4, 4)));
end func;
- Output:
6 1 4
[edit] Slate
s@(Sequence traits) mode
[| sortedCounts |
sortedCounts: (s as: Bag) sortedCounts.
(sortedCounts mapSelect: [| :count :elem | sortedCounts last count = count]) valueSet
].
[edit] Smalltalk
This code is able to find the mode of any collection of any kind of object.
OrderedCollection extend [
mode [ |s|
s := self asBag sortedByCount.
^ (s select: [ :k | ((s at: 1) key) = (k key) ]) collect: [:k| k value]
]
].
#( 1 3 6 6 6 6 7 7 12 12 17 ) asOrderedCollection
mode displayNl.
#( 1 1 2 4 4) asOrderedCollection
mode displayNl.
[edit] Tcl
# Can find the modal value of any vector of values
proc mode {n args} {
foreach n [list $n {*}$args] {
dict incr counter $n
}
set counts [lsort -stride 2 -index 1 -decreasing $counter]
set best {}
foreach {n count} $counts {
if {[lindex $counts 1] == $count} {
lappend best $n
} else break
}
return $best
}
# Testing
puts [mode 1 3 6 6 6 6 7 7 12 12 17]; # --> 6
puts [mode 1 1 2 4 4]; # --> 1 4
Note that this works for any kind of value.
[edit] UNIX Shell
#!/bin/bash
function mode {
declare -A map
max=0
for x in "$@"; do
tmp=$((${map[$x]} + 1))
map[$x]=$tmp
((tmp > max)) && max=$tmp
done
for x in "${!map[@]}"; do
[[ ${map[$x]} == $max ]] && echo -n "$x "
done
echo
}
mode 1 2 1 2 a b a b a 2
a 2
[edit] Ursala
The mode function defined below works on lists of any type and returns a list of the modes. There is no concept of a general collection in Ursala. The algorithm is to partition the list by equality, then partition the classes by their lengths, and then select a representative from each member of the set of classes with the maximum length.
#import std
mode = ~&hS+ leql$^&h+ eql|=@K2
#cast %nLW
examples = mode~~ (<1,3,6,6,6,7,7,12,12,17>,<1,1,2,4,4>)
The function is tested on a pair of lists, one with a unique mode and one with multiple modes.
- Output:
(<6>,<4,1>)
[edit] Vedit macro language
Current edit buffer stores the collection. Each line is an item in the collection. The items can be any type (ascii text, numeric values in ascii, binary values). However, binary file with fixed record length would require some modifications to the code.
The "mode" item and it's count are displayed on status line. If there are multiple items with the same count, the smallest one is displayed.
BOF // Copy all data to a new buffer
Reg_Copy(10, ALL)
Buf_Switch(Buf_Free)
Reg_Ins(10)
Sort(0, File_Size) // Sort the data
BOF
repeat(ALL) { // Count & delete duplicate lines
#1 = 1
while(Match("^{.*}\N\1$", REGEXP)==0) {
Del_Line(1)
#1++
}
Num_Ins(#1, NOCR) // Insert item count at the beginning of line
Ins_Char(9) // TAB
Line(1, ERRBREAK) // Next (different) line
}
Sort(0, File_Size, REVERSE) // Sort according to the count
BOF // Display the results
Reg_Copy_Block(10, CP, EOL_pos)
Buf_Quit(OK)
Statline_Message(@10)
[edit] XEmacs Lisp
This returns a list of the modes. Any type(s) of data can be passed in, and any "equal" predicate function can be specified.
(defun mode ( predicate &rest values)
"Finds the mode of all values passed in.
Uses `predicate' to compare items."
(let ((modes nil) ; Declare local variables
(mode-count 0)
(value-list nil)
current-value)
(loop for value in values do
(if (setq current-value (assoc* value value-list :test predicate)) ; Construct a linked list of cons cells, (value . count)
(incf (cdr current-value))
(push (cons value 1) value-list)))
(loop for (value . count) in value-list do ; Find modes in linked list
(if (> count mode-count)
(setq modes (list value)
mode-count count)
(when (eq count mode-count)
(push value modes))))
modes))
- Programming Tasks
- Probability and statistics
- ActionScript
- Ada
- AutoHotkey
- AWK
- BBC BASIC
- C
- C++
- C sharp
- Clojure
- CoffeeScript
- Common Lisp
- D
- E
- Elena
- Erlang
- Euphoria
- F Sharp
- Factor
- Fortran
- Haskell
- GAP
- Go
- Groovy
- Icon
- Unicon
- J
- Java
- JavaScript
- K
- Lua
- Mathematica
- MATLAB
- MUMPS
- NetRexx
- Objeck
- Objective-C
- OCaml
- Octave
- OoRexx
- Oz
- PARI/GP
- Perl
- Perl 6
- PHP
- PicoLisp
- PowerShell
- PureBasic
- Python
- R
- Racket
- REXX
- Ruby
- Scala
- Scheme
- Seed7
- Slate
- Smalltalk
- Tcl
- UNIX Shell
- Ursala
- Vedit macro language
- XEmacs Lisp