Trova il numero più grande adiacente a uno zero


38

Sfida:

Prendi un vettore / elenco di numeri interi come input e genera il numero più grande adiacente a zero.

specifiche tecniche:

  • Come sempre, formato di input e output opzionale
  • Si può presumere che ci sarà almeno uno zero e almeno un elemento diverso da zero.

Casi test:

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

Buona fortuna e buon golf!


È necessario aggiungere un caso di test come il quarto, ma in cui il risultato è negativo (ci sono numeri positivi nell'elenco).
mbomb007,

Stavo per provare questo a Retina, ma poi ho notato che ci sono aspetti negativi. La retina odia i negativi.
mbomb007,

2
Non lasciare che la retina imponga ciò che puoi e non puoi fare. Prendi il comando, sei il capo!
Stewie Griffin,

Risposte:



19

MATL , 10 byte

t~5BZ+g)X>

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

Prendiamo l'input [-4 -6 -2 0 -9]come esempio.

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)). Chi ha avuto l'idea di implementarlo? Molto intelligente e utile per array logici! :) Bella risposta!
Stewie Griffin,

1
@WeeingIfFirst Grazie! Avevo usato dec2bin()-'0'centinaia di volte in MATLAB, quindi sapevo che uno doveva essere in MATL :-)
Luis Mendo,

5
A proposito, il fatto di aver incluso il contenuto dello stack dopo ogni operazione merita solo un voto. Rende molto più facile capire (e possibilmente imparare) MATL =)
Stewie Griffin,

2
Rocce di convoluzione. +1
Suever,

10

05AB1E , 9 byte

ü‚D€P_ÏOZ

Spiegazione

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

Non funziona nell'interprete online, ma funziona offline.


Questo è incredibile haha! Giusto in tempo: p.
Adnan,

1
Hai appena implementato uno di questi operatori o? :)
Stewie Griffin,

1
@WeeingIfFirst: è üstato aggiunto proprio ieri :)
Emigna,

2
Questo ritorno non 0sarebbe se la risposta effettiva fosse negativa? Devi buttare via gli zero, credo.
Lynn,

1
@Lynn Nice catch! Questo può essere facilmente risolto sostituendo ˜con O(somma).
Adnan,

9

Haskell, 63 43 byte

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

Grazie a @MartinEnder per 4 byte!


Penso che puoi usare al a*b==0posto di ||.
Martin Ender,

Devi tornare alla versione precedente con zip. Qui a ed essere non sono più adiacenti
Damien,

Non hai bisogno di lambdabot qui. Questo è "normale" Haskell
Damien il

8

Pyth, 12 11 10 byte

eSsM/#0,Vt

Coppie di moduli, filtri per zero membri, ordinamenti per somma, restituisce il valore maggiore.


,Vt(implicito QQ) restituisce le stesse coppie di .:Q2, ma con le coppie capovolte. Dovrebbe funzionare, però.
PurkkaKoodari,

f}0Tè/#0
isaacg,

7

JavaScript (ES6), 59 57 56 byte

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

Modifica: salvato 2 byte grazie a Huntro
Edit: salvato 1 byte grazie a ETHproductions


1
Puoi salvare due byte usando ==invece di===
Huntro

1
Se riesci a salvare qualche byte in più punti:l=>l.map((n,i)=>m=l[i-1]*l[i+1]==0&n>m?n:m,m=-1/0)|m
ETHproductions

Errore: {"message": "Errore di sintassi", "nomefile": " stacksnippets.net/js ", "lineno": 15, "colno": 3}
RosLuP,

@RosLuP - Ciò richiede ES6 con il supporto della funzione freccia e non funzionerà su tutti i browser (inclusi, ma non limitati a: tutte le versioni IE precedenti a Edge, tutte le versioni Safari inferiori alla v10, ecc.)
Arnauld

6

JavaScript (ES6), 53 byte

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

Perché mi piace usare reduce. Soluzione alternativa, anche 53 byte:

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

5

Python, 49 byte

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

I test sono a ideone

Comprime le coppie, somma quelle contenenti qualsiasi zero, restituisce il massimo.


4

Rubino, 51 byte

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

Non penso che ti servano le parentesi a+b.
Martin Ender,

Si verifica l'errore di sintassi di @Martin Ender ... ideone.com/F6Ed4B
cia_rana

Funziona in Ruby 2.3. (disponibile qui per esempio: repl.it/languages/ruby )
Martin Ender,

@Martin Ender Quando uso "! =" Invece di "==", funziona. Grazie per il tuo consiglio! ideone.com/F6Ed4B
cia_rana,

C'è un bug qui dentro :(. -3 -2 0Restituisce 0. Penso che sostituirlo ...?0:...con ...?-1.0/0:...dovrebbe risolverlo, aggiungendo 5 byte.
m-chrzan,

4

PHP, 77 68 71 byte

-3 byte da anonimo, -4 e -2 da MartinEnder

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

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


2
usare \Kper scartare la partita finora è più breve che usare un look-behind.
user59178

2
È inoltre possibile utilizzare la separazione dello spazio per l'input e quindi utilizzare \S+per abbinare un numero intero con segno. Probabilmente dovrai usarlo, \b0,quindi non devi anteporre a ,.
Martin Ender,

1
Funziona come input 4 0 0 5?
Ton Hospel,

@TonHospel No. Non \Kfunziona con le alternative? Per motivi sconosciuti, la seconda alternativa ritorna 0 0, in modo che non ci sia più nulla 0da abbinare prima del 5. Risolto, grazie.
Tito,

Dai

4

Java 7, 118 105 106 byte

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 byte salvati grazie a @cliffroot usando invece un approccio aritmetico. 1 byte aggiuntivo grazie a @mrco dopo aver scoperto un bug (il caso test aggiunto 2, 1, 0avrebbe restituito 2invece di1 ).

Codice non testato e test:

Provalo qui.

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

Produzione:

7
9
-2
0
20
1

1
approccio leggermente diverso usando l'aritmetica, sembra funzionareint 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
L'output è errato, quando il primo numero non è adiacente a 0, ma maggiore di qualsiasi numero adiacente a 0. Riproducibile dal caso di test {2, 1, 0}. È possibile risolvere questo problema inizializzando i con 0 direttamente e m con 1 << 31 (+1 in totale).
mrco,

3

CJam , 16 byte

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

Provalo online!(Come una suite di test.)

Spiegazione

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 con Image Processing Toolbox, 32 byte

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

Questa è una funzione anonima. Esempio di utilizzo per i casi di test:

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

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

⌈/ il più grande di

l'appiattito (" e nlisted"

2(... a )/coppie

+ somma (zero più qualcosa è qualcosa)

↑⍨ preso se

0 zero

è membro di

, la coppia (lett. la concatenazione del numero della mano sinistra e del numero della mano destra)

ProvaAPL online!


3

R, 48 47 byte

EDIT: risolto un errore grazie a @Vlo e modificato per leggere l'input da stdins, salvato un byte assegnando we saltando le parentesi.

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]

Spiegazione non annidata

  1. Trova indici per i quali il vettore vassume i valori 0:w <- which(v == 0)
  2. Crea un nuovo vettore che contiene gli indici +-1:w-1 ew+1
  3. Estrai elementi che corrispondono agli indici w-1ew+1
  4. Ordinare in ordine decrescente ed estrarre l'elemento pugno

Si noti che se l'ultimo o il primo elemento di vè uno zero, w+-1verrà effettivamente recuperato un indice al di fuori della lunghezza del vettore che implica che v[length(v)+1]ritorni NA. Questo in genere non è un problema, ma le max()funzioni ritornano inavvertitamente NAse ci sono delle occorrenze nel vettore a meno che non si specifichi l'opzione na.rm=T. Quindi è più breve di 2 byte ordinare ed estrarre il primo elemento piuttosto che usarlo max(), ad esempio:

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

1
Hai bisogno di una parentesi aggiuntiva, altrimenti falliscono tutti i casi di test in cui max è a destra di 0, come c(1, 4, 3, 6, 0, 10, 7, 0) c((w<-which(v==0))-1,w+1)anche un po 'più breve con la scansionesort((v<-scan())[c(w<-which(v==0)-1,w+1)],T)[1]
Vlo,

@Vlo Grazie per aver segnalato quell'ovvio errore, +1. Nella soluzione suggerita, però, hai dimenticato ()anche tu ;). Aggiornato il codice e assegnato la vmanipolazione precedente ora.
Billywob,

3

Mathematica, 46 43 byte

Salvato 3 byte grazie a @MartinEnder .

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

Funzione anonima. Prende un elenco di numeri interi come input e restituisce un numero intero come output. Basato sulla soluzione Ruby.


2

Perl, 42 bytes

Includes +1 for -p

Give the numbers on line on 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])))...)

Create tuples for neighboring values, take those tuples containing 0, sum tuple values and find maximum


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

Cycle through every element, if there's a 0 in the position of either the left or the right of the current element, include it in the generator, and then run it through max. We need to pad the list with some non-0 number. It'll never be included because the slice [-1:2:2] won't include anything.


1

T-SQL, 182 bytes

Golfed:

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 @

Fiddle


1

PowerShell v3+, 62 bytes

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

A bit longer than the other answers, but a nifty approach.

Takes input $n. Then loops through the indices 0..$n.count, uses the Where-Object (|?{...}) to pull out those indices where the previous or next item in the array is 0, and feeds those back into array slice $n[...]. We then |sort those elements, and take the biggest [-1].

Examples

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}

This doesn't seem to work when the maximum comes after a 0. Also, I'm no q expert, but I think you would have to surround your code with {} to make it a function.
Dennis

1

J, 18 bytes

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

Explanation

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

Expanded:

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

Pretty straightforward. Iterates over the input, and when a number is 0, it sets $m to the highest number of the 2 adjacent numbers and any previous value of $m.

Run like this (-d added for aesthetics only):

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(‌​);

Explanation:

Use zip to join the array with itself but skipping the first value in the 2nd reference so that item zero joins to item one. Multiply a times b, if the result is zero, one of them must be zero and output a + b. Otherwise, output the minimum possible integer in the language. Given the assumption that we will always have a zero and a non-zero, this minimum value will never be output as the max.

Usage:

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

Hi. you can remove the space at int[]i) {. Also, I count 75 bytes in your current code (74 if you remove the space).
Kevin Cruijssen

I think you can save 4 bytes by inverting the ternaries: a?b?i.Min()).Max():a:b
Titus

Plus using System.Linq;, no?
pinkfloydx33

True but this question just asked for a method, not a full program and using System.Linq; is part of the default new class template.
Grax32

@Grax Either way you need to include the using statement in your byte count
TheLethalCoder

1

R, 48 54 bytes

s=scan()

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

Reads vector from console input, then takes the maximum over all values adjacent to 0.

Edit: Catches NAs produced at the boundary, thanks rturnbull!


Am I doing it wrong? pastebin.com/0AA11xcw
manatwork

This fails for cases such as 20 0, because s[w(s==0)+1] returns NA, and max's default treatment of NA is to return it. You can fix by adding the argument na.rm=T, or re-work the code to use sort (see the other R answer posted above).
rturnbull

Can you condense everything into one line? I don't know how to code in R, but I'm assuming you can.
clismique

@Qwerp-Derp: Not as far as I know. scan() waits for console input to read in the vector, the input stream is closed by entering an empty line. If you were to run the two lines as one, the second part would be at least partially recognized to be input for to the vector s.
Headcrash

0

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

Detailed version:

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

Testing:

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

Output:

7
9
-2
0
20

0

C 132 bytes

Outputs using main's return code:

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

I feel like I should be able to save a few bytes by saving one of the atoi calls, but I couldn't find an efficient way. (,t plus t= plus , plus t twice is too long). Also this technically uses undefined behaviour (setting _[a] to "1") but every compiler I know of allows it by default.

Strategy: pad the start and end of the array with 1, then loop over the internal section checking each neighbor.


0

PHP 69 64 bytes

Some bytes on and off from Jörg Hülsermann and Titus. = (-5)

Requires register_globals enabled. Usage: 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;

Golfed:

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

Why do not use directly the input as array. I could not seen the reason for json_encode.
Jörg Hülsermann

For non-default settings you have to add the full length of the setting change to your byte count. (see meta.codegolf.stackexchange.com/q/4778#4778) In this case +21 bytes for -d register_globals=1 (or specify a version where register_globals is enabled by default)
Titus

But json_decode is a nice idea.
Titus

@Titus What I mean is ?id[]=1&id[]=2&id[]=3 and then $_GET["id"] gives back an array. For this reason json_decode makes no sense for me
Jörg Hülsermann

@JörgHülsermann It costs bytes, but it´s still a nice idea.
Titus
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.