Найдите наибольшее число, соседнее с нулем


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

Я собирался попробовать это в Retina, но потом я заметил, что есть негативы. Сетчатка ненавидит негативы.
mbomb007

2
Не позволяйте сетчатке диктовать, что вы можете и не можете делать. Возьми на себя ответственность, ты босс!
Стьюи Гриффин

Ответы:



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)), Кто задумал реализовать это? Очень умный и полезный для логических массивов! :) Хороший ответ!
Стьюи Гриффин

1
@WeeingIfFirst Спасибо! Я использовал dec2bin()-'0'сотни раз в MATLAB, так что я знал, что нужно быть в MATL :-)
Луис Мендо

5
Кстати, тот факт, что вы включили содержимое стека после каждой операции, заслуживает отдельного одобрения. Это облегчает понимание (и, возможно, изучение) MATL =)
Стьюи Гриффин

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

Не работает в онлайн-переводчике, но работает в автономном режиме.


Это удивительно, ха-ха! Как раз вовремя: с.
Аднан

1
Только что реализовал один из этих операторов или? :)
Стьюи Гриффин

1
@WeeingIfFirst: üбыл добавлен только вчера :)
Emigna

2
Не вернется 0ли это, если фактический ответ будет отрицательным? Вы должны выбросить нули, я думаю.
Линн

1
@ Линн Хороший улов! Это может быть легко исправлена путем замены ˜с O(суммы).
Аднан

9

Haskell, 63 43 байта

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

Спасибо @MartinEnder за 4 байта!


Я думаю, что вы можете использовать a*b==0вместо ||.
Мартин Эндер

Вы должны вернуться к предыдущей версии с zip. Здесь a и be больше не примыкают
Damien

Тебе не нужен ламбдабот здесь. Это «обычный» Haskell
Дэмиен

8

Пиф, 12 11 10 байт

eSsM/#0,Vt

Формирует пары, фильтрует по нулевому элементу, сортирует по сумме, возвращает наибольшее.


,Vt(неявный 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

Редактировать: 2 байта благодаря Huntro
Редактировать: 1 байт благодаря ETHproductions


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

Ошибка: {"message": "Синтаксическая ошибка", "имя файла": " stacksnippets.net/js ", "lineno": 15, "colno": 3}
RosLuP

@RosLuP - это требует ES6 с поддержкой функции стрелки и не будет работать во всех браузерах (включая, но не ограничиваясь: все версии IE до Edge, все версии Safari ниже v10 и т. Д.)
Арнаулд

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)

Тесты в идеоне

Пролистывает пары, суммирует те, которые содержат любой ноль, возвращает максимум.


4

Рубин, 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 syntax error occurs... ideone.com/F6Ed4B
cia_rana

It works in Ruby 2.3. (available here for instance: repl.it/languages/ruby)
Martin Ender

@Martin Ender When I use "!=" instead of "==", it works. Thanks for your advice! ideone.com/F6Ed4B
cia_rana

There's a bug in there :(. -3 -2 0 returns 0. I think replacing ...?0:... with ...?-1.0/0:... should fix it, adding 5 bytes.
m-chrzan

4

PHP, 77 68 71 bytes

-3 bytes from anonymous, -4 and -2 from MartinEnder

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

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


2
using \K to discard the match so far is shorter than using a look-behind.
user59178

2
You can also use space separation for input and then use \S+ to match a signed integer. You'll probably have to use \b0, so you don't have to prepend the ,.
Martin Ender

1
Does this work for input like 4 0 0 5 ?
Ton Hospel

@TonHospel No. Does \K not work with alternatives? For unknown reason, the second alternative returns 0 0, so that there is no more 0 to match before the 5. Fixed, thanks.
Titus

Make a look at the other PHP solution with register_globals
Jörg Hülsermann

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 saved thanks to @cliffroot by using an arithmetic approach instead. 1 additional byte thank to @mrco after he discovered a bug (the added test case 2, 1, 0 would return 2 instead of 1).

Ungolfed & тестовый код:

Попробуй это здесь.

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

3
Вывод неправильный, когда первое число не смежно с 0, но больше, чем любое число, смежное с 0. Воспроизводится тестовым примером {2, 1, 0}. Вы можете исправить это, непосредственно инициализируя i значением 0, а m значением 1 << 31 (+1 в целом).
mrco


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∊,)/⎕

⌈/ самый большой из

уплощенный ( « е nlisted»

2(... )/попарно

+ сумма (ноль плюс что-то есть)

↑⍨ принято, если

0 нуль

является членом

, пара (освещенная конкатенация левого номера и правого номера)

Попробуй APL онлайн!


3

Р, 48 47 байт

РЕДАКТИРОВАТЬ: Исправлена ​​ошибка благодаря @Vlo и изменил его для чтения ввода из stdins, сохранил один байт, назначая wи пропуская parantheses.

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. Создайте новый вектор, который содержит индексы +-1: w-1иw+1
  3. Извлечь элементы, которые соответствуют индексам w-1иw+1
  4. Сортировать по убыванию и извлечь элемент кулак

Обратите внимание, что если последний или первый элемент vравен нулю, w+-1будет эффективно извлекать индекс за пределами длины вектора, что подразумевает, что v[length(v)+1]возвращает NA. Обычно это не проблема, но max()функция возвращает неудобство, NAесли в векторе есть вхождения, если не указан параметр na.rm=T. Таким образом, сортировка и извлечение первого элемента на 2 байта короче, чем использование max(), например:

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

1
Нужна дополнительная скобка, в противном случае все тестовые случаи не 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 Спасибо за указание на очевидную ошибку, +1. В предложенном вами решении вы ()тоже забыли ;). Обновил код и назначил vпредыдущие манипуляции сейчас.
Billywob

3

Mathematica, 46 43 байта

Сохранено 3 байта благодаря @MartinEnder .

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

Анонимная функция. Принимает список целых чисел в качестве входных данных и возвращает целое число в качестве выходных данных. Основано на решении 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])

Переберите каждый элемент, если он находится 0слева или справа от текущего элемента, включите его в генератор и затем выполните его max. Нам нужно дополнить список некоторыми 0номерами. Он никогда не будет включен, потому что срез [-1:2:2]не будет ничего включать.


1

T-SQL, 182 байта

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 @

скрипка


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, и возвращает их обратно в срез массива $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 . Кроме того, я не эксперт по q, но я думаю, что вам придется окружить свой код, {}чтобы сделать его функцией.
Деннис

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

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 байт

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, чтобы объединить массив с самим собой, но пропустив первое значение во 2-й ссылке, чтобы нулевой элемент присоединился к первому элементу. Умножьте 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
Тит

Плюс using System.Linq;нет?
pinkfloydx33

Верно, но этот вопрос только что задан для метода, а не для полной программы, и использование System.Linq;является частью нового шаблона класса по умолчанию.
Grax32,

@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

Это терпит неудачу для случаев, таких как 20 0, потому что s[w(s==0)+1]возвращает NA, и maxобработка по умолчанию 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 байта

Вывод с использованием основного кода возврата:

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, но я не смог найти эффективный способ. ( ,tплюс t=плюс ,плюс tвдвое длиннее). Также это технически использует неопределенное поведение (установка _ [a] в «1»), но каждый известный мне компилятор разрешает его по умолчанию.

Стратегия: заполните начало и конец массива 1, затем зациклите внутренний раздел, проверяя каждого соседа.


0

PHP 69 64 байта

Некоторые байты включаются и выключаются у Йорга Хюльсермана и Тита. знак равно(-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;

Golfed:

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

Почему бы не использовать вход непосредственно как массив. Я не мог видеть причину json_encode.
Йорг Хюльсерманн

Для нестандартных настроек вы должны добавить полную длину изменения настроек к вашему счету байтов. (см. meta.codegolf.stackexchange.com/q/4778#4778 ). В этом случае +21 байт -d register_globals=1(или укажите версию, в которой register_globals включена по умолчанию)
Тит

Но json_decodeэто хорошая идея.
Тит

@Titus Что я имею в виду, ?id[]=1&id[]=2&id[]=3 а затем $_GET["id"]возвращает массив. По этой причине json_decode не имеет смысла для меня
Йорг Хюльсерманн

@ JörgHülsermann Это стоит байтов, но это все еще хорошая идея.
Тит
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.