2018-10-10 18:03:03 -04:00
|
|
|
|
---
|
2019-08-28 16:26:13 +03:00
|
|
|
|
title: Averages/Pythagorean means
|
2018-10-10 18:03:03 -04:00
|
|
|
|
id: 594d966a1467eb84194f0086
|
|
|
|
|
|
challengeType: 5
|
2019-08-28 16:26:13 +03:00
|
|
|
|
forumTopicId: 302227
|
2018-10-10 18:03:03 -04:00
|
|
|
|
localeTitle: Средние значения - пифагорейские средства
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## Description
|
2019-08-28 16:26:13 +03:00
|
|
|
|
<section id='description'>
|
|
|
|
|
|
<p class="rosetta__paragraph"> Вычислите все три <a class="rosetta__link--wiki" href="https://en.wikipedia.org/wiki/Pythagorean means" title="wp: Пифагорейский означает">пифагорейских средства</a> набора целых чисел от <big>1</big> до <big>10</big> (включительно). </p><p class="rosetta__paragraph"> Покажите, что для этого набора натуральных чисел <big>$ A (x_1, \ ldots, x_n) \ geq G (x_1, \ ldots, x_n) \ geq H (x_1, \ ldots, x_n) $</big> . </p> Наиболее распространенным из трех означает <a class="rosetta__link--rosetta" href="http://rosettacode.org/wiki/Averages/Arithmetic mean" title="Средние / Средние арифметические">среднее арифметическое</a> - это сумма списка, деленная на его длину: <big>$ A (x_1, \ ldots, x_n) = \ frac {x_1 + \ cdots + x_n} {n} $</big> <a class="rosetta__link--wiki" href="https://en.wikipedia.org/wiki/Geometric mean" title="wp: среднее геометрическое">Геометрическая Среднее означает</a> $ n $ -ый корень из произведения списка: <big>$ G (x_1, \ ldots, x_n) = \ sqrt [n] {x_1 \ cdots x_n} $</big> <a class="rosetta__link--wiki" href="https://en.wikipedia.org/wiki/Harmonic mean" title="wp: Гармоническое среднее">Гармоническое среднее</a> $ n $, деленное на сумму обратный каждому элементу в списке: <big>$ H (x_1, \ ldots, x_n) = \ frac {n} {\ frac {1} {x_1} + \ cdots + \ frac {1} {x_n}} $</big> <p class="rosetta__paragraph"> Предположим, что вход представляет собой упорядоченный массив всех включенных чисел. </p><p class="rosetta__paragraph"> Для ответа, пожалуйста, выведите объект в следующем формате: </p><pre class="rosetta__pre"> {
|
2018-10-10 18:03:03 -04:00
|
|
|
|
значения: {
|
|
|
|
|
|
Арифметика: 5.5,
|
|
|
|
|
|
Геометрический: 4.528728688116765,
|
|
|
|
|
|
Гармонический: 3.414171521474055
|
|
|
|
|
|
},
|
|
|
|
|
|
test: 'является A> = G> = H? да'
|
|
|
|
|
|
}
|
2019-08-28 16:26:13 +03:00
|
|
|
|
</pre>
|
|
|
|
|
|
</section>
|
2018-10-10 18:03:03 -04:00
|
|
|
|
|
|
|
|
|
|
## Instructions
|
2019-08-28 16:26:13 +03:00
|
|
|
|
<section id='instructions'>
|
|
|
|
|
|
When writing your function, assume the input is an ordered array of all inclusive numbers.
|
|
|
|
|
|
For the answer, please output an object in the following format:
|
|
|
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
|
{
|
|
|
|
|
|
values: {
|
|
|
|
|
|
Arithmetic: 5.5,
|
|
|
|
|
|
Geometric: 4.528728688116765,
|
|
|
|
|
|
Harmonic: 3.414171521474055
|
|
|
|
|
|
},
|
|
|
|
|
|
test: 'is A >= G >= H ? yes'
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2018-10-10 18:03:03 -04:00
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
## Tests
|
|
|
|
|
|
<section id='tests'>
|
|
|
|
|
|
|
|
|
|
|
|
```yml
|
|
|
|
|
|
tests:
|
2019-08-28 16:26:13 +03:00
|
|
|
|
- text: <code>pythagoreanMeans</code> is a function.
|
|
|
|
|
|
testString: assert(typeof pythagoreanMeans === 'function');
|
|
|
|
|
|
- text: <code>pythagoreanMeans([1, 2, ..., 10])</code> should equal the same output above.
|
|
|
|
|
|
testString: assert.deepEqual(pythagoreanMeans(range1), answer1);
|
2018-10-10 18:03:03 -04:00
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
## Challenge Seed
|
|
|
|
|
|
<section id='challengeSeed'>
|
|
|
|
|
|
|
|
|
|
|
|
<div id='js-seed'>
|
|
|
|
|
|
|
|
|
|
|
|
```js
|
2019-08-28 16:26:13 +03:00
|
|
|
|
function pythagoreanMeans(rangeArr) {
|
2018-10-10 18:03:03 -04:00
|
|
|
|
// Good luck!
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2019-08-28 16:26:13 +03:00
|
|
|
|
### After Tests
|
2018-10-10 18:03:03 -04:00
|
|
|
|
<div id='js-teardown'>
|
|
|
|
|
|
|
|
|
|
|
|
```js
|
2019-08-28 16:26:13 +03:00
|
|
|
|
const range1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
|
|
|
|
const answer1 = {
|
|
|
|
|
|
values: {
|
|
|
|
|
|
Arithmetic: 5.5,
|
|
|
|
|
|
Geometric: 4.528728688116765,
|
|
|
|
|
|
Harmonic: 3.414171521474055
|
|
|
|
|
|
},
|
|
|
|
|
|
test: 'is A >= G >= H ? yes'
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2018-10-10 18:03:03 -04:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
## Solution
|
|
|
|
|
|
<section id='solution'>
|
|
|
|
|
|
|
|
|
|
|
|
```js
|
2019-08-28 16:26:13 +03:00
|
|
|
|
function pythagoreanMeans(rangeArr) {
|
|
|
|
|
|
// arithmeticMean :: [Number] -> Number
|
|
|
|
|
|
const arithmeticMean = xs =>
|
|
|
|
|
|
foldl((sum, n) => sum + n, 0, xs) / length(xs);
|
|
|
|
|
|
|
|
|
|
|
|
// geometricMean :: [Number] -> Number
|
|
|
|
|
|
const geometricMean = xs =>
|
|
|
|
|
|
raise(foldl((product, x) => product * x, 1, xs), 1 / length(xs));
|
|
|
|
|
|
|
|
|
|
|
|
// harmonicMean :: [Number] -> Number
|
|
|
|
|
|
const harmonicMean = xs =>
|
|
|
|
|
|
length(xs) / foldl((invSum, n) => invSum + (1 / n), 0, xs);
|
|
|
|
|
|
|
|
|
|
|
|
// GENERIC FUNCTIONS ------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
// A list of functions applied to a list of arguments
|
|
|
|
|
|
// <*> :: [(a -> b)] -> [a] -> [b]
|
|
|
|
|
|
const ap = (fs, xs) => //
|
|
|
|
|
|
Array.prototype.concat(...fs.map(f => //
|
|
|
|
|
|
Array.prototype.concat(...xs.map(x => [f(x)]))));
|
|
|
|
|
|
|
|
|
|
|
|
// foldl :: (b -> a -> b) -> b -> [a] -> b
|
|
|
|
|
|
const foldl = (f, a, xs) => xs.reduce(f, a);
|
|
|
|
|
|
|
|
|
|
|
|
// length :: [a] -> Int
|
|
|
|
|
|
const length = xs => xs.length;
|
|
|
|
|
|
|
|
|
|
|
|
// mapFromList :: [(k, v)] -> Dictionary
|
|
|
|
|
|
const mapFromList = kvs =>
|
|
|
|
|
|
foldl((a, [k, v]) =>
|
|
|
|
|
|
(a[(typeof k === 'string' && k)] = v, a), {}, kvs);
|
|
|
|
|
|
|
|
|
|
|
|
// raise :: Num -> Int -> Num
|
|
|
|
|
|
const raise = (n, e) => Math.pow(n, e);
|
|
|
|
|
|
/*
|
|
|
|
|
|
// show :: a -> String
|
|
|
|
|
|
// show :: a -> Int -> String
|
|
|
|
|
|
const show = (...x) =>
|
|
|
|
|
|
JSON.stringify.apply(
|
|
|
|
|
|
null, x.length > 1 ? [x[0], null, x[1]] : x
|
|
|
|
|
|
);
|
|
|
|
|
|
*/
|
|
|
|
|
|
// zip :: [a] -> [b] -> [(a,b)]
|
|
|
|
|
|
const zip = (xs, ys) =>
|
|
|
|
|
|
xs.slice(0, Math.min(xs.length, ys.length))
|
|
|
|
|
|
.map((x, i) => [x, ys[i]]);
|
|
|
|
|
|
|
|
|
|
|
|
// TEST -------------------------------------------------------------------
|
|
|
|
|
|
// mean :: Dictionary
|
|
|
|
|
|
const mean = mapFromList(zip(
|
|
|
|
|
|
['Arithmetic', 'Geometric', 'Harmonic'],
|
|
|
|
|
|
ap([arithmeticMean, geometricMean, harmonicMean], [
|
|
|
|
|
|
rangeArr
|
|
|
|
|
|
])
|
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
values: mean,
|
|
|
|
|
|
test: `is A >= G >= H ? ${mean.Arithmetic >= mean.Geometric &&
|
|
|
|
|
|
mean.Geometric >= mean.Harmonic ? 'yes' : 'no'}`
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
2018-10-10 18:03:03 -04:00
|
|
|
|
```
|
2019-08-28 16:26:13 +03:00
|
|
|
|
|
2018-10-10 18:03:03 -04:00
|
|
|
|
</section>
|