找出距离n最多的n个位置


29

这个问题的后遗症。

任务

给定正整数数组,找到最大元素k

存在一些正整数距离n,因此位于n中的数组中的元素位于距k  左右等于n的位置

确保该数组包含至少一个满足此条件的元素。

最短的代码(以字节为单位)获胜。您可以选择所需的任何I / O格式。

给定输入

[4, 6, 7, 9, 3, 6, 5, 7, 2]

合格值为:

  • 4,因为有一个7位于7个位置的右
  • 第一个6,因为3它的右边有3个位置
  • 3,因为有一个4位于4个位置到其左
  • 5,因为有一个2位于2位在它的右边
  • 第二个7,因为它3位于左侧3个位置。

在这些值中,最大的是7

测试用例

[1, 13] → 13
[2, 9, 8, 3, 72, 2] → 8
[5, 28, 14, 5, 6, 3, 4, 7] → 14
[1, 3, 5, 15, 4, 1, 2, 6, 7, 7] → 7
[5, 1, 3, 5, 2, 5, 5, 8, 5, 1, 5, 1, 2, 3] → 5
[5, 12, 2, 5, 4, 7, 3, 3, 6, 2, 10, 5, 5, 5, 4, 1, 8, 5] → 10

该示例中还有另外两种情况(尽管有些多余):前6种(再次),因为右边有5种5个位置;或第二个7(再次),因为它剩下6个六个位置。
乔纳森·艾伦

1.在我的手机上,标题似乎是“查找距离最大的位置”。2.陈述的条件是,存在一些k,使得(一个不依赖k的属性)。这肯定是错误的。
彼得·泰勒

@PeterTaylor“此元素”中的“ this”是指k。
Taemyr

1
@Taemyr,由于两个原因,这没有任何意义:首先,因为k未被声明为元素。其次,由于要求我们“ 找到满足 ”条件的最大元素,因此“ 此元素 ”在条件之外具有先行条件。
彼得·泰勒

2
也许您可以通过说“找到最大的元素k这样”,然后在定义中使用k而不是该元素来避免所有混乱?
马丁·恩德

Answers:


3

果冻,9 字节

Jạþ`=ḅa¹Ṁ

在线尝试!验证所有测试用例

怎么运行的

Jạþ`=ḅa¹Ṁ  Main link. Argument: A (array)

J          Indices; yield [1, ..., len(A)].
   `       Use the previous return value as left and right argument:
 ạþ        Absolute difference table; take the absolute value of the difference
           of each pair of indices, yielding a 2D array.
    =      Compare each absolute difference with the corresponding item of A.
     ḅ     Base; convert each Boolean list from base i to integer, where i is the
           corresponding item of A. The value of i is not important; we only care
           if the list contains a 1, which will result in a non-zero integer.
       ¹   Identity; yield A.
      a    Logical AND; replace non-zero values with the corresponding items of A.
        Ṁ  Take the maximum.

1
嗯,不确定这是什么策略,但是您现在有两种不同的方法,分别由同一用户使用相同的程序语言来回答。将9字节和10字节的摘要放在相同的答案中不是更明智的做法,因为这是相同的编程语言,而且由您自己决定?我可以理解多个用户使用同一编程语言编写的多个答案,但是我个人认为同一用户使用相同编程语言的不同方法更适合作为编辑。只是我的观点。
凯文·克鲁伊森

5
那是我的第一个meta问题,共识似乎是在不同的答案中应张贴不同的方法。在这种情况下,我的方法除了结尾处的最大值外没有别的,所以我去了另一篇文章。
丹尼斯

8

05AB1E,21字节

vyN+Ny-})¹gL<Ãv¹yè})Z

说明

v      }               # for each num in input
 yN+                   # push index + num
    Ny-                # push index - num
        )              # wrap stack in a list
         ¹gL<Ã         # remove indices outside the range of input
              v¹yè})   # get list of elements in input at the remaining indices
                    Z  # get max

在线尝试!


您可能一直在使用它,但是我只是注意到“将堆栈包装在列表中”。整齐。
GreenAsJade

@GreenAsJade:是的,这是我使用最多的命令之一:)
Emigna

7

Haskell,61 57 55字节

f x=maximum[a|(n,a)<-x,(i,b)<-x,b==abs(n-i)]
f.zip[0..]

用法示例:(f.zip[0..]) [5,28,14,5,6,3,4,7]-> 14

(或多或少)定义的直接实现:对于n输入列表的每个索引,如果存在等于的索引,则x保留。找到最大值。a := x!!nib := x!!iabs(n-i)

编辑:@xnor保存了两个字节。谢谢!


由于您没有使用x,因此在中定义函数z并在其中编写代码应该更短一些zip[0..]
xnor

6

果冻,10 字节

,N+JFfJị¹Ṁ

在线尝试!验证所有测试用例

怎么运行的

,N+JFfJị¹Ṁ  Main link. Argument: A (array)

,N          Pair A with -A (element-wise negative).
   J        Yield the indices of A [1, ..., len(A)].
  +         Add the elements of A (and their negatives) with the corr. indices.
    F       Flatten the resulting 2D array.
     fJ     Filter indices; remove invalid indices (not in [1, ..., len(A)]) from
            the generated array. The result is the list of all indices of eligible
            elements of A.
       ị¹   Retrieve the corresponding elements of A.
         Ṁ  Take the maximum.

5

Python 3, 85 80 72字节

lambda l,e=enumerate:max(i for p,i in e(l)for s,j in e(l)if j==abs(s-p))

编辑:-8字节感谢@Dennis


5

EXCEL:32 30字节

=MAX(IF(A:A-ROW(A:A)<0,A:A,0))

我仍然不敢相信我会这么短...

使用方法:将其
粘贴到除A列的单元格之外的任何单元格中。粘贴后,仍在编辑时,按control+ shift+ enter正确输入。
将您的值放入A列,每个单元格1个值(根据CSV条目)。

如果您想了解它是如何工作的,我在我的文章中附加了一个提示 在Excel中打高尔夫球的提示问题中。


我爱这些出色的高尔夫球-谁会想到的!
GreenAsJade

4

JavaScript(ES6),61个字节

a=>Math.max(...a.filter((_,i)=>a.some((e,j)=>e==i-j|e==j-i)))

4

Perl,45个字节

包括+2 -ap

在STDIN的一行上给数字:

largest.pl <<< "5 12 2 5 4 7 3 3 6 2 10 5 5 5 4 1 8 5"

largest.pl

#!/usr/bin/perl -ap
($_)=sort{$b-$a}map@F[$^P=$n-$_,$n+++$_],@F

通过替换可以再获得一个字节 ^P文字控制字符,但是这会导致在最近的Perls上出现STDERR警告。

假设 largest number + array length < 2^32


3

Pyth,19个 17字节

感谢@ Pietu1998为-2个字节

eS@LQ@UQs.e,-kb+b

一个程序,在STDIN上输入列表并打印结果。

在线尝试

怎么运行的

eS@LQ@UQs.e,-kb+b  Program. Input: Q
         .e        Map over Q (implicit input fill) with elements as b and indices as k:
            -kb     k-b
               +b   k+b (Implicit fill with k)
           ,        2-element list of those (possible indices)
        s          Flatten that
      UQ           Yield [0, 1, 2, 3..., len(Q)-1]
     @             Filter the flattened list by presence in the above, removing invalid
                   indices
  @LQ              Index into Q at those indices
 S                 Sort that
e                  Yield the last element of that, giving the maximum
                   Implicitly print

}#与相同@。另外,如果您将最后一位重新排列,则,-kb+bk可以删除最后一位,k因为Pyth自动插入了最后一位。
PurkkaKoodari

@ Pietu1998谢谢。我不知道枚举的隐式填充。对其他任何地图类型的功能有效吗?
TheBikingViking

适用于任何lambda,它将使用第一个lambda变量自动填充其余lambda。
PurkkaKoodari

3

MATL,13字节

ttn:tYTq=a)X>

输入必须是列向量。即,输入以分号分隔,如[1; 2; 3],或以逗号分隔,最后以转置记号分隔,如[1,2,3]'。

在线尝试!

所有测试用例:(A)(B)(C)(D)(E)(F)

感谢Suever在MATL聊天室中建议保存2个字符。

说明:

总体策略与我的Octave / MATLAB答案相同,其中解释了基本概念:https : //codegolf.stackexchange.com/a/94161/42247

此MATL答案中的特定代码如下构建:

该方法的核心是构造第ij个条目为abs(ij)的Toeplitz矩阵。我们首先使用MATL的toeplitz命令YT构造abs(i-1)+1项的Toeplitz矩阵,如下所示:

n:tYT % Equivalent to @(v)toeplitz(1:length(v))

要查看其工作原理,让我们将输入向量称为此代码段“ v”。'n'找到v的长度,然后':'构造向量1:length(v)。接下来,“ t”在堆栈上复制另一个1:length(v)的副本;由于MATL的YT函数(相当于toeplitz()的MATL)中的一个众所周知的错误,需要额外的副本,其中它期望输入的两个副本而不是1。然后YT接受此向量的两个副本1 :length(v),从堆栈中取出abs(ij)+1 Toeplitz矩阵。

现在我们需要从该矩阵中减去1以获得具有abs(ij)项的Toeplitz矩阵,并找到该abs(ij)Toeplitz矩阵等于包含输入列副本的所有列向量的矩阵的ij位置向量v。这样做如下:

t n:tYT q=
% t [code] q= is equivalent to @(v) [code](v)-1 == v

第一个“ t”会额外复制输入内容并将其存储在堆栈中。'n:tYT'如前所述制作toeplitz矩阵并将其输出到堆栈中。然后,“ q”从Toeplitz矩阵中减去1,而“ =”在abs(ij)矩阵和其列为输入副本的向量之间进行元素相等性比较。请注意,通过将列向量与矩阵进行比较,我们隐式地利用了MATLAB / MATL的运算符广播规则(比较中的列向量被复制为矩阵,而无需发出任何命令)。

最后,我们需要找到行索引i,其中存在列j,以使上面构造的矩阵差中的第ij个条目等于1,然后获取与这些索引对应的输入矢量的值,然后取最大值。这分以下三个步骤:

1)查找包含非零的任何行的索引:

tn:tYTq= a
% [code] a is equivalent to @(v) any([code](v))

2)提取与这些索引相对应的输入向量的元素:

t tn:tYTq= a ) X>
% t [code] ) is equivalent to @(v) v([code](v)]

3)查找并返回最大元素:

t tn:tYTq= a ) X>
% [code] X> is equivalent to @(v) max(v).

版本20.2.2中功能的行为YT已更改。现在,默认情况下它使用1个输入(通常更有用)。尽管这样做可以为您节省1个字节(在之前删除),但是由于语言的更改使挑战晚了,因此无法利用。但这会导致您的答案在新版本中不再有效,该新版本现已在TIO中发布tYT
Luis Mendo

您既可以编辑链接的代码并留下注释,也可以使用指向 MATL Online解释程序的链接,该解释程序支持较早的版本。不幸的是,您还需要更新其他链接。抱歉给您带来不便
路易斯·门多


2

Ruby,66个字节

->a{i=-1;a.map{|e|i+=1;[a[j=i+e]||0,a[0>(k=i-e)?j:k]||0].max}.max}

2

八度/ MATLAB,40字节

@(v)max(v(any(toeplitz(1:nnz(v))-v==1)))

输入必须是列向量。

感谢Luis Mendo为节省3个字节的建议(请参阅注释)

感谢Suever的建议,节省了4个字节(用any()替换~~(sum()))

说明:

给定输入向量v,此问题等效于找到以下离散方程的所有解i,j,

abs(i-j) = v(i),   i,j both in 1..k,

其中abs()是绝对值函数。求解该方程的每个v(i)是我们可以最大化的候选解决方案之一。

作为i和j的离散函数,可以将左侧的所有可能性布置在看起来像这样的toeplitz矩阵中:

[0, 1, 2, 3, 4]
[1, 0, 1, 2, 3]
[2, 1, 0, 1, 2]    <--- abs(i-j)
[3, 2, 1, 0, 1]
[4, 3, 2, 1, 0]

而且由于右侧不依赖于i,因此可以将所有可能性都排列成矩阵,其中各列都是输入的副本,

[v(1), v(1), v(1), v(1), v(1)]
[v(2), v(2), v(2), v(2), v(2)]
[v(3), v(3), v(3), v(3), v(3)]   <--- v(i)
[v(4), v(4), v(4), v(4), v(4)]
[v(5), v(5), v(5), v(5), v(5)]

为了找到该方程的所有解,我们将这两个矩阵相减并找到零的位置。零的行对应于aj的期望索引i,使得abs(ij)= v(i)。

其他技巧:

  • 构造绝对值函数加abs(ij)+1所需的字符较少,然后检查差异为1的位置,而不是构造真实的(未移位的)绝对值函数。
  • 使用自动操作员广播隐式制作v的列副本
  • 通过nnz()而不是length()获取输入的长度,这是有效的,因为在问题陈述中输入被认为是肯定的。

输入格式默认是灵活的。您可以将其v作为列向量,只需在答案中说明即可。此外,您更换find~~,以节省两个字节
路易斯Mendo

@LuisMendo谢谢,我编辑了帖子以纳入您的建议!
Nick Alger

对于不同的语言(或使用相同语言的方法大不相同),您应该发布另一个答案。如果您对语言有任何疑问,可以使用MATL聊天室
Luis Mendo

顺便说一句,由于MATL toeplitzYT)中的错误,默认情况下它使用两个输入(不是一个)
Luis Mendo

嗯不错。我将其翻译为MATL,并在此处发布了另一个答案:codegolf.stackexchange.com/a/94183/42247
Nick Alger

1

Mathematica,69个字节

Max@MapIndexed[{If[#2[[1]]>#,a[[#2-#]],{}],a[[#2+#]]~Check~{}}&,a=#]&

匿名函数。将整数列表作为输入,并返回整数作为输出。忽略任何生成的消息。


1

Scala,94个字节

a=>a.zipWithIndex.filter(p=>a.zipWithIndex.exists(x=>x._1==Math.abs(p._2-x._2))).unzip._1.max

1

PHP,128字节

<?foreach(($i=$_GET[i])as$k=>$v){$k-$v<0?:!($i[$k-$v]>$m)?:$m=$i[$k-$v];if($k+$v<count($i))if($i[$k+$v]>$m)$m=$i[$k+$v];}echo$m;

1

Java 7,125 123字节

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

@mrco节省了2个字节。

松散的(某种)和测试代码:

在这里尝试。

class M{
  static int c(int[] a){
    int r = 0,
        i = 0,
        l = a.length,
        x;
    for(; i < l; r = l > (x = i + a[i])
                      ? a[x] > r
                         ? a[x]
                         : r
                      : r,
                 r = (x = i - a[i++]) > 0
                      ? a[x] > r
                         ? a[x]
                         : r
                      : r);
    return r;
  }

  public static void main(String[] a){
    System.out.println(c(new int[]{ 1, 13 }));
    System.out.println(c(new int[]{ 2, 9, 8, 3, 72, 2 }));
    System.out.println(c(new int[]{ 5, 28, 14, 5, 6, 3, 4, 7 }));
    System.out.println(c(new int[]{ 1, 3, 5, 15, 4, 1, 2, 6, 7, 7 }));
    System.out.println(c(new int[]{ 5, 1, 3, 5, 2, 5, 5, 8, 5, 1, 5, 1, 2, 3 }));
    System.out.println(c(new int[]{ 5, 12, 2, 5, 4, 7, 3, 3, 6, 2, 10, 5, 5, 5, 4, 1, 8, 5 }));
  }
}

输出:

13
8
14
7
5
10

1
您不需要x和y。只需重用其中之一(-2)。我也不认为您可以将r设置为一个很大的三进制,因为您总是必须同时测试左右两种情况。
mrco 16/09/23

1
@mrco谢谢,删除了,y。对于单三元if,我确实得出了相同的结论。当然可以,但是您将进行两次检查,使检查时间更长。
凯文·克鲁伊森

1

Java,118个字节

int f(int[]a){int t=0,i,j,z=0,l=a.length;while(t<l*l){i=t/l;j=t++%l;z=a[i]>z&&((i<j?j-i:i-j)==a[j])?a[i]:z;}return z;}

欢迎来到PPCG!:)
Martin Ender

1

Python,58个字节

基于Tony S.的Ruby answer。此答案适用于Python 2和3。欢迎打高尔夫球。

lambda n:max([n[i+v]for i,v in enumerate(n)if i+v<len(n)])

开球

def f(array):
    result = []
    for index, value in enumerate(array):
        if index + value < len(array):
            result.append(array[index + value])
    return max(result)

1

Ruby 56字节

我最小的红宝石解决方案。

->n{x=[];i=0;n.map{|v|x<<n[v+i]&&v+i<n.size;i+=1};x.max}

在Rails控制台中非常容易测试

a = ->n{x=[];i=0;n.map{|v|x<<n[v+i]&&v+i<n.size;i+=1};x.max}
a[[1, 13]
=> 13
a[[2, 9, 8, 3, 72, 2]]
=> 8
a[[5, 12, 2, 5, 4, 7, 3, 3, 6, 2, 10, 5, 5, 5, 4, 1, 8, 5]]
=> 10

它开始于63字节,感谢您提出的建议以帮助减少它!


你可以使用.map,而不是.each
Cyoce

(x) if (y)可以替换为(y)&&(x)
Cyoce

您可以使用a<<b,而不是a+=[b]
Sherlock9

@ Sherlock9我忘记了<<。使用a + = [b]不适用于Cyoce使用&&的建议。现在可以了,谢谢!
Tony S.

1

其实是17个位元组

这个答案实际上是我的Python答案的端口。欢迎打高尔夫球。在线尝试!

;╗ñ♂Σ⌠╜l>⌡░⌠╜E⌡MM

开球

         Implicit input L.
;╗       Duplicate L and save a copy of L to register 0.
ñ        enumerate() the other copy of L.
♂Σ       sum() all the pairs of [index, value of n]. Call this list Z.
⌠...⌡░   Push values of Z where the following function returns a truthy value. Variable v_i.
  ╜        Push L from register 0.
  l        Push len(L).
  >        Check if len(L) > v_i.
⌠...⌡M   Map the following function over Z_filtered. Variable i.
  ╜        Push L from register 0.
  E        Take the ith index of L.
M        max() the result of the map.
         Implicit return.

0

T-SQL(sqlserver 2016),132字节

打高尔夫球:

;WITH C as(SELECT value*1v,row_number()over(order by 1/0)n FROM STRING_SPLIT(@,','))SELECT max(c.v)FROM C,C D WHERE abs(D.n-C.n)=D.v

取消高尔夫:

DECLARE @ varchar(max)='2, 9, 8, 3, 72, 2'

;WITH C as
(
  SELECT
    value*1v,
    row_number()over(order by 1/0)n
  FROM
    STRING_SPLIT(@,',')
)
SELECT
  max(c.v)
FROM
  C,C D
WHERE
  abs(D.n-C.n)=D.v

小提琴


0

JavaScript(ES6),56 54字节

let f =
    
l=>l.map((n,i)=>m=Math.max(m,l[i+n]|0,l[i-n]|0),m=0)|m

console.log(f([1, 13])); // → 13
console.log(f([2, 9, 8, 3, 72, 2])); // → 8
console.log(f([5, 28, 14, 5, 6, 3, 4, 7])); // → 14
console.log(f([1, 3, 5, 15, 4, 1, 2, 6, 7, 7])); // → 7
console.log(f([5, 1, 3, 5, 2, 5, 5, 8, 5, 1, 5, 1, 2, 3])); // → 5
console.log(f([5, 12, 2, 5, 4, 7, 3, 3, 6, 2, 10, 5, 5, 5, 4, 1, 8, 5])); // → 10


0

Clojure,68个字节

#(apply max(map(fn[i](get % i 0))(flatten(map-indexed(juxt - +)%))))

例如,(map-indexed (juxt - +) [3 4 1 2])([-3 3] [-3 5] [1 3] [1 5])+/-为其值编制索引),这些值用于从原始向量中查找值(超出范围的默认0值是),并找到最大值。仍然有点冗长,但至少我必须使用juxt:)

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.