Encontre o maior número adjacente a um zero


38

Desafio:

Pegue um vetor / lista de números inteiros como entrada e produza o maior número adjacente a um zero.

Especificações:

  • Como sempre, formato opcional de entrada e saída
  • Você pode supor que haverá pelo menos um zero e pelo menos um elemento diferente de zero.

Casos de teste:

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

Boa sorte e feliz golfe!


Você deve adicionar um caso de teste como o quarto, mas onde o resultado é negativo (há números positivos na lista).
mbomb007

Eu ia tentar isso na Retina, mas então notei que há negativos. Retina odeia negativos.
mbomb007

2
Não deixe a retina ditar o que você pode ou não fazer. Assuma o controle, você é o chefe!
Stewie Griffin

Respostas:



19

MATL , 10 bytes

t~5BZ+g)X>

Experimente online! Ou verifique todos os casos de teste .

Explicação

Vamos dar [-4 -6 -2 0 -9]um exemplo como exemplo.

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)). Quem foi a ideia de implementar essa? Muito inteligente e útil para matrizes lógicas! :) Boa resposta!
Stewie Griffin

1
@WeeingIfFirst Thanks! Eu tinha usado dec2bin()-'0'centenas de vezes em MATLAB, então eu sabia que era preciso estar em MATL :-)
Luis Mendo

5
A propósito, o fato de você ter incluído o conteúdo da pilha após cada operação vale apenas um voto positivo. Isso torna muito mais fácil de entender (e possivelmente aprender) MATL =)
Stewie Griffin

2
Rochas de convolução. +1
Suever

10

05AB1E , 9 bytes

ü‚D€P_ÏOZ

Explicação

ü‚         # 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

Não funciona no intérprete online, mas funciona offline.


Isso é incrível haha! Bem a tempo: p.
Adnan

1
Apenas implementou um desses operadores ou? :)
Stewie Griffin

1
@WeeingIfFirst: üfoi adicionado ontem :)
Emigna

2
Isso não retornará 0se a resposta real for negativa? Você tem que jogar fora os zeros, eu acho.
Lynn

1
@ Catch Lynn Nice! Isso pode ser facilmente corrigido substituindo-o ˜por O(soma).
Adnan

9

Haskell, 63 43 bytes

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

Obrigado a @MartinEnder por 4 bytes!


Eu acho que você pode usar em a*b==0vez do ||.
Martin Ender

Você precisa voltar à versão anterior com zip. Aqui um e ser não são adjacentes
Damien

Você não precisa de lambdabot aqui. Isso é "regular" Haskell
Damien

8

Pitão, 12 11 10 bytes

eSsM/#0,Vt

Pares de formulários, filtros por zero membro, classificados por soma, retornam maiores.


,Vt(implícito QQ) retorna os mesmos pares que .:Q2, mas com os pares invertidos. Deve funcionar, no entanto.
PurkkaKoodari

f}0Té/#0
isaacg 21/09

7

JavaScript (ES6), 59 57 56 bytes

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

Edit: economizou 2 bytes graças ao Huntro
Edit: economizou 1 byte graças ao ETHproductions


1
Você pode salvar dois bytes usando em ==vez de===
Huntro

1
Você pode salvar alguns bytes em vários locais:l=>l.map((n,i)=>m=l[i-1]*l[i+1]==0&n>m?n:m,m=-1/0)|m
ETHproductions

Erro: {"message": "Erro de sintaxe", "filename": " stacksnippets.net/js ", "lineno": 15, "colno": 3}
RosLuP

@RosLuP - Isso requer ES6 com suporte função de seta e não funcionará em todos os navegadores (incluindo, mas não limitados a: todas as versões ou seja, antes de Borda, todas as versões do Safari abaixo v10, etc.)
Arnauld

6

JavaScript (ES6), 53 bytes

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

Porque eu gosto de usar reduce. Solução alternativa, também 53 bytes:

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

5

Python, 49 bytes

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

Os testes estão no ideone

Atravessa os pares, soma os que contêm zero, retorna o máximo.


4

Ruby, 51 bytes

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

uso

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

Eu não acho que você precise dos parênteses a+b.
Martin Ender

@Martin Ender erro de sintaxe ocorre ... ideone.com/F6Ed4B
cia_rana

Funciona no Ruby 2.3. (disponível aqui por exemplo: repl.it/languages/ruby )
Martin Ender

@ Martin Ender Quando eu uso "! =" Em vez de "==", ele funciona. Obrigado pelo teu conselho! ideone.com/F6Ed4B
cia_rana

Há um bug lá :(. -3 -2 0Retornos 0Eu acho que a substituição. ...?0:...Com ...?-1.0/0:...deve corrigi-lo, adicionando 5 bytes.
m-Chrzan

4

PHP, 77 68 71 bytes

-3 bytes de anônimo, -4 e -2 de MartinEnder

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

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


2
usar \Kpara descartar a partida até agora é mais curto do que usar um look-behind.
user59178

2
Você também pode usar a separação de espaço para entrada e, em seguida, usar \S+para corresponder a um número inteiro assinado. Você provavelmente precisará usar \b0,para não preceder o ,.
Martin Ender

1
Isso funciona como entrada 4 0 0 5?
Ton Hospel 21/09/16

@TonHospel Não. Não \Kfunciona com alternativas? Por motivo desconhecido, a segunda alternativa retorna 0 0, para que não haja mais 0correspondência antes da 5. Corrigido, obrigado.
Titus


4

Java 7, 118 105 106 bytes

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

13 bytes salvos graças ao @cliffroot usando uma abordagem aritmética. 1 byte adicional, graças a @mrco depois que ele descobriu um bug (o caso de teste adicionado 2, 1, 0retornaria em 2vez de 1).

Ungolfed & código de teste:

Experimente aqui.

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

Saída:

7
9
-2
0
20
1

1
ligeiramente abordagem utilizando diferentes aritmética, parece estar funcionandoint 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;}
cliffroot

3
A saída está incorreta quando o primeiro número não é adjacente a 0, mas é maior que qualquer número adjacente a 0. Reproduzível pelo caso de teste {2, 1, 0}. Você pode corrigir isso inicializando i com 0 diretamente e m com 1 << 31 (+1 no total).
Mrco 23/09/16

3

CJam , 16 bytes

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

Experimente online!(Como uma suíte de teste.)

Explicação

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 com Image Processing Toolbox, 32 bytes

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

Esta é uma função anônima. Exemplo de uso para os casos de teste:

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

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

⌈/ maior de

o achatada ( " e nlisted"

2(... em )/pares

+ soma (zero mais algo é alguma coisa)

↑⍨ tomado se

0 zero

é um membro de

, o par (lit. a concatenação do número da esquerda e do número da direita)

TryAPL online!


3

R, 48 47 bytes

EDIT: Corrigido um erro graças ao @Vlo e alterado para ler a entrada de stdins, economizando um byte atribuindo we pulando parênteses.

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]

Explicação não aninhada

  1. Encontre índices para os quais o vetor vassume os valores 0:w <- which(v == 0)
  2. Crie um novo vetor que contenha os índices +-1: w-1ew+1
  3. Extrair elementos que correspondam aos índices w-1ew+1
  4. Classificar em ordem decrescente e extrair o primeiro elemento

Observe que, se o último ou o primeiro elemento de vfor um zero, w+-1buscará efetivamente um índice fora do comprimento do vetor, o que implica em v[length(v)+1]retornos NA. Isso geralmente não é problema, mas as max()funções retornam inconvenientemente NAse houver alguma ocorrência no vetor, a menos que alguém especifique a opção na.rm=T. Portanto, é 2 bytes mais curto para classificar e extrair o primeiro elemento do que para usar max(), por exemplo:

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

1
Precisa de um parêntese adicional de outra forma falhar todos os casos de teste, onde Max está para a direita de 0, como c(1, 4, 3, 6, 0, 10, 7, 0) c((w<-which(v==0))-1,w+1)também um pouco mordeu mais curto com varredurasort((v<-scan())[c(w<-which(v==0)-1,w+1)],T)[1]
Vlo

Obrigado por apontar esse erro óbvio, +1. Na sua solução sugerida, você esqueceu ()também;). Atualizado o código e a vmanipulação anterior atribuída agora.
Billywob

3

Mathematica, 46 43 bytes

Salvo 3 bytes devido a @MartinEnder .

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

Função anônima. Pega uma lista de números inteiros como entrada e retorna um número inteiro como saída. Baseado na solução Ruby.


2

Perl, 42 bytes

Inclui +1 para -p

Dê os números on-line em 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

Julia, 56 55 Bytes

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

Crie tuplas para valores vizinhos, pegue aquelas que contenham 0, some valores de tuplas e encontre o máximo


1

Python 2, 74 bytes

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

Passe por cada elemento, se houver um 0na posição esquerda ou direita do elemento atual, inclua-o no gerador e execute-o max. Precisamos preencher a lista com algum 0número não . Ele nunca será incluído porque a fatia [-1:2:2]não incluirá nada.


1

T-SQL, 182 bytes

Golfe:

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 @

Ungolfed:

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 @

Violino


1

PowerShell v3 +, 62 bytes

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

Um pouco mais do que as outras respostas, mas uma abordagem bacana.

Recebe entrada $n. Em seguida, percorre os índices 0..$n.count, usa o Where-Object( |?{...}) para extrair os índices onde o item anterior ou o próximo na matriz está 0e os alimenta novamente na fatia da matriz $n[...]. Nós então |sortesses elementos, e tomamos o maior[-1] .

Exemplos

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 bytes

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

Isso não parece funcionar quando o máximo vem após um 0 . Além disso, eu não sou especialista em q, mas acho que você precisaria cercar seu código {}para torná-lo uma função.
Dennis

1

J, 18 bytes

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

Explicação

[:>./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 bytes

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

Expandido:

# 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 bytes

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

Bem direto. Repete a entrada e, quando um número é 0, ele define $mo número mais alto dos 2 números adjacentes e qualquer valor anterior de $m.

Execute assim ( -dadicionado apenas para estética):

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 bytes

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

Explicação:

Use zip para associar a matriz a ela mesma, mas ignorando o primeiro valor na 2ª referência, para que o item zero se junte ao item um. Multiplique a vezes b, se o resultado for zero, um deles deve ser zero e gerar a + b. Caso contrário, imprima o número inteiro mínimo possível no idioma. Dada a suposição de que sempre teremos um zero e um diferente de zero, esse valor mínimo nunca será gerado como o máximo.

Uso:

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

Oi. você pode remover o espaço em int[]i) {. Além disso, conto 75 bytes no seu código atual (74 se você remover o espaço).
Kevin Cruijssen

Eu acho que você pode salvar 4 bytes invertendo os ternários:a?b?i.Min()).Max():a:b
Titus

Além disso using System.Linq;, não?
pinkfloydx33

Verdadeiro, mas esta pergunta apenas solicitou um método, não um programa completo e o uso System.Linq;faz parte do novo modelo de classe padrão.
Grax32 22/09

@Grax De qualquer maneira, você precisa incluir a usingdeclaração em sua contagem de bytes
TheLethalCoder

1

R, 48 54 bytes

s=scan()

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

Lê o vetor da entrada do console e assume o máximo de todos os valores adjacentes a 0.

Edit: Pega NAs produzidos na fronteira, graças rturnbull!


Estou fazendo errado? pastebin.com/0AA11xcw
manatwork

Isso falha em casos como 20 0, porque s[w(s==0)+1]retorna NAe maxo tratamento padrão de NAé devolvê-lo. Você pode corrigir adicionando o argumento na.rm=Tou refazer o código a ser usado sort(consulte a outra resposta R postada acima).
precisa saber é o seguinte

Você pode condensar tudo em uma linha? Não sei como codificar em R, mas presumo que você possa.
Clismique

@ Qwerp-Derp: Não tanto quanto eu sei. scan () aguarda a entrada do console para ler o vetor, o fluxo de entrada é fechado digitando uma linha vazia. Se você executasse as duas linhas como uma, a segunda parte seria pelo menos parcialmente reconhecida como entrada para os vetores s.
Headcrash 25/09/16

0

Raquete 183 bytes

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

Versão detalhada:

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

Teste:

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

Saída:

7
9
-2
0
20

0

C 132 bytes

Saídas usando o código de retorno principal:

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

Sinto que deveria conseguir salvar alguns bytes salvando uma das chamadas atoi, mas não consegui encontrar uma maneira eficiente. ( ,tmais t=mais ,mais tduas vezes é muito longo). Também isso tecnicamente usa um comportamento indefinido (definindo _ [a] como "1"), mas todo compilador que conheço o permite por padrão.

Estratégia: preencha o início e o fim do array com 1 e, em seguida, passe pela seção interna verificando cada vizinho.


0

PHP 69 64 bytes

Alguns bytes ligados e desligados de Jörg Hülsermann e Titus. =(-5)

Requer register_globals ativado. Uso: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;

Golfe:

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

Por que não usar diretamente a entrada como matriz. Não pude ver o motivo do json_encode.
Jörg Hülsermann

Para configurações não padrão, você deve adicionar o comprimento total da alteração à sua contagem de bytes. (consulte meta.codegolf.stackexchange.com/q/4778#4778 ) Nesse caso, +21 bytes para -d register_globals=1(ou especifique uma versão em que register_globals está ativado por padrão)
Titus

Mas json_decodeé uma boa ideia.
Titus

@ Titus O que quero dizer é ?id[]=1&id[]=2&id[]=3 e, em seguida, $_GET["id"]devolve uma matriz. Por esta razão json_decode não faz sentido para mim
Jörg Hülsermann

@ JörgHülsermann Custa bytes, mas ainda é uma boa idéia.
Titus
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.