Отказ от ответственности: среднее значение составлено мной
Определите среднее арифметическое чисел как
Определите среднее геометрическое чисел как
Определить среднее гармоническое для n чисел как
M _ {- 1} (x_1, ..., x_n) = \ frac {n} {\ frac {1 } {x_2} + \ frac {1} {x_2} + ... + \ frac {1} {x_n}}
Определить среднеквадратичное значение n чисел как
M_2 (x_1, ..., x_n) = \ root \ of {\ frac {x_1 ^ 2 + x_2 ^ 2 + ... + x_n ^ 2} {n}}
Среднее значение ( M_M ) определяется следующим образом: Определите четыре последовательности ( a_k, b_k, c_k, d_k ) какNM1(х1, . , , , хN) = х1+ х2+ . , , + хNN
NM0( х1, . , , , хN) = х1Икс2, , , ИксN--------√N
NM- 1( х1, . , , , хN) = n1Икс2+ 1Икс2+ . , , + 1ИксN
NM2( х1, . , , , хN) = х21+ х22+ . , , + х2NN--------------√
MMк,Ьк,ск,dKс0=М1(х1,...,хп),ak,bk,ck,dka0=M1(x1,...,xn),b0=M0(x1,...,xn),c0=M−1(x1,...,xn),d0=M2(x1,...,xn),ak+1=M1(ak,bk,ck,dk),bk+1=M0(ak,bk,ck,dk),ck+1=M−1(ak,bk,ck,dk),dk+1=M2(ak,bk,ck,dk)
Все четыре последовательности сходятся к тот же номер,MM(x1,x2,...,xn) .
пример
Среднее значение 1 и 2 рассчитывается следующим образом: начните с a0=(1+2)/2=1.5,b0=1∗2−−−−√=2–√≈1.4142,c0=211+12=43≈1.3333,d0=12+222−−−−−−−√=52−−√≈1.5811.
Тогда
a1= 1,5 + 1,4142 + 1,3333 + 1,58114≈ 1,4571 ,б1= 1,5 * 1,4142 * 1,3333 * 1,5811-----------------------√4≈ 1,4542 ,с1= 411,5+ 11,4142+ 11,3333+ 11,5811≈ 1,4512 ,d1= 1,52+ 1.41422+ 1.33332+ 1.581124----------------------------√≈ 1,4601.
Дальнейший расчет последовательностей должен быть понятен. Видно, что они сходятся к одному и тому же числу, примерно 1.45568889 .
Вызов
Для двух положительных действительных чисел a и б ( а < б ) вычислите их среднее значение MM( а , б ) .
Контрольные примеры
1 1 => 1
1 2 => 1.45568889
100 200 => 145.568889
2.71 3.14 => 2.92103713
0.57 1.78 => 1.0848205
1.61 2.41 => 1.98965438
0.01 100 => 6.7483058
Заметки
- Ваша программа действительна, если разница между ее выходом и правильным выходом не превышает 1/100000 от абсолютного значения разности между входными числами.
- На выходе должно быть одно число.
Это код-гольф , поэтому выигрывает самый короткий код!
Ответы:
Wolfram Language (Mathematica) , 52 байта
Попробуйте онлайн!
В моем первом подходе я использовал эти встроенные функции
Mean
GeometricMean
HarmonicMean
иRootMeanSquare
Вот некоторые замены для сохранения байтов
HarmonicMean
->1/Mean[1/x]
от @Robin Ryder (сохранено 3 байта)GeometricMean
->E^Mean@Log@x
от @A. Рекс (2 байта сохранены)RootMeanSquare
->Mean[x^2]^.5
@A. Рекс (4 байта сохранены)наконец , мы можем приписать
Mean
кM
(как это было предложено @ovs) и сохранить более 5 байтисточник
#//.x_:>N@{Mean@x,E^Mean@Log@x,1/Mean[1/x],Mean[x^2]^.5}&
R
706967 байтПопробуйте онлайн!
-1 байт с лучшей подготовкой.
-2 байта при переключении на базу 2.
Как и некоторые другие ответы, здесь используется выражение среднего геометрического в качестве среднего арифметического на логарифмической шкале (здесь, в базе 2):M0( х1, … , ХN) = 2M1( журнал2Икс1, … , Журнал2ИксN),
Также используется тот факт, что∀ к , дК≥ аК≥ бК≥ cК , то есть dК= Макс (К, бК, сК, дК) . Следовательно, условие aК= бК= сК= дК эквивалентно dК= М1( аК, бК, сК, дК) , что я и использую в цикле while; это достигается путем злоупотребления синтаксисом,сК вместо этого, так как это минимум из четырех, но мы не могли использоватьaК илибК в условии.)
while
который учитывает первый элемент, только когда условие является вектором, отсюда и порядок, в котором хранятся средства. (Обратите внимание, что мы могли бы также использоватьКогда мы выходим из цикла while,
x
это постоянный вектор. Финал?x
вычисляет его значение, чтобы уменьшить его до скаляра.источник
J , 34 байта
(31 как выражение без присваивания переменной
f
)Попробуйте онлайн!
Для функций
a
иb
,a &.: b
( «а при Ь» ( связанная с этим проблема )) равносильна(b inv) a b
- применить Ь, то а, то обратный Ь. В этом случае среднее геометрическое / гармоническое / квадратичное - это среднее арифметическое «под» логарифмом, инверсией и квадратом соответственно.источник
TI-BASIC,
423534 байта-1 байт благодаря @SolomonUcko
Ввод представляет собой список из двух целых чисел в
Ans
.Вывод сохраняется
Ans
и автоматически распечатывается по завершении программы.Формулы, используемые для геометрических, гармонических и квадратичных средних, основаны на объяснениях пользователя 202729 .
Пример:
Пояснение:
(Новые строки были добавлены для пояснения. Они НЕ появляются в коде.)
Заметки:
TI-BASIC - это токенизированный язык. Количество символов не равно количеству байтов.
e^(
это этот один байт маркера.^-1
используется для этого однобайтового токена. Вместо этогоя выбрал запись,
^-1
потому что токен выглядит какֿ¹
в блоке кода.√(
это этот один байт маркера.ΔList(
это это два байта маркера.источник
max(DeltaList(Ans
->variance(Ans
.Ява 10,
234229214211215206203196180177 байт-5 байт благодаря @PeterCordes .
-15 еще байт благодаря @PeterCordes , вдохновленных @RobinRyder R ответа «s .
+4 байта, потому что я предполагал, что входы предварительно упорядочены.
-27 байт благодаря @ OlivierGrégoire .
Попробуйте онлайн.
Объяснение:
источник
f+=Math.abs(d-D)<1e-9;
и получить неявное преобразование из логического результата сравнения в целое число 0/1, а затемdouble
. Есть ли в Java какой-нибудь компактный синтаксис для этого? Или можно сделатьf+=Math.abs(d-D)
и потом проверить, что сумма абсолютных разностей достаточно мала ?f>1e-8
работает как условие цикла: 229 байтов.a->{for(double f=1,D,A[],l;f>1e-8;a=A){D=a[0];A=new double[]{f=0,1,0,0};for(var d:a){f+=Math.abs(d-D);A[0]+=d;A[1]*=d;A[2]+=1/d;A[3]+=d*d;}A[0]/=l=a.length;A[1]=Math.pow(A[1],1/l);A[2]=l/A[2];A[3]=Math.sqrt(A[3]/l);}return a[0];}
, При этом1e-9
он работает медленнее (примерно вдвое больше процессорного времени), и ему приходится выполнять больше итераций, чтобы получить на 4 *d-D
меньше. С1e-7
, это примерно такая же скорость, как 1e-8. С1e-6
, некоторые из последних цифр отличаются для одного случая.f
полностью отказаться и только проверитьa[3]-a[2]<4e-9
.l==2||
вы имеете в виду (игра в гольфl<3|
). Но да, хорошая мысль; Я добавил это. :)Древесный уголь , 40 байт
Попробуйте онлайн! Ссылка на подробную версию кода. Принимает ввод как массив чисел. Объяснение:
Повторите, пока массив содержит разные значения ...
... заменить массив списком значений:
... Значение...
... среднее геометрическое ...
... среднее гармоническое ...
... и корень означает квадрат.
Приведите элемент массива к строке и неявно напечатайте его.
источник
Желе , 24 байта
Попробуйте онлайн!
источник
PowerShell ,
182180183 байтаПопробуйте онлайн!
источник
05AB1E ,
262423 байтаПопробуйте онлайн или посмотрите шаги всех тестовых случаев .
-1 байт благодаря @Grimy .
23-байтовая альтернатива для среднего геометрического:
Попробуйте онлайн или посмотрите шаги всех тестовых случаев .
Объяснение:
источник
Δ©P®gzm®ÅA®zÅAz®nÅAt)}н
Y
2/4. :)Δ©ÅA®.²ÅAo®zÅAz®nÅAt)}н
. К сожалению, не похоже, что мы можем реорганизовать все этиÅA
s.Желе ,
2524 байтаПопробуйте онлайн!
объяснение
источник
P*İL
работать на среднее геометрическое?P*Lİ$
чтобы не экономить байты. Это означало бы, что я мог быÆm
восстановить строку без затрат байтов, но мне очень нравится тот факт, что каждый из них в настоящее время имеет среднее арифметическое значение.Python 3 , 152 байта
Попробуйте онлайн!
Рекурсивная функция
f
, будет сходиться к точности с плавающей точкой. В принципе работает для всех списков положительных чисел любого размера, но ограниченрекурсивным пределом Pythonдля некоторых тестовых случаев ошибка округления.В качестве альтернативы можно рассчитать с точностью до 9 десятичных знаков:
Python 3 , 169 байт
Попробуйте онлайн!
источник
C # , 173 байта
Попробуйте онлайн!
источник
using System
иusing System.Linq
в свой счетчик байтов, поскольку они необходимы для запуска программы. Вы можете изменить свой компилятор на C # Visual Interactive Compiler, который не нуждается в импорте. Также,1.0
->1d
Чисто , 124 байта
Попробуйте онлайн!
Выполняет операцию, пока результат не перестанет меняться.
Ура для ограниченной точности с плавающей точкой!
источник
Pyth, 32 байта
Попробуйте это онлайн здесь , или проверьте все тесты (план два, см. Примечание ниже) сразу здесь . Принимает ввод в виде списка.
Кажется, есть некоторые проблемы с округлением, поскольку некоторые входные данные не сходятся правильно, когда они должны были бы. В частности, тестовый пример
0.01 100
застревает в значениях[6.748305820749738, 6.748305820749738, 6.748305820749739, 6.748305820749738]
, а тестовый пример1.61 2.41
застревает в[1.9896543776640825, 1.9896543776640825, 1.9896543776640827, 1.9896543776640825]
- обратите внимание, что в обоих случаях 3-е среднее (среднее гармоническое) отличается от других.Я не уверен, что эта проблема делает мою запись недействительной, но я все равно публикую ее, так как она должна работать. Если это неприемлемо, это можно исправить, введя
.RRT
перед, округляя[
каждое из средств до 10 десятичных знаков, как показано в этом наборе тестов .источник
.Wt{H
сu
на -4 байт (и изменениеZ
кG
)Japt v2.0a0
-g
,4238 байтДолжен быть более короткий путь ... Это чудовище! Сохранено 4 байта благодаря @Shaggy!
Попытайся
источник
C # (интерактивный компилятор Visual C #) , 177 байт
Спасибо @KevinCruijjsen за указание на то, что использование точности с плавающей точкой вызывает проблемы! Было бы 163 байта, если бы двойники были совершенно точными.
Попробуйте онлайн!
источник
StackOverflowException
точность с плавающей запятой. Вместоc==g[0]
тебя можно было сделать что-то подобноеMath.Abs(c-g[0])<1e-9
. Попробуйте онлайн.машинный код x86 (SIMD 4x float с использованием 128-битного SSE1 и AVX) 94 байта
машинный код x86 (SIMD 4x double с использованием 256-битного AVX) 123 байта
float
проходит тестовые случаи в вопросе, но с порогом выхода из цикла, достаточно маленьким, чтобы это произошло, легко застрять в бесконечном цикле со случайными входами.Инструкции SSE1 упакованной одинарной точности имеют длину 3 байта, а инструкции SSE2 и простые AVX имеют длину 4 байта. (Отдельные скалярные инструкции, такие как
sqrtss
, также имеют длину 4 байта, поэтому я использую их,sqrtps
хотя мне важен только низкий элемент. Он даже медленнее, чем sqrtss на современном оборудовании). Я использовал AVX для неразрушающего назначения, чтобы сохранить 2 байта против movaps + op.В двойной версии мы все еще можем сделать пару
movlhps
для копирования 64-битных кусков (потому что часто мы заботимся только о младшем элементе горизонтальной суммы). Горизонтальная сумма 256-битного вектора SIMD также требует дополнительного,vextractf128
чтобы получить верхнюю половину, по сравнению с медленной, но небольшой 2-кратнойhaddps
стратегией для float .double
Версия также нуждается в 2x 8-байтовых константах вместо 2x 4-байтовых. В целом он выходит примерно на 4/3 размераfloat
версии.mean(a,b) = mean(a,a,b,b)
для всех 4-х из этих средств , поэтому мы можем просто дублировать ввод до 4-х элементов и никогда не реализовывать length = 2. Таким образом, мы можем жестко закодировать геометрическое среднее как, например, 4-й корень = sqrt (sqrt). И нам нужна только одна константа FP4.0
.У нас есть один вектор SIMD из всех 4
[a_i, b_i, c_i, d_i]
. Исходя из этого, мы вычисляем 4 средних как скаляры в отдельных регистрах и перемешиваем их вместе для следующей итерации. (Горизонтальные операции над векторами SIMD неудобны, но мы должны сделать то же самое для всех 4 элементов в достаточном количестве случаев, чтобы он уравновешивался. Я начал на этой версии для x87, но она становилась очень длинной и не увлекательной.)Условие петлевой выход
}while(quadratic - harmonic > 4e-5)
(или меньше константа дляdouble
) основана на @ R ответа RobinRyder в и Java ответ Кевин Cruijssen в : среднее квадратичное всегда по величине величины и среднее гармоническое всегда наименьшее ( без учета ошибок округления). Таким образом, мы можем проверить дельту между этими двумя, чтобы обнаружить сходимость. Мы возвращаем среднее арифметическое как скалярный результат. Это обычно между этими двумя и, вероятно, наименее подвержены ошибкам округления.Версия с плавающей запятой: может вызываться как
float meanmean_float_avx(__m128);
с аргументом arg и возвращаемым значением в xmm0. (Таким образом, x86-64 System V, или Windows x64 vectorcall, но не x64 fastcall.) Или объявите тип возврата как__m128
таковой, чтобы вы могли получить квадратичное и гармоническое среднее для тестирования.Если для этого потребуются 2 отдельных
float
аргумента в xmm0 и xmm1, это будет стоить 1 дополнительный байт: нам понадобится ashufps
с imm8 (вместо простоunpcklps xmm0,xmm0
), чтобы перемешать и дублировать 2 входа.(Список NASM создан с помощью
nasm -felf64 mean-mean.asm -l/dev/stdout | cut -b -34,$((34+6))-
. Удалите часть списка и восстановите источник с помощьюcut -b 34- > mean-mean.asm
)SIMD горизонтальная сумма и деление на 4 (т.е. среднее арифметическое) реализована в отдельной функции, которую мы
call
(с указателем функции, чтобы амортизировать стоимость адреса). С4/x
до / после илиx^2
до и после, мы получаем среднее гармоническое и квадратичное среднее. (Было больно писать этиdiv
инструкции вместо умножения на точно представимое0.25
.)Среднее геометрическое реализовано отдельно с умноженным и цепным квадратами. Или с одним sqrt первым, чтобы уменьшить величину экспоненты и, возможно, помочь численной точности.
floor(log2(x))
Журнал недоступен, только через AVX512vgetexpps/pd
. Exp является своего рода доступным через AVX512ER (только Xeon Phi), но только с точностью 2 ^ -23.Смешивание 128-битных инструкций AVX и устаревших SSE не является проблемой производительности. Смешивание 256-битного AVX с устаревшим SSE может быть на Haswell, но на Skylake это просто потенциально создает потенциальную ложную зависимость для инструкций SSE. Я думаю, что моя
double
версия избегает любых ненужных переносимых по цепочке цепочек депов и узких мест в div / sqrt латентности / пропускной способности.Двойная версия:
Испытательный жгут
Сборка с:
Очевидно, вам нужен процессор с поддержкой AVX или эмулятор, такой как Intel SDE. Чтобы скомпилировать на хосте без встроенной поддержки AVX, используйте
-march=sandybridge
или-mavx
Выполнить: проходит жестко заданные тестовые примеры, но для плавающей версии случайные тестовые примеры часто не соответствуют
(b-a)/10000
пороговому значению, заданному в вопросе.Ошибки FP достаточны для того, чтобы квад-вред оказался меньше нуля для некоторых входных данных.
Или с
a += 1<<11; b += (1<<12)+1;
комментариямиНи одна из этих проблем не происходит с
double
. Закомментируйтеprintf
перед каждым тестом, чтобы увидеть, что вывод пуст (ничего изif(delta too high)
блока).TODO: используйте
double
версию как ссылку наfloat
версию, вместо того, чтобы просто посмотреть, как они сходятся с квад-вредом.источник
Javascript - 186 байт
Принимает ввод как массив чисел. Использует средние преобразования в ответе J42161217, чтобы сократить код.
Попробуйте онлайн
объяснение
источник
Perl 5 ,
9272 байтаПопробуйте онлайн!
... используя некоторые грязные трюки.
источник
SNOBOL4 (CSNOBOL4) , 296 байт
Попробуйте онлайн!
Простая реализация. Использую трюк из моего ответа на связанный вопрос, чтобы немного больше в гольфе.
источник