查找与零相邻的最大数字


38

挑战:

以向量/整数列表作为输入,并输出与零相邻的最大数字。

规格:

  • 与往常一样,可选的输入和输出格式
  • 您可以假定将至少有一个零和至少一个非零元素。

测试用例:

1 4 3 6 0 3 7 0
7

9 4 9 0 9 0 9 15 -2
9

-4 -6 -2 0 -9
-2

-11 0 0 0 0 0 -12 10
0

0 20 
20

祝你好运,打高尔夫球愉快!


您应该添加第4个测试用例,但结果为负(列表中有正数)。
mbomb007'9

我本来打算在Retina上尝试,但后来我发现里面有底片。视网膜讨厌底片。
mbomb007'9

2
不要让视网膜决定您可以做什么和不能做什么。负责,你是老板!
Stewie Griffin

Answers:



19

MATL,10字节

t~5BZ+g)X>

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

说明

让我们以输入[-4 -6 -2 0 -9]为例。

t     % Input array. Duplicate
      %   STACK: [-4 -6 -2 0 -9],  [-4 -6 -2 0 -9]
~     % Logical negate. Replaces zeros by logical 1, and nonzeros by logical 0
      %   STACK: [-4 -6 -2 0 -9],  [0 0 0 1 0]
5B    % Push logical array [1 0 1] (5 in binary)
      %   STACK: [-4 -6 -2 0 -9], [0 0 0 1 0], [1 0 1]
Z+    % Convolution, maintaining size. Gives nonzero (1 or 2) for neighbours of
      % zeros in the original array, and zero for the rest
      %   STACK: [-4 -6 -2 0 -9], [0 0 1 0 1]
g     % Convert to logical
      %   STACK: [-4 -6 -2 0 -9], [0 0 1 0 1]
)     % Use as index into original array
      %   STACK: [-2 -9]
X>    % Maximum of array.
      %   STACK: -2
      % Implicitly display

x(~~(dec2bin(5)-48))。实施那个是谁的想法?非常聪明,对逻辑数组很有用!:)好答案!
Stewie Griffin

1
@WeeingIfFirst谢谢!我已经dec2bin()-'0'在MATLAB中使用了数百次,所以我知道必须在MATL中进行:-)
Luis Mendo

5
顺便说一句,您值得在每次操作后包括堆栈内容的事实。它使理解(甚至可能学习)MATL =)变得非常容易
Stewie Griffin

2
卷积岩。+1
Suever

10

05AB1E,9个字节

ü‚D€P_ÏOZ

说明

ü‚         # pair up elements
  D        # duplicate
   €P      # product of each pair (0 if the pair contains a 0)
     _     # logical negate, turns 0 into 1 and everything else to 0
      Ï    # keep only the pairs containing at least 1 zero
       O   # sum the pairs
        Z  # take max

在在线解释器中不起作用,但在离线状态下起作用。


哈哈!及时:p。
阿德南

1
刚刚实现了这些运算符之一还是?:)
Stewie Griffin

1
@WeeingIfFirst:ü是昨天才添加的:)
Emigna'Sep

2
0如果实际答案是否定的,这不会回报吗?我认为您必须排除零。
林恩

1
@Lynn不错!通过用(sum)替换˜,可以轻松解决此问题O
阿德南

9

Haskell,63个 43字节

f x=maximum[a+b|(a,b)<-tail>>=zip$x,a*b==0]

感谢@MartinEnder提供4个字节!


我认为您可以使用a*b==0代替||
Martin Ender's

您必须使用zip返回先前的版本。这里a和be不再相邻
Damien

您在这里不需要lambdabot。这是“常规” Haskell
Damien 2016年

8

Pyth,12 11 10字节

eSsM/#0,Vt

形成对,按零成员过滤,按和排序,返回最大。


,Vt(implicit QQ)返回与相同的对.:Q2,但对被翻转。应该可以,但是。
PurkkaKoodari

f}0T/#0
isaacg

7

JavaScript(ES6),59 57 56字节

let f =
    
l=>l.map((n,i)=>m=l[i-1]==0|l[i+1]==0&&n>m?n:m,m=-1/0)|m

console.log(f([1, 4, 3, 6, 0, 3, 7, 0]));       // 7
console.log(f([9, 4, 9, 0, 9, 0, 9, 15, -2]));  // 9
console.log(f([-4, -6, -2, 0, -9]));            // -2
console.log(f([-11, 0, 0, 0, 0, 0, -12, 10]));  // 0
console.log(f([3, 0, 5]));                      // 5
console.log(f([28, 0, 14, 0]));                 // 28

编辑:感谢Huntro保存2个字节编辑:感谢ETHproductions
保存1个字节


1
您可以使用==而不是===
Huntro

1
我可以在几个地方保存一些字节:l=>l.map((n,i)=>m=l[i-1]*l[i+1]==0&n>m?n:m,m=-1/0)|m
ETHproductions 2016年

错误:{“消息”:“语法错误”,“文件名”:“ stacksnippets.net/js”、“lineno”:15、“colno”:3 }
RosLuP

@RosLuP-这需要具有箭头功能支持的ES6,并且不适用于所有浏览器(包括但不限于:Edge之前的所有IE版本,v10以下的所有Safari版本等)
Arnauld

6

JavaScript(ES6),53个字节

a=>(m=-1/0,a.reduce((l,r)=>(m=l*r||l+r<m?m:l+r,r)),m)

因为我喜欢使用reduce。替代解决方案,也是53个字节:

a=>Math.max(...a.map((e,i)=>e*a[++i]==0?e+a[i]:-1/0))

5

Python,49个字节

lambda a:max(sum(x)for x in zip(a,a[1:])if 0in x)

测试在ideone

将所有对压缩,将包含任何零的那些相加,返回最大值。


4

Ruby,51个字节

->a{a.each_cons(2).map{|a,b|a*b!=0?-1.0/0:a+b}.max}

用法

f=->a{a.each_cons(2).map{|a,b|a*b!=0?-1.0/0:a+b}.max}
p f[gets.split.map(&:to_i)]

我认为您不需要括号a+b
马丁·恩德

发生@Martin Ender语法错误... ideone.com/F6Ed4B
cia_rana

它可以在Ruby 2.3中使用。(例如,在此处提供:repl.it/languages/ruby
Martin Ender

@Martin Ender当我使用“!=”而不是“ ==”时,它起作用了。谢谢你的建议!ideone.com/F6Ed4B
cia_rana

那里面有:(一错误。-3 -2 0回到0我认为更换。...?0:......?-1.0/0:...应该修复它,增加5个字节。
M-chrzan

4

PHP,77 68 71字节

来自匿名的-3个字节,来自MartinEnder的-4个和-2个

preg_match_all("#(?<=\b0 )\S+|\S+(?= 0)#",$argv[1],$m);echo max($m[0]);

php -r '<code>' '<space separated values>'


2
\K到目前为止,使用放弃匹配比使用后向查找要短。
user59178

2
您还可以将空格用于输入,然后用于\S+匹配带符号的整数。您可能需要使用,\b0,因此不必在之前添加,
Martin Ender's

1
这对像这样的输入有用4 0 0 5吗?
Ton Hospel '16

@TonHospel否。\K不能使用替代方法吗?出于未知原因,第二个替代方案返回0 0,因此0在之前没有其他匹配项5。固定,谢谢。
泰特斯(Titus)2016年

请看看了register_globals其他PHP解决方案
约尔格Hülsermann

4

Java 7中,118个 105 106字节

int d(int[]a){int i=0,m=1<<31,c;for(;++i<a.length;m=a[i]*a[i-1]==0&(c=a[i]+a[i-‌​1])>m?c:m);return m;}

@cliffroot通过使用算术方法节省了13个字节。@mrco发现错误后,还要多 1个字节(添加的测试用例2, 1, 02代替而不返回1)。

取消测试代码:

在这里尝试。

class M{
  static int c(int[] a){
    int i,
        m = a[i=0],
        c;
    for(; ++i < a.length; m = a[i] * a[i-1] == 0 & (c = a[i] + a[i - 1]) > m)
                           ? c
                           : m);
    return m;
  }

  public static void main(String[] a){
    System.out.println(c(new int[]{ 1, 4, 3, 6, 0, 3, 7, 0 }));
    System.out.println(c(new int[]{ 9, 4, 9, 0, 9, 0, 9, 15, -2 }));
    System.out.println(c(new int[]{ -4, -6, -2, 0, -9 }));
    System.out.println(c(new int[]{ -11, 0, 0, 0, 0, 0, -12, 10 }));
    System.out.println(c(new int[]{ 0, 20 }));
    System.out.println(c(new int[]{ 2, 1, 0 }));
  }
}

输出:

7
9
-2
0
20
1

1
使用算术略有不同的方法似乎正在奏效int d(int[]a){int i,m=a[i=0],c;for(;++i<a.length;m=a[i]*a[i-1]==0&(c=a[i]+a[i-1])>m?c:m);return m;}
悬崖根

3
当第一个数字不与0相邻但大于与0相邻的任何数字时,输出错误。可由测试用例{2,1,0}重现。您可以通过直接将i初始化为0并将m初始化为1 << 31(总共+1)来解决此问题。
mrco

3

CJam,16字节

q~2ew{0&},::+:e>

在线尝试!(作为测试套件。)

说明

q~    e# Read and eval input.
2ew   e# Get all (overlapping) pairs of adjacent values.
{0&}, e# Keep only those that contain a 0.
::+   e# Sum each pair to get the other (usually non-zero) value.
:e>   e# Find the maximum.

3

带图像处理工具箱的MATLAB,32字节

@(x)max(x(imdilate(~x,[1 0 1])))

这是一个匿名函数。测试用例的示例用法:

>> f = @(x)max(x(imdilate(~x,[1 0 1])))
f =
  function_handle with value:
    @(x)max(x(imdilate(~x,[1,0,1])))

>> f([1 4 3 6 0 3 7 0])
ans =
     7

>> f([9 4 9 0 9 0 9 15 -2])
ans =
     9

>> f([-4 -6 -2 0 -9])
ans =
    -2

>> f([-11 0 0 0 0 0 -12 10])
ans =
     0

>> f([0 20])
ans =
    20

3

Dyalog APL,14 个字节

⌈/∊2(+↑⍨0∊,)/⎕

⌈/ 最大的

扁平化(“ e列出”

2(... )/成对

+ 总和(零加某物是某物)

↑⍨ 如果采取

0

是的成员

, 对(点亮。左手数字和右手数字的串联)

在线尝试APL!


3

R,48 47字节

编辑:修复了由于@Vlo而导致的错误,并将其更改为从stdins读取输入,通过分配w和跳过括号节省了一个字节。

function(v)sort(v[c(w<-which(v==0)-1,w+1)],T)[1]

v=scan();w=which(v==0);sort(v[c(w-1,w+1)],T)[1]

不必要的解释

  1. 查找向量v为0的索引:w <- which(v == 0)
  2. 创建包含索引的新向量+-1w-1w+1
  3. 提取与索引匹配的元素,w-1然后w+1
  4. 降序排序并提取出拳头元素

请注意,如果的最后一个或第一个元素v为零,w+-1则将有效地获取向量长度之外的索引,这意味着v[length(v)+1]return NA。这通常没有问题,但是如果向量中有任何出现,则max()函数会不方便地返回NA,除非有人指定了选项na.rm=T。因此,排序和提取第一个元素比使用要短2个字节max(),例如:

max(x,na.rm=T)
sort(x,T)[1]

1
需要额外的括号,否则将无法通过max等于0的所有测试用例,例如在c(1, 4, 3, 6, 0, 10, 7, 0) c((w<-which(v==0))-1,w+1)扫描时也稍短一点sort((v<-scan())[c(w<-which(v==0)-1,w+1)],T)[1]
Vlo

@Vlo感谢您指出明显的错误+1。在建议的解决方案中,您也忘记了();)。现在更新了代码并分配了v事先的操作。
Billywob

3

Mathematica,46 43个字节

由于@MartinEnder而节省了3个字节。

Max[Tr/@Partition[#,2,1]~Select~MemberQ@0]&

匿名函数。将整数列表作为输入,并返回整数作为输出。基于Ruby解决方案。


2

Perl,42个字节

包括+1的 -p

在STDIN上在线给出数字

largest0.pl <<< "8 4 0 0 5 1 2 6 9 0 6"

largest0.pl

#!/usr/bin/perl -p
($_)=sort{$b-$a}/(?<=\b0 )\S+|\S+(?= 0)/g

2

朱莉娅56 55字节

f(l)=max(map(sum,filter(t->0 in t,zip(l,l[2:end])))...)

为相邻值创建元组,取包含0的那些元组,对元组值求和并找到最大值


1

Python 2,74字节

def f(x):x=[9]+x;print max(x[i]for i in range(len(x)) if 0in x[i-1:i+2:2])

循环遍历每个元素(如果0当前元素的左侧或右侧的位置中有一个),则将其包含在生成器中,然后遍历max。我们需要用一些非0数字填充列表。它将永远不会被包括在内,因为切片[-1:2:2]不会包含任何东西。


1

T-SQL,182字节

打高尔夫球:

DECLARE @x varchar(max)='1 5 4 3 6 1 3 17 1 -8 0 -7'

DECLARE @a INT, @b INT, @ INT WHILE @x>''SELECT @a=@b,@b=LEFT(@x,z),@x=STUFF(@x,1,z,''),@=IIF(@a=0,IIF(@b<@,@,@b),IIF(@b<>0 or @>@a,@,@a))FROM(SELECT charindex(' ',@x+' ')z)z PRINT @

取消高尔夫:

DECLARE @x varchar(max)='1 5 4 3 6 1 3 17 1 -8 0 -7'

DECLARE @a INT, @b INT, @ INT
WHILE @x>''
  SELECT 
   @a=@b,
   @b=LEFT(@x,z),
   @x=STUFF(@x,1,z,''),
   @=IIF(@a=0,IIF(@b<@,@,@b),IIF(@b<>0 or @>@a,@,@a))
  FROM(SELECT charindex(' ',@x+' ')z)z 
PRINT @

小提琴


1

PowerShell v3 +,62个字节

param($n)($n[(0..$n.count|?{0-in$n[$_-1],$n[$_+1]})]|sort)[-1]

比其他答案要长一点,但是很漂亮。

接受输入$n。然后遍历索引0..$n.count,使用Where-Object|?{...})拉出数组中上一个或下一个项所在的那些索引0,并将它们反馈到数组slice中$n[...]。然后|sort,我们将这些元素取为最大[-1]

例子

PS C:\Tools\Scripts\golfing> @(1,4,3,6,0,3,7,0),@(9,4,9,0,9,0,9,15,-2),@(-4,-6,-2,0,-9),@(-11,0,0,0,0,0,-12,10)|%{""+$_+" --> "+(.\largest-number-beside-a-zero.ps1 $_)}
1 4 3 6 0 3 7 0 --> 7
9 4 9 0 9 0 9 15 -2 --> 9
-4 -6 -2 0 -9 --> -2
-11 0 0 0 0 0 -12 10 --> 0

PS C:\Tools\Scripts\golfing> @(0,20),@(20,0),@(0,7,20),@(7,0,20),@(7,0,6,20),@(20,0,6)|%{""+$_+" --> "+(.\largest-number-beside-a-zero.ps1 $_)}
0 20 --> 20
20 0 --> 20
0 7 20 --> 7
7 0 20 --> 20
7 0 6 20 --> 7
20 0 6 --> 20

1

q,38个字节

{max x where 0 in'x,'(next x),'prev x}

当最大值在0之后出现时,这似乎不起作用。另外,我也不是专家,但是我认为您必须将代码括起来{}才能使其发挥作用。
丹尼斯

1

J,18个字节

[:>./2(0&e.\#+/\)]

说明

[:>./2(0&e.\#+/\)]  Input: array A
                 ]  Identity. Get A
     2              The constant 2
      (         )   Operate on 2 (LHS) and A (RHS)
               \    Get each subarray of size 2 from A and
             +/       Reduce it using addition
           \        Get each subarray of size 2 from A and
       0&e.           Test if 0 is a member of it
            #       Filter for the sums where 0 is contained
[:>./               Reduce using max and return

1

Perl 6、53字节

{max map ->$/ {$1 if !$0|!$2},(1,|@_,1).rotor(3=>-2)}

展开:

# bare block lambda with implicit signature of (*@_)
{
  max

    map

      -> $/ {           # pointy lambda with parameter 「$/」
                        # ( 「$0」 is the same as 「$/[0]」 )
        $1 if !$0 | !$2 # return the middle value if either of the others is false
      },

      ( 1, |@_, 1 )     # list of inputs, with added non-zero terminals
      .rotor( 3 => -2 ) # grab 3, back-up 2, repeat until less than 3 remain
}

1

PHP,66字节

foreach($a=$argv as$k=>$v)$v||$m=max($m,$a[$k-1],$a[$k+1]);echo$m;

非常简单。遍历输入,当数字为时0,它将设置$m为2个相邻数字中的最高数字任何先前的值$m

像这样运行(-d仅出于美观目的而添加):

php -d error_reporting=30709 -r 'foreach($a=$argv as$k=>$v)$v||$m=max($m,$a[$k-1],$a[$k+1]);echo$m;' -- -4 -6 -2 0 -9;echo

1

C#76 74字节

using System.Linq;i=>i.Zip(i.Skip(1),(a,b)=>a*b==0?1<<31:a+b).Max(‌​);

说明:

使用zip将数组与自身连接,但是跳过第二个引用中的第一个值,以便零项连接到第一项。将a乘以b,如果结果为零,则其中之一必须为零,并输出a + b。否则,输出该语言的最小可能整数。假设我们总是有一个零和一个非零,那么这个最小值将永远不会作为最大值输出。

用法:

[TestMethod]
public void LargestFriend()
{
    Assert.AreEqual(7, F(new int[] { 1, 4, 3, 6, 0, 3, 7, 0 }));
    Assert.AreEqual(9, F(new int[] { 9, 4, 9, 0, 9, 0, 9, 15, -2 }));
    Assert.AreEqual(-2, F(new int[] { -4, -6, -2, 0, -9 }));
    Assert.AreEqual(0, F(new int[] { -11, 0, 0, 0, 0, 0, -12, 10 }));
    Assert.AreEqual(20, F(new int[] { 0, 20 }));
}

你好 您可以在删除空格int[]i) {。另外,我在当前代码中计算了75个字节(如果删除空格,则为74个字节)。
凯文·克鲁伊森

我认为您可以通过反转三进制来节省4个字节:a?b?i.Min()).Max():a:b
Titus

另外using System.Linq;,不是吗?
pinkfloydx33 2013年

是的,但是这个问题只是问一个方法,而不是一个完整的程序,并且使用System.Linq;是默认新类模板的一部分。
Grax32 '16

@Grax无论哪种方式,您都需要using在字节数中包含该语句
TheLethalCoder

1

R,48 54字节

s=scan()

w=which;max(s[c(w(s==0)+1,w(s==0)-1)],na.rm=T)

从控制台输入读取向量,然后在与0相邻的所有值上取最大值。

编辑:捕获边界产生的NA,谢谢rturnbull!


我做错了吗?pastebin.com/0AA11xcw
manatwork's

这种失败的案件,例如20 0,由于s[w(s==0)+1]回报NAmax的默认处理NA是归还。您可以通过添加参数来修复na.rm=T,或重新编写要使用的代码sort(请参见上面发布的其他R答案)。
rturnbull

您可以将所有内容浓缩为一行吗?我不知道如何用R进行编码,但是我假设您可以。
clismique

@ Qwerp-Derp:据我所知。scan()等待控制台输入读取向量,通过输入空行关闭输入流。如果将两条线作为一条线运行,则第二部分至少会被部分识别为向量s的输入。
Headcrash

0

球拍183字节

(λ(k)(let*((lr(λ(l i)(list-ref l i)))(l(append(list 1)k(list 1)))(m(for/list((i(range 1(sub1(length l))))
#:when(or(= 0(lr l(sub1 i)))(= 0(lr l(add1 i)))))(lr l i))))(apply max m)))

详细版本:

(define f
 (λ(k)
    (let* ((lr (λ(l i)(list-ref l i)))
           (l (append (list 1) k (list 1)))
           (m (for/list ((i (range 1 (sub1(length l))))
                         #:when (or (= 0 (lr l (sub1 i)))
                                    (= 0 (lr l (add1 i))) ))
                (lr l i) )))
      (apply max m) )))

测试:

(f (list 1 4 3 6 0 3 7 0))
(f (list 9 4 9 0 9 0 9 15 -2))
(f (list -4 -6 -2 0 -9))
(f (list -11 0 0 0 0 0 -12 10))
(f (list 0 20 ))

输出:

7
9
-2
0
20

0

C 132字节

使用main的返回码输出:

int main(int a,char**_){int i,m=0;_[0]=_[a]="1";for(i=1;i<a;++i){m=(*_[i-1]-48||*_[i+1]-48?m>atoi(_[i])?m:atoi(_[i]):m);}return m;}

我觉得我应该能够通过保存一个atoi调用来节省一些字节,但是我找不到有效的方法。(,tt=号加上加,t两次太长)。同样,从技术上讲,它使用未定义的行为(将_ [a]设置为“ 1”),但是我所知道的每个编译器默认都允许它。

策略:用1填充数组的开始和结尾,然后遍历内部部分以检查每个邻居。


0

PHP 69 64字节

JörgHülsermann和Titus的一些字节断断续续。=(-5)

需要启用register_globals。用法:http://localhost/notnull.php?i[]=9&i[]=-5i[]=...

$x=$_GET['i'];
$y=0;
foreach($x as $j){
if($y<abs($j)){
$y=$j;
}
}
echo $y;

打高尔夫球:

$x=$_GET['i'];$y=0;foreach($x as $j)if($y<abs($j))$y=$j;echo $y;

为什么不直接将输入用作数组。我看不到json_encode的原因。
约尔格Hülsermann

对于非默认设置,您必须将设置更改的全长添加到字节数中。(请参阅meta.codegolf.stackexchange.com/q/4778#4778)在这种情况下,需要+21个字节-d register_globals=1(或指定默认情况下启用register_globals的版本)
Titus

但这json_decode是一个好主意。
泰特斯(Titus)2016年

@Titus我的意思是?id[]=1&id[]=2&id[]=3 然后$_GET["id"]返回一个数组。为此json_decode是没有意义的,我
约尔格Hülsermann

@JörgHülsermann它花费字节,但是还是个好主意。
泰特斯(Titus)2016年
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.