找到最大偏差


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.

这是代码高尔夫,所以最短的答案以字节为单位。

Answers:


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)))

您可以with在整个lambda函数上使用的TIL +1
Bassdrop Cumberwubwubwub 16-10-21

实际上,Uncaught SyntaxError: Unexpected token with。您可以发布有效的代码段吗?
Bassdrop Cumberwubwubwub

@BassdropCumberwubwubwub如果要命名lambda,则需要将赋值放在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

我的第一个递归lambda!

用法:

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这是怎么回事?
Addison Crump

@VTCAKAVSMoACE基本上,我将1匹配到宽度连续的行。$&将包含整个匹配项,该匹配项将在算术上下文中评估为第一个数字。$1将包含最后一个数字。然后,我用强制使正则表达式失败\A。因此它将尝试所有起始位置和长度直至宽度。我将差的绝对值用作数组索引,并查看数组的增长量。Perl有没有内置的max,所以我必须凑合
吨Hospel

那太聪明了。什么办法可以把-0pi3 -e-0pi3e?只是对可能减少的假设,我不使用perl(因此是我的问题)。
Addison Crump

@VTCAKAVSMoACE不幸的是,没有。-i吃掉一切作为其价值的东西,包括任何东西e
Ton Hospel

我假设那-e必须在代码之前进行?笨蛋
Addison Crump

4

R,63 62 56字节

Billywob已经仅使用基本函数提供了很好的R答案。但是,我想看看是否可以使用另一种方法,也许使用R的一些扩展包。包中有一个不错的函数rollapplyzoo旨在将函数应用于数组的滚动窗口,因此非常适合我们的目的。我们使用rollapply查找max每个窗口的,然后再次使用它查找min每个窗口的。然后,我们取最大和最小之间的差,这将为我们提供每个窗口的偏差,然后返回max这些窗口的。

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

1
很好,我知道有一个生成子序列的函数,但是找不到。同样在工作的代理后面,因此不能使用任何外部软件包。
Billywob '16

1
进行一些谷歌搜索后,我发现还存在gtools::rolling,但这又是一个字节,我对此并不熟悉。对于使用非基本软件包,我总是有两种想法:一方面,当有一个简单的解决方案时,感觉就像作弊;另一方面,我认为这些软件包(和社区)是R语言的优势之一。
rturnbull

3

R,80 77字节字节

编辑:由于@rturnbull,节省了3个字节

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 '16

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

05AB1E12 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

爪哇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;}

不打高尔夫球

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;
}

您缺少尾括号。;)
Addison Crump

@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;}
Addison Crump

@VTCAKAVSMoACE我不相信您拥有的东西可能是错误的。尝试在测试用例中切换7和1。但是,我可以使用它来消除我的新想法!
dpa97

1
我也通过在i处启动k来消除了对abs的需求(当然,在该过程中会使算法变得更糟)。在同一行中有x =(f = ...)的漂亮技巧,谢谢
dpa97

2

Mathematica,41 37字节

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

您不能将dot产品{-1,1}用于避免Abs吗?
2016年

@miles谢谢!编辑答案。
JungHwan Min

@JHM用保存的一个字节Max[BlockMap[MinMax,#,#2,1].{-1,1}]&

1

Ruby,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

您也可以在Ideone的Octave上进行尝试(但与Matlab不同,Octave需要显式加载映像包)。

说明

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

Scala,48个字节

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

取消高尔夫:

(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

在线尝试!

从Nimi的Haskell答案中观察到的-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,1d=3

编辑:感谢JörgHülsermann节省了2个字节


echo+$o;而不是echo$o?:0;
约尔格Hülsermann

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字节

Java =昂贵(我知道它可以打得更多)

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;}

不打高尔夫球

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-1d-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))))

取消高尔夫:

(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]}

mmaxmmin分别是滑动窗口的最大值和最小值

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个字节

打高尔夫球:

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();}

取消高尔夫:

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.”

注:xy在左,右分别争论。


0

Perl 6, 44 bytes

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

$^a and $^b are the two arguments to the function, called v and d respectively in the problem statement. The rotor method returns the sequence of subsequences of v of size d.


0

Clojure, 73 67 bytes

Edit: Using #(...) instead of (fn[...]) and for instead of map.

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

0

Python 3, 80 bytes

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

you can use (max(v[i:i+d])-min(v[i:i+d])for i in range(-~len(v)-d) instead of map(lambda g:max(g)-min(g),[v[i:i+d]for i in range(-~len(v)-d)])
Wheat Wizard
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.