Межквартильное среднее

26

задача

Учитывая (любым способом) отсортированный набор данных с плавающей запятой, верните (любым способом и в пределах 1 ‰ от правильного значения) среднее значение четверти .

Один возможный алгоритм

  1. Откажитесь от самых низких и самых высоких четвертей точек данных.
  2. Рассчитать среднее (сумма, деленная на количество) оставшихся точек данных.

Примечание. Если размер набора данных не делится поровну на четыре, вам придется взвесить точки данных , которые совместно используются подмножествами. См. Пример оценки 2 ниже.

Пример оценки 1

Даны {1, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 38}

  1. Количество данных равно 12, поэтому мы удаляем самые низкие и самые высокие 3 точки данных:
    { 1, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 38 }
  2. Среднее из оставшихся 6 точек данных:
    (5 + 6 + 6 + 7 + 7 + 8) / 6 = 6,5

Пример оценки 2

Дано {1, 3, 5, 7, 9, 11, 13, 15, 17}

  1. Число равно 9, поэтому в каждом квартале есть 2¼ точек данных:
    { 1, 2, (0,25 × 5), (0,75 × 5), 7, 9, 11, (0,75 × 13), (0,25 × 13), 15, 17 }
  2. Среднее из оставшихся 4,5 точек данных:
    (0,75 × 5 + 7 + 9 + 11 + 0,75 × 13) / 4,5 = 9
Адам
источник

Ответы:

5

Scilab, 8 байт

trimmean

Смотрите документацию . По умолчанию, discard=50так что IQM вычисляется.

РЕДАКТИРОВАТЬ: Вы знаете, это тривиальный встроенный ответ, поэтому я помечаю его как CW .

Линн
источник
Я думаю, что это будет победителем. Отлично сработано.
Адам
8

Pyth , 11 10 байт

.O> <LqS * 4Ql
.OsPtc4S * 4

Тестирование.

Как это работает

Это приводит к четырехкратному дублированию списка ввода, чтобы гарантировать, что количество данных делится на 4.

Это все еще нуждается в сортировке, потому что *4применяется ко всему списку, а не к каждому отдельному элементу.

Затем он разбивает список на четыре равные части, а затем убирает первую и последнюю часть.

Оставшийся список сглаживается, а среднее берется.

Дрянная Монахиня
источник
8

MATL , 12 11 байт

4Y"G"6L)]Ym

Ввод представляет собой горизонтальный вектор с форматом

[1, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 38]

или

[1 3 4 5 6 6 7 7 8 8 9 38]

Попробуйте онлайн!

объяснение

4Y"    % Input horizontal vector implicitly. Repeat each element 4 times (run-length
       % decoding). The resulting array is still sorted.
G"     % Push input, for each: repeat as many times as the input size
  6L)  %   Remove first and last elements, by applying the index "2:end-1"
]      % End for each
Ym     % Compute mean. Display implicitly
Луис Мендо
источник
Я не понимаю Как 6L)убрать первый и последний элементы? Когда я делаю это, это сбивает кучу сложных чисел.
DJMcMayhem
5
@DrGreenEggsandIronMan Для этого в MATL могут использоваться комплексные числа. Мнимая единица обозначает конец массива, и если есть два из трех чисел, они определяют диапазон. Так что [2, -1+i]при использовании в качестве индексного средства2:end-1
Луис Мендо
7

Снеговик , 66 байт

}vg","aS:10sB;aM4aRAsOal`,4nD,`aG0AaGal`NdE`AaL1AfL:nA;alaF,nDtSsP

Попробуйте онлайн!

Использует тот же алгоритм, что и ответы @LeakyNun .

}         enable variables b, e, and g
vg        read a line of input into b
","aS     split on commas (in-place)
:10sB;aM  convert each element in resulting array to number ("frombase(10)-map")
4aR       repeat the array 4 times
AsO       sort the array
al        take the length and put it in e without consuming b (the array)
`,        swap b and e, then move e to g; now b=length g=array
4nD       divide b by 4 (4 was stored in e, which is why the array was moved)
,`        move the array and length/4 back to their original positions
aG        split the array into groups of length (length/4)
0AaG      take all elements with index >0 (i.e. remove the first element)
al        store the length of the new array in e again
`NdE`     bring it up to b, decrement, and put it back
AaL       take all elements with index <length-1 (i.e. remove last)
1AfL      flatten the array 1 level deep
:nA;      push a block that adds two numbers (to e)
al        store the length of this new array in g
aF        fold b over e (sum the numbers)
,         move g (the length) into e
nD        divide the sum by the length, resulting in the average
tSsP      to-string and print
Дверная ручка
источник
2
Этот язык выглядит ужасно. Я люблю это.
Мего
5

Желе , 14 13 12 байт

x4ṫL '$ ḣLN $ S ÷ LH 
x4ṫLḊḣLN $ S ÷ LH
x4œs4ḊṖFS ÷ LH

Попробуйте онлайн!

Тестирование.

Как это работает

Это перевод моего ответа в Pyth .

Дрянная Монахиня
источник
Я почти уверен, что это можно сократить, поскольку я могу сделать это 15 в APL.
Адам
@ Adám Пожалуйста, опубликуйте свое решение (чтобы я мог скопировать его)
Leaky Nun
Я хочу дать
Маринусу
Ну вот!
Адам
Достаточно шансов после более чем 9 месяцев, конечно
Луис Мендо
4

Брахилог , 21 байт

:3jo@4brbcLl/N,L+:N*.

Попробуйте онлайн! или проверить несколько тестовых случаев

объяснение

Это в основном алгоритм ответа Pyth @ LeakyNun.

:3j      Append 3 copies of the input to itself
o@4      Sort and split in 4 lists of equal length
brb      Remove the head and the tail of the list of lists
cL       Concatenate the 2 sublists into a list L
l/N,     N is the inverse of the length of L
L+:N*.   Output is the product of N and the sum of the elements of L

Единственный маленький трюк заключается в умножении на обратную величину длины вместо деления на длину, потому что деление между двумя целыми числами является целочисленным делением.

Fatalize
источник
3

Октава , 44 байта

@(x)mean(reshape(~~(1:4)'*x,[],4)(:,2:3)(:))

Это определяет анонимную функцию.

Вход представляет собой горизонтальный вектор.

Попробуйте это на Ideone .

объяснение

Входной горизонтальный вектор сначала умножается матрицей ( *) на вектор столбцов из четырех (построенный с ~~(1:4)'). В результате получается матрица из четырех столбцов, где каждая строка является копией входного вектора. Затем он преобразуется, сохраняя линейный порядок элементов, в матрицу из 4 столбцов ( reshape(...,[],4)). Центральные два столбца сохраняются ( (:,2:3)) и линеаризуются в один столбец ( (:)), из которого вычисляется среднее значение ( mean(...)).

Луис Мендо
источник
Вы можете сохранить 1 байт с более читабельным [x;x;x;x]вместо~~(1:4)'*x
Том Карпентер
@(x)mean([x;x;x;x](:)((b=numel(x))+1:3*b))также на 2 байта меньше. Вот почему я придумал, но это в основном так же, как ваш подход.
Том Карпентер
@ TomCarpenter Я не думаю, что это так похоже. Я думаю, что вы должны опубликовать это как отдельный ответ
Луис Мендо
3

J , 20 18 байт

2 байта благодаря @miles

# -:.. @% ~ - @ # + / @} #} 4 #]
- @ # (+ /% #) @}} # 4 #]..

Попробуйте онлайн! ( Онлайн переводчик )

использование

>> f =: -@#(+/%#)@}.#}.4#]
>> f 1 3 5 7 9 11 13 15 17
<< 9

Как это работает

Это перевод моего ответа в Pyth .

Дрянная Монахиня
источник
@ Adám Спасибо, добавил.
Утренняя монахиня
2
Вы можете просто взять среднее значение средней части -@#(+/%#)@}.#}.4#]за 18 байт .
миль
2

На самом деле , 20 15 13 байт

; l╗; +; + S╜ @ t╜τ @ HΣ╜τ @ / 
; l; τ; a; +; + StHΣ /
; Л; τ; aττStHΣ /

Попробуйте онлайн!

Как это работает

Это перевод моего ответа в Pyth .

Дрянная Монахиня
источник
На этот раз, на самом деле ответ, который читается (по-гречески).
Адам
@ Adám Pyth использует ASCII.
Утренняя монахиня
2

Октава, 42 байта

Еще одна анонимная функция для Octave.

@(x)mean([x;x;x;x](:)((b=numel(x))+1:3*b))

Вы можете попробовать это онлайн . Просто введите эту команду, а затем введите ans([1 2 4 5 6 9])или какие-либо цифры, необходимые.

Этот начинается с создания из входного массива одного с 4-мя каждым входным элементом, сначала конкатенируя четыре копии по вертикали, а затем выравнивая по вертикали. Это поддерживает порядок сортировки.

Затем он извлекает диапазон элементов из длины входного массива плюс от 1 до трехкратной длины входного массива. Поскольку новый массив в четыре раза длиннее, это отсекает верхний и нижний квартили.

Наконец, возвращается среднее значение нового массива.

Том Карпентер
источник
2

05AB1E, 15 байтов

€D€D¹gô¦¨˜DOsg/

объяснение

€D€D             # quadruple each element in list
    ¹gô          # split into pieces the size of input
       ¦¨˜       # remove the first and last and flatten the middle 2
          DOsg/  # sum and divide by length

Попробуйте онлайн

Emigna
источник
2

APL (Dyalog) , 15 байтов

IQM←(+/÷≢)≢↓-∘≢↓4∘/

Попробуйте онлайн!

4∘/ дублировать каждый элемент

-∘≢↓ отбросить столько конечных элементов, сколько есть элементов в аргументах

≢↓ отбросить столько ведущих элементов, сколько есть элементов в аргументе

() Применить следующую молчаливую функцию:

+/ сумма

÷ деленное на

 подсчет

Адам
источник
1

JavaScript (ES6), 75 байт

a=>a.concat(a,a,a).sort(g=(x,y)=>x-y).slice(l=a.length,-l).reduce(g,0)/l/-2

Использует очевидный подход с четырьмя дубликатами и сортировкой, и я использую reduce, что приятно. Единственная хитрость здесь состоит в том, чтобы сохранить 4 байта, повторно используя компаратор сортировки, чтобы вычесть все элементы массива из нуля, что дает мне -2lвремя, которое я хочу получить.

Нил
источник
1

На самом деле, 12 байтов

4α;l¼≈;±(Htæ

Попробуйте онлайн! (в настоящее время не работает, потому что TIO отстает от нескольких версий)

Объяснение:

4α;l¼≈;±(Htæ
4α            repeat each element 4 times
  ;l¼≈        length divided by 4, as integer
      ;±      copy, unary negate
        (Ht   remove first and last quartiles
           æ  mean
Mego
источник
1

Mathematica, 51 байт

Mean@#[[(l=1+Length@#/4);;-l]]&@Sort@Join[#,#,#,#]&

Сортирует четыре копии списка (чтобы избежать проблем с длиной списка, не кратной четырем), принимает участие "1 quarter the length of resulting list plus 1"в "1/4 length list + 1 from the end", принимает их Mean.

LLlAMnYP
источник
1

Java 146 126 байт

Такая ява многословна!

float m(float[]n){float r=0;int l=n.length,i=l/4;r-=(n[i])*(l%4)/4;r+=n[i*3]*(4-(l%4))/4;for(;i<l*3/4;r+=n[i],i++);return r/l*2;}

Старые Ungolfed частично читаемые с тестовыми примерами

/**
 *
 * @author rohan
 */
public Golf{

float m(float[]n){
//declarations 
float r=0;
int x,i=0,l=n.length;
//sum the array 
for(float m:n){r+=m;}
//remove the excess
for(;i<l/4;r-=n[i]+n[l-i-1],i++);
//weight the quartiles
r-=(n[l/4]+n[l*3/4])*(l%4)/4;
//return the sum/length but multiply by two since only half of the set is averaged
return r/l*2;
    }
static void interQuartileMean(float... set){
    System.out.println(new Golf().m(set));
}
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
    //test cases pass with flying colours
        interQuartileMean(1, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 38);
        interQuartileMean(1, 3, 5, 7, 9, 11, 13, 15, 17);   
    }

}
Рохан Джунджхунвала
источник
1

Clojure, 82 81 байт

Изменить: на 1 байт меньше, переписав часть "didvide by 2 n".

#(let[n(count %)](*(/ n)0.5(apply +(subvec(vec(for[i % j(range 4)]i))n(* 3 n)))))

Предыдущая:

#(let[n(count %)](/(apply +(subvec(vec(for[i % j(range 4)]i))n(* 3 n)))(* 2.0 n)))

Использует forдля генерации 4 повторных значений, используя float, 2.0чтобы не иметь дробных результатов, остальное просто стандартно.

NikoNyrh
источник
1

R, 17 11 байт

mean(n,0.25)

Предполагается n, что входной вектор в стандартной форме Rn=c(1, 2, 3, ...) .

Это ни в коем случае не удивительно, поскольку R можно считать «языком статистических вычислений» и имеет множество встроенных статистических данных.

ОБНОВИТЬ. Благодаря rturnbull сохранено 6 байт, поскольку trimпо умолчанию это первый необязательный аргумент!

Тестовые случаи:

a <- c(1, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 38)
b <- c(1, 3, 5, 7, 9, 11, 13, 15, 17)
mean(a,trim=0.25) # Returns 6.5
mean(b,trim=0.25) # Returns 9
Андрей Костырка
источник
Поскольку trimэто второй аргумент по умолчанию, вам не нужно его называть; 0.25можно сократить до .25или 1/4. Это экономит вам шесть байтов.
rturnbull
0

Excel, 17 байт

=TRIMMEAN(A:A,.5)

Удобный формат ввода делает это легко. Введите один в строке в столбце А.

Wernisch
источник