Средневзвешенное значение - проблема тренда отжимания

10

Скажем, этот массив - это количество отжиманий, которые я получал каждый день за последние 28 дней:

[
  20,20,20,30,30,30,30,
  35,35,40,40,40,45,45,
  50,50,50,50,50,50,50,
  60,70,80,90,100,110,120
]

Как вы можете видеть, на прошлой неделе произошел крутой восходящий тренд, и это часть данных, которые меня больше всего интересуют. Чем дальше, тем меньше я хочу, чтобы эти данные отображались в моем «среднем» Количество отжиманий.

Для этого я хочу выработать «среднее», где каждая неделя стоит больше, чем предыдущая.


Справочная информация, не является частью этой проблемы.

Нормальное среднее:

Сумма всех значений / количество значений

Для выше:

1440/28 = 51,42857142857143


Средневзвешенное:

Разделите массив на 4 группы по 7 и запустите новый массив.

  • Добавьте первую группу в массив.
  • Добавьте вторую группу в массив дважды.
  • Добавьте третью группу в массив трижды.
  • Добавьте четвертую группу в массив четыре раза.

Суммируйте весь новый массив и разделите на длину нового массива.

Для выше:

Преобразовать массив в это:

[
  20,20,20,30,30,30,30, # first week once
  35,35,40,40,40,45,45, 
  35,35,40,40,40,45,45, # second week twice
  50,50,50,50,50,50,50,
  50,50,50,50,50,50,50,
  50,50,50,50,50,50,50, # third week thrice
  60,70,80,90,100,110,120,
  60,70,80,90,100,110,120,
  60,70,80,90,100,110,120,
  60,70,80,90,100,110,120 # Fourth week four times
]

Затем запустите нормальное среднее значение для этого массива.

4310/70 = 61,57142857142857

Обратите внимание, что это выше, чем нормальное среднее значение из-за восходящего тренда на прошлой неделе.


Правила:

  • Входные данные представляют собой плоский массив из 28 неотрицательных целых чисел.
  • Любой язык, на котором вы хотели бы писать.
  • Выведите число.
  • Мне всегда нравится видеть ссылки TIO .
  • Попробуйте решить проблему с наименьшим количеством байтов.
  • Результат должен быть десятичным, с точностью не менее 4 десятичных разрядов (либо усеченным, либо округленным по сравнению со значениями контрольного примера - в порядке) или точной дробью

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

Случай 1: тенденция к росту

[
  20,20,20,30,30,30,30,
  35,35,40,40,40,45,45,
  50,50,50,50,50,50,50,
  60,70,80,90,100,110,120
]

Нормальное среднее: 51,42857142857143 Средневзвешенное: 61,57142857142857

Случай 2: Оставить затишье позади

(У меня была плохая неделя, но это было некоторое время назад)

[
  50,50,50,50,50,50,50,
  10,10,10,10,10,10,10,
  50,50,50,50,50,50,50,
  50,50,50,50,50,50,50
]

Нормальное среднее: 40 Средневзвешенное: 42

Случай 3: сдача

У меня была плохая неделя, она быстро снижала мой средний уровень.

[
  50,50,50,50,50,50,50,
  50,50,50,50,50,50,50,
  50,50,50,50,50,50,50,
  10,10,10,10,10,10,10
]

Нормальное среднее: 40 Средневзвешенное: 34

Случай 4: усреднение

Итак, я просто играю здесь, я подумал, что это может быть одинаковое значение для нормальных и взвешенных средних, но, конечно, это не так.

[
  60,60,60,60,60,60,60,
  30,30,30,30,30,30,30,
  20,20,20,20,20,20,20,
  15,15,15,15,15,15,15
]

Нормальное среднее: 31,25 Средневзвешенное: 24,0


Бонусная проблема:

Какая комбинация из 28 значений будет иметь одинаковое нормальное среднее и средневзвешенное значение?


Удачного игры в гольф!

AJFaraday
источник
1
Возможно, вы захотите попробовать экспоненциальное сглаживание тоже - new_avg = α*weekly_sum + (1-α)*old_avgдля некоторыхα∈(0,1)
Angs
2
Я делаю 0отжимания каждый день, поэтому мое средневзвешенное значение совпадает с моим обычным средним.
Нейл,
@Neil, вы не выиграете от средневзвешенной системы;)
AJFaraday
1
будьте осторожны, чтобы не перетренироваться: р
Брайан Х.

Ответы:

3

Шелуха , 6 байт

AΣΣṫC7

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

Использует трюк, который Деннис использовал, чтобы превзойти мою подачу желе. Вместо того, чтобы повторять каждый фрагмент N раз, он извлекает суффиксы из списка фрагментов, которые после выравнивания будут давать тот же результат, за исключением порядка.

Мистер Xcoder
источник
5

05AB1E , 8 7 байт

Сохранено 1 байт благодаря Mr. Xcoder

7ô.s˜ÅA

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

объяснение

7ô         # split list into groups of 7
  .s       # push suffixes
    ˜      # flatten
     ÅA    # arithmetic mean
Emigna
источник
@ Mr.Xcoder: О да, я знал, что видел злую функцию, но не смог ее найти: P
Emigna
4

Желе , 7 байт

s7ṫJFÆm

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

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

s7ṫJFÆm  Main link. Argument: A (array of length 28)

s7       Split the array into chunks of length 7.
   J     Indices; yield [1, ..., 28].
  ṫ      Tail; yield the 1st, ..., 28th suffix of the result to the left.
         Starting with the 5th, the suffixes are empty arrays.
    F    Flatten the resulting 2D array.
     Æm  Take the arithmetic mean.
Деннис
источник
Да, это x"J$эквивалентно ṫJв этом контексте. Интересно!
г-н Xcoder
Вроде. Вместо того, чтобы повторять элементы n-го массива n раз, здесь используются все суффиксы. После выравнивания он генерирует те же элементы, но в другом порядке.
Деннис
4

R + pryr, 32 28 байт

и тот же средний балл неделя за неделей приведет к равенству средств.

pryr::f(s%*%rep(1:4,e=7)/70)

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

Благодаря Giuseppe удалось сэкономить 4 байта с помощью точечного произведения .

Pure R будет использовать еще два байта function

Jayce
источник
Конечно, это было бы так очевидно, теперь я думаю об этом.
AJFaraday
1
28 байтов, использующих скалярное произведение вместоsum
Джузеппе
У меня было 40 байт сfunction(s)weighted.mean(s,rep(1:4,e=7))
Джузеппе
1
@ Джузеппе К счастью, я не помню weighted.mean. Люблю, когда Rобгоняет Python.
JayCe
4

MATL , 10 байт

7es4:*s70/

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

Я не отправлял ответ MATL в возрасте! Я подумал, что могу участвовать в LOTM в мае 2018 года !

Объяснение:

7e          % Reshape the array into 7 rows (each week is one column)
  s         % Sum each column
   4:       % Push [1 2 3 4]
     *      % Multiply each columnar sum by the corresponding element in [1 2 3 4]
      s     % Sum this array
       70/  % Divide by 70
Джеймс
источник
У меня также было K:7Y"*s70/10 байтов.
Джузеппе
3

Желе , 9 байт

s7x"J$FÆm

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

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

s7x "J $ FÆm - принимает входные данные из первого аргумента командной строки и выводит их в STDOUT.
s7 - разбить на группы по 7 человек.
   "- Применить векторизация (zipwith):
  x J $ - Повторите элементы каждого списка количество раз, равное индексу списка.
      F - Свести.
       Æm - среднее арифметическое.
Мистер Xcoder
источник
2

Haskell , 35 байт

(/70).sum.zipWith(*)([1..]<*[1..7])

Бонус: если a,b,c,d еженедельные суммы, нормальное среднее равно средневзвешенному, если:

(a + b + c + d)/4 = (a + 2b + 3c + 4d)/10  <=>
10(a + b + c + d) = 4(a + 2b + 3c + 4d)    <=>
5(a + b + c + d)  = 2(a + 2b + 3c + 4d)    <=>
5a + 5b + 5c + 5d = 2a + 4b + 6c + 8d      <=>
3a + b - c - 3d   = 0

Одно из решений состоит в том, когда первая и последняя недели имеют одинаковые суммы, а также вторая и третья недели имеют одинаковую сумму, но существует бесконечно много решений, если ваш бицепс до этого. Пример: [15,10,10,10,10,10,5,20,20,20,25,25,20,20,30,20,20,20,20,20,20,10,10,20 , 0,10,10,10]

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

Angs
источник
2

JavaScript (Node.js) , 49 байт

a=>a.map((x,i)=>(I+=d=-~(i/7),s+=x*d),s=I=0)&&s/I

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


Не универсальное решение

JavaScript (Node.js) , 39 36 байт

a=>a.reduce((s,x,i)=>s+x*-~(i/7))/70

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

DanielIndie
источник
1
-1 байт при первом использовании решения a=>a.reduce((s,x,i)=>(I+=d=-~(i/7),s+x*d),I=0)/I. И быстрый совет: используйте, <hr>чтобы создать горизонтальную линию в уценке
Herman L
@HermanL Что не так с использованием ---(нужен собственный абзац)?
Нейл
2

Stax , 10 8 байт

äΔ6◙█µøΓ

Запустите и отладьте его

Пояснение (без упаковки):

7/4R:B$:V Full program, implicit input
7/        Split into parts of length 7
  4R      Push [1, 2, 3, 4]
    :B    Repeat each element the corresponding number of times
      $   Flatten
       :V Average
Wastl
источник
1
Еще один, использующий Stax! Да! Вы можете использовать $для выравнивания, если все элементы являются целыми числами - теперь проверяем с помощью OP.
Хулдрасет на'Барья
2

Древесный уголь , 14 байтов

I∕ΣE⪪A⁷×Σι⊕κ⁷⁰

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

     A          Input array
    ⪪ ⁷         Split into subarrays of length 7
   E            Loop over each subarray
         ι      Subarray
        Σ       Sum
           κ    Loop index
          ⊕     Incremented
       ×        Product
  Σ             Sum results
            ⁷⁰  Literal 70
 ∕              Divide
I               Cast to string
                Implicitly print
Нил
источник
2

К4 / К (ОК) , 19 16 14 байтов

Решение:

+/(1+&4#7)%70%

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

Пример:

+/(1+&4#7)%70%50 50 50 50 50 50 50 10 10 10 10 10 10 10 50 50 50 50 50 50 50 50 50 50 50 50 50 50
42

Объяснение:

Оценка выполняется справа налево. Разделите 7 1s, 7 2s, 7 3s и 7 4s на 70, разделенные на входные данные; затем подведите итог.

+/(1+&4#7)%70% / the solution               
           70% / 70 divided by the input
  (      )%    / the stuff in brackets divided by this...
      4#7      / draw from 7, 4 times => 7 7 7 7
     &         / 'where' builds 7 0s, 7 1s, 7 2s, 7 3s
   1+          / add one
+/             / sum (+) over (/) to get the total
streetster
источник
2

Excel: 33 байта

(3 байта сохранены из ответа @ wernisch, запустив данные в 2 строки из A1: N1 и A2: N2)

=AVERAGE(A1:N2,H1:N2,A2:N2,H2:N2)

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

dissemin8or
источник
2

Japt , 11 10 байт

xÈ/#F*ÒYz7

Попробуй это


объяснение

 È             :Pass each element at index Y through a function
  /#F          :  Divide by 70
       Yz7     :  Floor divide Y by 7
      Ò        :  Negate the bitwise NOT of that to add 1
     *         :  Multiply both results
x               :Reduce by addition
мохнатый
источник
1

Треугольность , 49 байтов

....)....
...D7)...
..14)21..
.WM)IEtu.
}u)70s/..

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

объяснение

)D7)14)21WM)IEtu}u)70s/ – Full program.
)D7)14)21               – Push the literals 0, 7, 14, 21 onto the stack.
         WM     }       – Wrap the stack to a list and run each element on a separate
                          stack, collecting the results in a list.
           )IEt         – Crop the elements of the input before those indices.
               u        – Sum that list.
                 u      – Then sum the list of sums.
                  )70   – Push the literal 70 onto the stack.
                     s/ – Swap and divide.
Мистер Xcoder
источник
1

Perl 5 -pa , 28 байт

$\+=$_/70*int$i++/7+1for@F}{

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

Ввод разделен пробелом, а не запятыми.

Xcali
источник
У вас есть в $.наличии идеальный множитель. Нет необходимости$i
Тон Хоспел
1

APL + WIN, 13 байт

Запрашивает массив как вектор целых чисел:

(+/⎕×7/⍳4)÷70

Объяснение:

7/⍳4) create a vector comprising 7 1s, 7 2s, 7 3s and 7 4s

+/⎕× prompt for input, multiply by the vector above and sum result

(....)÷70 divide the above sum by 70
Грэхем
источник
1

Java 8, 57 байт

a->{int r=0,i=35;for(;i-->7;)r+=i/7*a[i-7];return r/70d;}

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

Объяснение:

a->{              // Method with integer-array parameter and double return-type
  int r=0,        //  Result-sum, starting at 0
      i=35;       //  Index-integer, starting at 35
  for(;i-->7;)    //  Loop `i` downwards in the range (35,7]
    r+=           //   Add the following to the result-sum:
       i/7        //    `i` integer-divided by 7,
       *a[i-7];   //    multiplied by the item at index `i-7`
  return r/70d;}  //  Return the result-sum, divided by 70.0
Кевин Круйссен
источник
1

J , 16 байт

70%~1#.]*7#4{.#\

Объяснение:

              #\           finds the lengths of all successive prefixes (1 2 3 4 ... 28)
           4{.             takes the first 4 items (1 2 3 4)
         7#                creates 7 copies of each element of the above list
       ]*                  multiplies the input by the above 
    1#.                    sum
70%~                       divide by 70

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

Гален Иванов
источник
1

Clojure, 48 46 байтов

#(/(apply +(for[i[0 7 14 21]v(drop i %)]v))70)

Это оказалось короче, чем комбинация mapcat + subvec.

NikoNyrh
источник
1

TI-Basic, 25 байтов

mean(Ansseq(sum(I>{0,7,21,42}),I,1,70

Альтернативный раствор, 39 байт

Input L1
For(I,1,70
Ans+L1(I)sum(I>{0,7,21,42
End
Ans/70
Timtech
источник
1

Рубин , 65 байт

->r{(b=(0..r.size/7).map{|a|r[a*7..-1]}.flatten).sum/b.size.to_f}

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

lfvt
источник
Размер ввода указан здесь равным 28, так что вы можете сохранить несколько байтов путем жесткого кодирования значений вместо использования sizeсвойства. Попробуйте онлайн!
sundar - Восстановить Монику
1

Excel, 36 33 байта

-3 байта благодаря @tsh.

=SUM(1:1,H1:AB1,O1:AB1,V1:AB1)/70

Ввод в первом ряду ( A1до AB1).

Wernisch
источник
Может быть A1:AB1-> 1:1?
февраля
1

Юлия 0,6 , 27 байт

p->repeat(1:4,inner=7)'p/70

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

repeatВызов образует матрицу - столбец 28 значений, содержащий семь 1, а затем семь 2 - х и т.д. Затем мы транспонировать ее ', а затем сделать матричное умножение с входом (mutiplication подразумевается здесь). Так как это матричное умножение матрицы 1x28 с матрицей 28x1, мы получаем одно значение, которое является необходимой нам взвешенной суммой. Разделите это, 70чтобы получить наше взвешенное среднее.

sundar - Восстановить Монику
источник