Найти максимальное отклонение


20

Эта проблема "вдохновлена" вопросом, который изначально задавался на Quora (не для игры в гольф). Я просто хочу сделать это вызов для вас, ребята (и моя первая проблема здесь).

Учитывая массив целочисленных элементов vи целое число d(мы предполагаем, что d меньше или равен длине массива), рассмотрим все последовательности dпоследовательных элементов в массиве. Для каждой последовательности вычислите разницу между максимальным и минимальным значением элементов в этой последовательности и назовите ее отклонением.

Ваша задача - написать программу или функцию, которая вычисляет максимальное значение среди всех отклонений всех последовательностей, рассмотренных выше, и возвращает или выводит это значение.

Проработанный пример:

v: (6,9,4,7,4,1)
d: 3

The sequences of length 3 are:
6,9,4 with deviation 5
9,4,7 with deviation 5
4,7,4 with deviation 3
7,4,1 with deviation 6

Thus the maximal deviation is 6, so the output is 6.

Это код гольф, поэтому выигрывает самый короткий ответ в байтах.

Ответы:


14

Dyalog APL, 7 байтов

⌈/⌈/-⌊/

Проверьте это на TryAPL .

Как это устроено

⌈/⌈/-⌊/  Dyadic chain. Left argument: d. Right argument: v

     ⌊/  Reduce v by d-wise minimum, yielding the minima of all slices of length d.
  ⌈/     Reduce v by d-wise maximum, yielding the maxima of all slices of length d.
    -    Subtract, yielding the ranges of all slices of length d.
⌈/       Take the maximum.

5

JavaScript (ES6), 73 байта

with(Math)(v,d)=>max(...v.map((a,i)=>max(...a=v.slice(i,i+d))-min(...a)))

+1 за TIL, который вы можете использовать withдля всей лямбда-функции
Bassdrop Cumberwubwubwub

На самом деле Uncaught SyntaxError: Unexpected token with. Можете ли вы опубликовать рабочий фрагмент?
Bassdrop Cumberwubwubwub

@BassdropCumberwubwubwub Если вы хотите назвать лямбду, вам нужно поставить присвоение после with(Math)или использовать f=eval("with(Math)(v,d)=>max(...a)))").
Нил

4

Python, 60 байт

Экономия 5 байтов благодаря Нейлу

f=lambda v,d:v and max(max(v[:d])-min(v[:d]),f(v[1:],d))or 0

Моя первая рекурсивная лямбда!

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

print f([6,9,4,7,4,1], 3)

1
Я думаю, что вы можете просто использовать v and; диапазон не увеличивается, если вы удаляете элементы.
Нил

4

Perl, 48 байт

Включает +5 для -0pi

Задайте ширину после -iпараметра, укажите элементы в STDIN как отдельные строки:

perl -0pi3 -e '/(^.*\n){1,$^I}(?{\$F[abs$1-$&]})\A/m;$_=$#F'
6
9
4
7
4
1
^D

Просто код:

/(^.*\n){1,$^I}(?{\$F[abs$1-$&]})\A/m;$_=$#F

(используйте литерал \nдля заявленной оценки)


Я вижу регулярное выражение, а затем я теряюсь. 0.0 Что здесь происходит?
Эддисон Крамп

@VTCAKAVSMoACE В основном я соответствую 1 к ширине последовательных линий. $&будет содержать все совпадение, которое будет оцениваться как первое число в арифметическом контексте. $1будет содержать последний номер. Затем я принудительно провалил регулярное выражение с \A. Так что он попробует все начальные позиции и длины до ширины. Я использую абсолютное значение разницы в качестве индекса массива и вижу, насколько большой массив растет. У Perl нет встроенных функций, maxпоэтому я должен импровизировать
Тон Хоспел

Это очень умно. В любом случае вы можете положить -0pi3 -eв -0pi3e? Просто предположение о возможном сокращении, я не использую Perl (таким образом, мой вопрос).
Эддисон Крамп

@VTCAKAVSMoACE Нет, к сожалению. -iест все после него в качестве его ценности, в том числе любойe
Тон Хоспел

И я предполагаю, что -eэто должно идти прямо перед кодом? Облом.
Эддисон Крамп

4

R, 63 62 56 байт

Billywob уже предоставил отличный ответ R, используя только базовые функции . Тем не менее, я хотел посмотреть, возможен ли альтернативный подход, возможно, с использованием некоторых обширных пакетов R. Там есть функция хорошо rollapplyв zooупаковке , предназначенной для применения функции к прокатному окну массива, так что соответствует нашей цели хорошо. Мы используем, rollapplyчтобы найти maxкаждого окна, и мы используем его снова, чтобы найти minкаждого окна. Затем мы берем разницу между максимумами и минутами, которая дает нам отклонение для каждого окна, а затем возвращаем maxих.

function(v,d)max((r=zoo::rollapply)(v,d,max)-r(v,d,min))

1
Хорошо, я знал, что была функция для генерации подпоследовательностей, но не мог ее найти. Также за прокси на работе, поэтому не может использовать какие-либо внешние пакеты.
Billywob

1
Некоторый поиск в Google сообщает мне, что есть gtools::rolling, но это еще один байт, и я не знаком с ним. Я всегда думаю об использовании не базовых пакетов: с одной стороны, когда есть простое решение, возникает чувство обмана; с другой стороны, пакеты (и сообщество) являются одной из сильных сторон языка R, я думаю.
rturnbull

3

R, 80 77 байт

Редактировать: 3 байта сохранены благодаря @rturnbull

function(s,d)max(sapply(d:sum(1|s)-d+1,function(i)diff(range(s[i:(i+d-1)]))))

1
Вы можете заменить 1:(length(s)-d+1)на d:sum(1|s)-d+1.
rturnbull

@rturnbull Хороший улов!
Billywob

2

PowerShell v2 +, 68 байт

param($v,$d)($v|%{($x=$v[$i..($i+++$d-1)]|sort)[-1]-$x[0]}|sort)[-1]

Итеративное решение. Циклы $v, но на самом деле мы просто используем это как счетчик, а не просто просматриваем значения. Каждая итерация, мы нарезка $vпо $i..($i+++$d-1), где по $iумолчанию 0. Мы |sortэти элементы, и сохранить результат в $x. Тогда мы берем самое большое [-1]и вычитаем самое маленькое[0] . Мы тогда |sortте результаты и принять самые большие[-1] из этого. Это число остается в конвейере и вывод неявный.

Примеры

PS C:\Tools\Scripts\golfing> .\find-the-maximum-deviation.ps1 @(6,9,4,7,4,1) 3
6

PS C:\Tools\Scripts\golfing> .\find-the-maximum-deviation.ps1 @(1,2,3,4,5,6) 3
2

PS C:\Tools\Scripts\golfing> .\find-the-maximum-deviation.ps1 @(7,2,3,4,5,6) 3
5

2

05AB1E , 12 10 байт

Использует кодировку CP-1252 .

Œù€{øÀ`-ÄZ

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

объяснение

Œ              # sublists of v
 ù             # of length d
  €{           # sort each
    ø          # zip
     À         # rotate left (last 2 lists will be largest and smallest)
      `        # flatten (lists with smallest and largest item will be on top)
       -       # subtract largest from smallest
        Ä      # take absolute value (as we will have negatives after the previous step)
         Z     # take the largest

2

Java 8, 140 128

Побрился, частично благодаря VTCAKAVSMoACE.

int l(int[]a,int d){int x=0,i=0,f,j,k;for(;i<=a.length-d;i++)for(j=i;j<i+d;j++)for(k=i;k<i+d;)x=(f=a[j]-a[k++])>x?f:x;return x;}

Ungolfed

int l(int[]a,int d){
    int x=0,i=0,f,j,k;
    for(;i<=a.length-d;i++)
        for(j=i;j<i+d;j++)
            for(k=i;k<i+d;)
                x=(f=a[j]-a[k++])>x?f:x;
    return x;
}

Вам не хватает конечной скобки. ;)
Эддисон Крамп

@VTCAKAVSMoACE упс. Ошибка копирования и вставки :(
dpa97

1
5-байтовое сокращение:int l(int[]a,int d){int x=0,i=0,f,j,k;for(;i<=a.length-d;i++)for(j=i;j<i+d;j++)for(k=j;k<i+d;)x=(f=a[j]-a[k++])<0?-f:f>x?f:x;return x;}
Аддисон Крамп

@VTCAKAVSMoACE Я не верю, что то, что у тебя будет, может работать неправильно. Попробуйте переключить 7 и 1 в тестовом примере. Тем не менее, я могу использовать это, чтобы побриться от моей новой идеи!
dpa97

1
Я избавился от потребности в abs (что, конечно, значительно ухудшило алгоритм), также запустив k в i. Довольно изящный трюк с x = (f = ...) в одной строке, спасибо за это
dpa97

2

Mathematica, 41 37 байт

Max[MovingMap[MinMax,#,#2-1].{-1,1}]&

Не могли бы вы использовать точечный продукт, {-1,1}чтобы избежать Abs?
миль

@ Майлз Спасибо! Отредактированный ответ.
JungHwan Мин

@JHM Один байт сохранен с Max[BlockMap[MinMax,#,#2,1].{-1,1}]&.

1

Рубин, 45 байт

->a,d{a.each_cons(d).map{|b|b.max-b.min}.max}

Я чувствую, что это может быть намного лучше.


1

MATLAB с наборами инструментов статистики и обработки изображений, 33 байта

@(v,d)max(range(im2col(v,[1 d])))

Это определяет анонимную функцию. Пример использования:

>> f = @(v,d)max(range(im2col(v,[1 d])));
>> f([6,9,4,7,4,1], 3)
ans =
     6

Вы также можете попробовать это на Octave в Ideone. (но Octave, в отличие от Matlab, требует явной загрузки пакета изображений).

объяснение

im2col(v,[1 d]))   % Takes overlapping blocks of size d from v, and arranges them as
                   % columns of a matrix
range(...)         % Maximum minus minimum of each column. Gives a row vector
max(...)           % Maximum of the above row vector

1

Скала, 48 байт

(_:Seq[Int])sliding(_:Int)map(s=>s.max-s.min)max

Ungolfed:

(a:Seq[Int],d:Int)=>a.sliding(d).map(s=>s.max-s.min).max

Объяснение:

(_:Seq[Int])   //define a function with a seq of ints as an argument
sliding(_:Int) //get the sequences with the length of an int argument
map(s=>        //map each sequence
  s.max-s.min    //to its deviation
)max           //and take the maximum value

1

MATL , 10 байт

YCS5LY)dX>

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

объяснение

Рассмотрим входные данные [6,9,4,7,4,1], 3 в качестве примера.

       % Implicitly take the two inputs: v, d
       % STACK: [6,9,4,7,4,1], 3
YC     % Matrix of overlapping d-blocks of v
       % STACK: [6 9 4 7
                 9 4 7 4
                 4 7 4 1]
S      % Sort each column
       % STACK: [4 4 4 1
                 6 7 4 4
                 9 9 7 7]
5LY)   % Keep first and last rows
       % STACK: [4 4 4 1
                 9 9 7 7]
d      % Differences along each column
       % STACK: [5 5 3 6]
X>     % Maximum
       % STACK: 6
       % Implicitly display

1

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

╗╜@V`;m@M-`MM

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

-6 байт из наблюдения в ответе Хаши Нелли , что кусочки короче, чемd не влияют на максимальное отклонение.

Объяснение:

╗╜@V`;m@M-`MM
╗              store d in register 0
 ╜@            push d, swap so v is on top
   V           push all slices of v whose length is in [1, d]
    `;m@M-`M   map (for each slice):
     ;m@M-       get minimum and maximum, subtract min from max
           M  get maximum of list of deviations

1

PHP, 89 87 байт

for($i=1;$r=array_slice($argv,++$i,$argv[1]);$d=max($r)-min($r))$o=$d>$o?$d:$o;echo+$o;

Не особенно умный или красивый, но это работает. Используйте как:

php -r "for($i=1;$r=array_slice($argv,++$i,$argv[1]);$d=max($r)-min($r))$o=$d>$o?$d:$o;echo+$o;" 3 6 9 4 7 1

для v= 6,9,4,7,4,1, d=3

Изменить: 2 байта сохранены благодаря Йорг Хюльсерманн


echo+$o;вместоecho$o?:0;
Йорг Хюльсерманн

0

CJam , 17 байт

q~ew{$)\(\;-}%:e>

(Также q~ew:$z)\(\;.-:e>)

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

объяснение

q~                   e# Read the two inputs. Evaluate
  ew                 e# Overlapping blocks
    {       }%       e# For each block
     $               e# Sort
      )              e# Get last element (that is, maximum)
       \(            e# Swap, get first element (minimum)
         \;          e# Swap, delete rest of the block
           -         e# Subtract (maximum minus minimum)
              :e>    e# Maximum of array

0

Java 7,159 байт

Ява = дорого (я знаю, что это может быть в гольф гораздо больше)

int c(int[]a,int d){int[]b=new int[d];int i,j,s=0;for(i=-1;i<a.length-d;){for(j=++i;j<i+d;)b[i+d-1-j]=a[j++];Arrays.sort(b);s=(j=b[d-1]-b[0])>s?j:s;}return s;}

Ungolfed

static int c ( int []a , int d){
    int []b = new int[ d ];
    int i , j , s = 0 ;
    for ( i = -1 ; i < a.length - d ;) {
        for ( j = ++i ; j < i + d ;)
        b[ i + d - 1 - j ] = a[ j++ ] ;
        Arrays.sort( b ) ;
        s = ( j = b[ d - 1 ] - b[ 0 ] ) > s ? j : s ;
    }
    return s ;
    }

0

Haskell, 56 байт

_#[]=0 
d#l|m<-take d l=max(maximum m-minimum m)$d#tail l

Пример использования: 3 # [6,9,4,7,4,1] ->6 .

Учитывая диапазон меньше , чем dне меняет общий максимум, так что мы можем работать take dвплоть до самого конца списка (т.е. также включают диапазоны с последними d-1, d-2... 0элементами). Рекурсия заканчивается пустым списком, в котором мы устанавливаем отклонение 0.



0

Ракетка 121 байт

(let p((v v)(j 0))(let*((l(take v d))(k(-(apply max l)(apply min l)))
(j(if(> k j)k j)))(if(= d(length v))j(p(cdr v)j))))

Ungolfed:

(define (f d v)
  (let loop ((v v)
             (mxdev 0))                     ; start with max deviation as 0
    (let* ((l (take v d))                   ; take initial d elements in v
           (dev (- (apply max l)            ; find deviation
                    (apply min l)))
           (mxdev (if(> dev mxdev)          ; note max deviation
                   dev
                   mxdev)))
      (if (= d (length v)) mxdev            ; if all combinations tested, print max deviation
          (loop (rest v) mxdev))            ; else test again 
      )))                                   ; with first element of list removed

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

(f 3 '(6 9 4 7 4 1))

Выход:

6

0

q, 25 байтов

{max mmax[y;x]-mmin[y;x]}

mmaxи mminскользящее окно максимум и минимум соответственно

пример

q){max mmax[y;x]-mmin[y;x]}[6 9 4 7 4 1;3]
6

0

C #, 131 байт

вот подробное решение linq

int c(int[]a){var x=from j in Enumerable.Range(0,a.Length-2)let p=new[]{a[j],a[j+1],a[j+2]}select p.Max()-p.Min();return x.Max();}

0

C #, 163 байта

Golfed:

int m(List<int> v,int d){var l=new List<List<int>>();for(int i=0;i<v.Count;i++){if(v.Count-i>=d)l.Add(v.GetRange(i,d));}return l.Select(o=>o.Max()-o.Min()).Max();}

Ungolfed:

public int m(List<int> v, int d)
{
  var l = new List<List<int>>();

  for (int i = 0; i < v.Count; i++)
  {
    if (v.Count - i >= d)
      l.Add(v.GetRange(i, d));
  }

  return l.Select(o => o.Max() - o.Min()).Max();
}

Тестовое задание:

var maximumDeviation = new MaximumDeviation();
Console.WriteLine(maximumDeviation.f(new List<int> {6,9,4,7,4,1}, 3));

Выход:

6

0

Pyth, 11 байт

eSms.+Sd.:F

объяснение

eSms.+Sd.:FQ   Implicit input
          FQ   Unpack the input (v, d)
        .:     Get all subsequences of length d
  m   Sd       Sort each
   s.+         Take the sum of differences to get the deviation
eS             Get the maximum

0

Желе , 8 байт

ṡµṂ€ạṀ€Ṁ

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

Использует тот же алгоритм, что и Dyalog APL, но я сам понял это, прежде чем посмотреть на него.

Объяснение:

ṡµṂ€ạṀ€Ṁ ḷ“Main link. Arguments: v d.”
ṡ        ḷ“Overlapping sublists of x of length y.”
 µ       ḷ“Start a new monadic chain.”
  Ṃ€ạṀ€  ḷ“Find the deviation of each of the elements of x.”
       Ṁ ḷ“Take the maximum of x.”

Примечание: x, yоставлены, правильные аргументы соответственно.


0

Perl 6 , 44 байта

{$^a.rotor($^b=>1-$^b).map({.max-.min}).max}

$^aи $^bявляются двумя аргументами функции, вызванной vи dсоответственно в постановке задачи. rotorМетод возвращает последовательность подпоследовательностей vразмера d.


0

Clojure, 73 67 байт

Изменить: Использование #(...)вместо (fn[...])и forвместо map.

#(apply max(for[p(partition %2 1 %)](-(apply max p)(apply min p))))

0

Python 3, 80 байт

lambda v,d:max(map(lambda g:max(g)-min(g),[v[i:i+d]for i in range(-~len(v)-d)]))

Вы можете использовать (max(v[i:i+d])-min(v[i:i+d])for i in range(-~len(v)-d)вместоmap(lambda g:max(g)-min(g),[v[i:i+d]for i in range(-~len(v)-d)])
Мастер пшеницы
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.