Codegolf — Сгладить Линейный График

  • Автор темы Skoloda
  • Обновлено
  • 20, Oct 2024
  • #1

Учитывая ввод целого числа н и список положительных целых чисел м1, м2, ..., выведите список целых чисел м1', м2', ... где мх' определяется как среднее значение мх-н через мх+n.

При расчете этих средних значений игнорируйте индексы, выходящие за пределы допустимых значений (и соответственно отрегулируйте то, на что вы делите сумму). н всегда будет ≥ 1 но никогда не на половину длины м (округлено в меньшую сторону) и более. Это означает, что минимальная длина м

равно 4. Элементы в м будут целыми положительными числами, но результат должен быть точным как минимум до 3 знаков после запятой.Элементы ввода/вывода, являющиеся списками, могут быть либо Строки или массивы/списки/т. д., разделенные пробелами/запятыми. Для ввода, если ваш

решение — это функция, вы можете дополнительно принять первый аргумент

 
 In                             Out
----------------------------------------------------------------------
n=1, m=12 6 3 9                9 7 6 6
n=1, m=1 4 5 7 10              2.5 3.333 5.333 7.333 8.5
n=1, m=1 3 3 7 4 2 4 2         2 2.333 4.333 4.666 4.333 3.333 2.666 3
n=2, m=1 3 5 9 10 14 15 16 23  3 4.5 5.6 8.2 10.6 12.8 15.6 17 18
n=3, m=1 1 1 1 1 1 1 1         1 1 1 1 1 1 1 1
n=3, m=1 2 3 4 5 6 7 8         2.5 3 3.5 4 5 5.5 6 6.5
 
:

1 4 5 7 10 __/ | | | L avg(1,4) = 2.5 | | | \___/ | | L avg(1,4,5) = 3.333 | | \___/ | L avg(4,5,7) = 5.333 | \___/ L avg(5,7,10) = 7.333 \___ L avg(7,10) = 8.5 Final output: 2.5 3.333 5.333 7.333 8.5

н

идополнительные аргументы как):

n=1

м

Skoloda


Рег
09 May, 2020

Тем
77

Постов
209

Баллов
664
  • 26, Oct 2024
  • #2

МАТЛ, 30 28 26 24 байта

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Mean/@N@Partition[#2,UpTo[2#+1],1,{-#-1,#+1}]&
 

Проверено на Matlab и Octave. Использование текущая версия (9.1.0) языка/компилятора.

Ввод: сначала число, управляющее длиной окна, затем массив с форматом. ćU˜©ε®NX@iX·>£ÅAV®¦©YëN>X+£ÅA} ć Head extract (get n) U Save in variable X ˜ Flat the list © Save the list in register c ε } Map ® Get the list from register c NX@ Is the iteration greater than or equal to n i if true ë if false X·> push (n*2)+1 £ extract (n*2)+1 elements from head ÅA Arithmetic mean V Save the result in variable Y ® Push the list from register c again ¦ remove head (first element) © save the new list in register c Y get variable Y (to apply on map returned value) N>X+ push i+1+n (i=iteration index, loop count) £ extract i+1+n elements from head ÅA Arithmetic mean .

РЕДАКТИРОВАТЬ (20 мая 2016 г.): Попробуйте онлайн! Код по ссылке имеет [n,[list_m]] replaced by ćU˜©ε®NX@iX·>£ÅAV®¦©YëN>X+£ÅA} чтобы соответствовать версии 18.0.0 языка.

Пример

F=(n,a)=>a.map((e,i)=>(s=a.slice(i<n?0:i-n,i+n+1))&&s.reduce((l,c)=>l+c)/s.length) document.write('<pre>' + [ [1, [12, 6, 3, 9], [9, 7, 6, 6] ], [1, [1, 4, 5, 7, 10], [2.5, 3.333, 5.333, 7.333, 8.5] ], [1, [1, 3, 3, 7, 4, 2, 4, 2], [2, 2.333, 4.333, 4.667, 4.333, 3.333, 2.667, 3] ], [2, [1, 3, 5, 9, 10, 14, 15, 16, 23], [3, 4.5, 5.6, 8.2, 10.6, 12.8, 15.6, 17, 18] ], [3, [1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1] ], [3, [1, 2, 3, 4, 5, 6, 7, 8], [2.5, 3, 3.5, 4, 5, 5.5, 6, 6.5] ] ].map(t => { var [n, m, e] = t; var r = F(n, m); // verify to precision of 3 decimals var test = r.every((v, i) => v.toPrecision(3) === e[i].toPrecision(3)); return 'F(' + n + ', [' + m + '])\t' + (test ? 'Pass' : 'Fail') + '\n\t{' + r + '} ' + (test ? '=' : '≠') + ' {' + e + '}'; }).join('\n\n') + '</pre>');

Объяснение

Эквивалентный код Matlab будет

F=(n,a)=>a.map((e,i)=>(s=a.slice(i<n?0:i-n,i+n+1))&&s.reduce((l,c)=>l+c)/s.length)

Код MATL использует недавно добавленные функции неявного ввода и автоматического буфера обмена для ввода функций:

<pre id=O></pre> ||answer||

APL (Диалог Юникод), 18 16 байты

f=(n,l,p=0)=>l.map((v,i)=>(p+=~l[i-n-1]-~l[i+n])/(n+1+Math.min(n,l.length-1-i,i)),l.map((v,i)=>p+=i<n&&v)) console.log=x=>O.textContent+=x+'\n'; ;[ [1,[12,6,3,9],[9,7,6,6]] , [1,[1,4,5,7,10],[2.5,3.333,5.333,7.333,8.5]] , [1,[1,3,3,7,4,2,4,2],[2,2.333,4.333,4.667,4.333,3.333,2.667,3]] , [2,[1,3,5,9,10,14,15,16,23],[3,4.5,5.6,8.2,10.6,12.8,15.6,17,18]] , [3,[1,1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1]] , [3,[1,2,3,4,5,6,7,8],[2.5,3,3.5,4,5,5.5,6,6.5]] ].forEach(t=>{ var n=t[0],l=t[1],x=t[2],r=f(n,l) // verify (limited to 3 decimals) var ok = r.every((v,i)=>v.toFixed(3)==x[i].toFixed(3)) console.log((ok?'OK ':'Fail ')+n+' '+l+' -> '+r+' ('+x+')') })

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

@ngn предложил средний трюк, используя (l, n) => { p = 0; for (i = 0; i < n; i++) p += v; r = []; for (i = 0; i < l.length; i++) { p += (l[i + n] || 0) - (i > n ? l[i - n - 1] : 0); r.push(p / Math.min(n, l.length - i - 1, i); } return r; } , и я пошел еще дальше, сократив его на два байта, устранив необходимость (l,n,p=0)=>l.map((v,i)=>(p+=~l[i-n-1]-~l[i+n])/(n+1+Math.min(n,l.length-1-i,i)),l.map((v,i)=>p+=i<n&&v)) .

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

Трюк по умолчанию для среднего использования .OM sM .: + Means of flattens of sublists of length 2K+1 of + J * ] Y J is E copies of []. K E Save E to a variable to use it later. ]MQ the input J Put J on both sides of ]MQ. h y K 2K+1 (matrix divide/solve linear equation/least squares fit) is "divide a vector by its all ones version", which solves the least squares of something like this:

.OMsM.:++J*]YKE]MQJhyK

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

t<-2*n+1 -- assign t to the maximum number of elements of a -- of sublist take t(inits x) -- build the sublists from t elements of the inits ++tails x -- of the input and the tails of the input, -- e.g. x=[1,2,3,4], t=3: -- [[],[1],[1,2]] ++ [[1,2,3,4],[2,3,4],[3,4],[4],[]] a<-take t<$> -- take at most t elements from every sublist ,length a>n -- keep those with a minimum length of n+1 sum a/sum(1<$a) -- calculate average, "sum(1<$a)" is the length of a

Альтернативно, Extended может сделать то же самое в 15 байтах, используя тот факт, что левый аргумент всегда равен нулю (в отличие от «размера заполнения» в обычной версии Dyalog):

APL (расширенный диалог), 15 байт

[3.0,4.5,5.6,8.2,10.6,12.8,15.6,17.0,18.0]

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


APL (Диалог Юникод) 18.0, 18 байты

2 # [1,3,5,9,10,14,15,16,23]

Попробуйте эквивалентную программу 17.x онлайн!

Какой достойный вызов для трафарета Dyalog APL import Data.List n#x|t<-2*n+1=[sum a/sum(1<$a)|a<-take t<$>take t(inits x)++tails x,length a>n] .

Оператор Stencil извлекает движущееся окно из массива точно так, как описано в задаче. В частности, для нечетного размера окна окно центрируется над каждым элементом, при необходимости дополняется нулями вне массива, а затем величина заполнения задается в качестве дополнительной информации, так что один Drop f(n,m)=[mean(m[max(1,i-n):min(end,i+1)])for i=1:endof(m)] will remove such padding. The rest is just specifying the right window size and taking average m.O:vzeS,0-dQh+dQUvz по каждому подмассиву.

Иллюстрация

2n+1

Также возможен подход умножения матриц, но он недостаточно короткий:

APL (Диалог Юникод), 21 байты

n

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

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

n [m1 m2 ... mx] ||answer||

CJam, 31 30 байт

ri_S*l~1$++\2*)ew{S-_:+\,d/}%`

Формат ввода: {÷/⍵1+.ר⊂⍺≥|∘.-⍨⍳≢⍵} ⍝ Left:n, Right:m ⍳≢⍵ ⍝ 1..length of m ∘.-⍨ ⍝ Self outer product by difference ⍺≥| ⍝ 1 if abs diff is at most n, 0 otherwise ⍝ which gives the band matrix ⍵1+.ר⊂ ⍝ Inner product with m and all-one vector ÷/ ⍝ Divide left by right .

Запустите все тестовые случаи. (Автоматически преобразует набор тестов в необходимый входной формат.)

Это работает путем предварительного и добавления {÷/⍵1+.ר⊂⍺≥|∘.-⍨⍳≢⍵} spaces, then taking all substrings of length Input array: 12 6 3 9 Input n: 1 Window size: 3 (1+2×n) Arguments to left operand of Stencil: Left Right 1 0 12 6 ⍝ Zero padding 1 unit to the left; 1↓ drops 0 from the front 0 12 6 3 0 6 3 9 ¯1 3 9 0 ⍝ Zero padding 1 unit to the right ¯1↓ drops 0 from the back и снова удаляя пробелы перед вычислением их средних значений.

 

Сан Саныч


Рег
27 Jul, 2004

Тем
83

Постов
180

Баллов
615
  • 26, Oct 2024
  • #3

Пиф, 20 байт

(+/÷≢)

Набор тестов

Довольно просто: просто вырежьте соответствующий раздел из списка, а затем усредните его.

 

Alexnets


Рег
06 Jun, 2006

Тем
73

Постов
203

Баллов
618
  • 26, Oct 2024
  • #4

Юлия, 57 байт

Это функция, которая принимает два целых числа и возвращает массив чисел с плавающей запятой.

Подход здесь очень простой. Мы создаем новый массив, взяв среднее значение секций входного массива, усекая спереди и сзади.

 

Langtu


Рег
23 Jan, 2005

Тем
78

Постов
218

Баллов
618
  • 26, Oct 2024
  • #5

Хаскелл, 97 95 байт

Пример использования: (+/÷≢)⍤↓⌺(1+2×⎕)⊢⎕ -> (⊢⌹<)⌺(1+2×⎕)⊢⎕ .

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

{⍵⌹×⍵} Input: a vector of positive integers, possibly with zeros to ignore ×⍵ Signum of each number, which gives 1 for positives and 0 for zeros ⍵⌹ Matrix-divide the original vector by the above, which gives the system of equations, e.g. for 0 0 1 3 5: 0x = 0 0x = 0 1x = 1 1x = 3 1x = 5 Then the zero-coefficient equations are ignored in the least squares, which leads to the average of only positive entries. ||answer||

Пиф, 22 байта

1x = 1 1x = 3 1x = 5

Объяснение:

Попробуйте это здесь.

 

Boqiyev88


Рег
14 Jul, 2016

Тем
87

Постов
218

Баллов
653
  • 26, Oct 2024
  • #6

JavaScript (ES6), 104

Текущий общий объем/текущий размер выборки. В Javascript чтение значения за пределами массива дает неопределенное значение, которое можно преобразовать в 0 с помощью ~~

Негольфед

Тест

{⍵⌹×⍵}⌺(1+2×⎕)⊢⎕ 2*1+ % get implicit input "n". Multipliy by 2 and add 1 :g % create a vector of 2*n+1 "true" values (will act as "one" values) 2X5 % 'same' string literal 3$X+ % get implicit input "x" (array). Convolution using three inputs 1M % push all three inputs from last function bgbb % convert first input to "true" values. Will act as "one" values 3$X+ % convolution using three inputs / % divide element-wise. Implicitly print
 

AkaN


Рег
15 Sep, 2011

Тем
79

Постов
210

Баллов
615
  • 26, Oct 2024
  • #7

JavaScript (ES6), 82 байта

код:

n = 1; %// first input: number controlling window length x = [1 4 5 7 10]; %// second input: array result = conv(x,ones(1,2*n+1),'same')./conv(ones(size(x)),ones(1,2*n+1),'same');

тест:

>> matl > 2*1+:g2X53$X+1Mbgbb3$X+/ > > 1 > [1 4 5 7 10] 2.5 3.333333333333333 5.333333333333333 7.333333333333333 8.5 >> matl > 2*1+:g2X53$X+1Mbgbb3$X+/ > > 2 > [1 3 5 9 10 14 15 16 23] 3 4.5 5.6 8.199999999999999 10.6 2.8 15.6 17 18 ||answer||

05AB1E, 30 байт

Y+

Ввод: X+ Output is: `[list_of_avgs]

Объяснение

[1 4 5 7 10]

Попробуйте здесь :)

 

Polli1


Рег
05 Jan, 2012

Тем
76

Постов
215

Баллов
615
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно