Держите ненулевые и их соседей

26

Взято из этого вопроса в Stack Overflow. Спасибо также @miles и @Dada за то, что они предложили тестовые материалы, которые касаются некоторых ключевых случаев.

Соревнование

Учитывая массив целочисленных значений, удалите все нули, которые не окружены некоторым ненулевым значением.

Эквивалентно, запись должна сохраняться либо в том случае, если она ненулевая, либо если это ноль, который непосредственно близок к ненулевому значению.

Сохраняемые записи должны сохранять в выходных данных порядок, в котором они находились.

пример

Данный

[2 0 4 -3 0 0 0 3 0 0 2 0 0]

значения, которые должны быть удалены, помечены x:

[2 0 4 -3 0 x 0 3 0 0 2 0 x]

и поэтому вывод должен быть

[2 0 4 -3 0 0 3 0 0 2 0]

правила

Входной массив может быть пустым (и тогда вывод тоже должен быть пустым).

Форматы ввода и вывода, как обычно, гибкие: массив, список, строка или все, что разумно.

Код гольф, наименьшее количество лучших.

Контрольные примеры

[2 0 4 -3 0 0 0 3 0 0 2 0 0] -> [2 0 4 -3 0 0 3 0 0 2 0]
[] -> []
[1] -> [1]
[4 3 8 5 -6] -> [4 3 8 5 -6]
[4 3 8 0 5 -6] -> [4 3 8 0 5 -6]
[0] -> []
[0 0] -> []
[0 0 0 0] -> []
[0 0 0 8 0 1 0 0] -> [0 8 0 1 0]
[-5 0 5] -> [-5 0 5]
[50 0] -> [50 0]
Луис Мендо
источник
Могу ли я использовать _2вместо -2? Многие языки используют этот формат.
Утренняя монахиня
Будем ли мы иметь -0?
Утренняя монахиня
@LeakyNun 1 Да 2 Нет
Луис Мендо
Будут ли когда-нибудь числа иметь лидирующие нули? Как [010 0 0 01 1]?
FryAmTheEggman
@FryAmTheEggman Нету
Луис Мендо

Ответы:

16

JavaScript (ES6), 35 байт

a=>a.filter((e,i)=>e|a[i-1]|a[i+1])

Работает на поплавках тоже для двух дополнительных байтов.

Нил
источник
10

Python, 50 байт

f=lambda l,*p:l and l[:any(l[:2]+p)]+f(l[1:],l[0])

Рекурсивная функция, которая принимает кортеж. Включает первый элемент, если среди первых двух элементов или предыдущего значения, сохраненного в прошлый раз, имеется ненулевое значение. Затем удаляет первый элемент и рекурсивно. Предыдущий элемент хранится в синглтон-списке p, который автоматически упаковывается в список и начинается как пустой (спасибо Деннису за 3 байта с этим).


55 байтов:

lambda l:[t[1]for t in zip([0]+l,l,l[1:]+[0])if any(t)]

Создает все фрагменты длины-3 из списка, сначала помещая нули в начало и конец, и берет элементы середины тех, которые не все равны нулю.

Итеративный подход оказался длиннее (58 байт)

a=0;b,*l=input()
for x in l+[0]:a|b|x and print(b);a,b=b,x

Это не совсем работает, потому что b,*lнужен Python 3, но Python 3 inputдает строку. Инициализация тоже безобразна. Возможно, подобный рекурсивный подход подойдет.

К сожалению, метод индексации

lambda l:[x for i,x in enumerate(l)if any(l[i-1:i+2])]

не работает, потому что l[-1:2]интерпретируется -1как конец списка, а не точка перед его началом.

XNOR
источник
10

Haskell, 55 48 байтов

h x=[b|a:b:c:_<-scanr(:)[0]$0:x,any(/=0)[a,b,c]]

Пример использования: h [0,0,0,8,0,1,0,0]-> [0,8,0,1,0].

scanrперестраивает входной список xс дополнительным 0в начале и конце. На каждом шаге мы сопоставляем 3 элемента и сохраняем средний, если есть хотя бы один ненулевой элемент.

Спасибо @xnor за 7 байтов, переключившись с zip3на scanr.

Ними
источник
Было бы неплохо просто сделать это h x=[snd t|t<-zip3(0:x)x$tail x++[0],(0,0,0)/=t], но я думаю, что нет короткого способа получить второй элемент 3-кортежа.
xnor
Оказывается, короче , чтобы получить тройки из scanчем zip3: h x=[b|a:b:c:_<-scanr(:)[0]$0:x,any(/=0)[a,b,c]].
xnor
8

Matlab, 29 27 байт

Входные данные должны состоять из 1*nматрицы (где n=0это возможно). (Это приведет к ошибке для 0*0матриц.)

@(a)a(conv(a.*a,1:3,'s')>0) 

Свертка - ключ к успеху.

flawr
источник
's'вместо 'same'<- :-D
Луис Мендо
Этот трюк
часто работает с buildins
Я видел этот трюк даже с вопросами, не связанными с игрой в гольф, с флагом 'UniformOutpout'(понятно). Но я не знал об этом
Луис Мендо
1
Не могли бы вы использовать ~~aвместо a.*a?
feersum
2
@feersum Matlab, к сожалению, отказывается объединять logicalмассивы. Это часто является проблемой для встроенных модулей, которые не написаны в самом Matlab. В противном случае логические массивы ведут себя во многом как числовые. Это может работать в мысли Октавы, но у меня не установлено в данный момент.
flawr
6

J, 17 14 байт

#~0<3+/\0,~0,|

Сохранено 3 байта с помощью @ Zgarb.

использование

   f =: #~0<3+/\0,~0,|
   f 2 0 4 _3 0 0 0 3 0 0 2 0 0
2 0 4 _3 0 0 3 0 0 2 0
   f ''

   f 0 0 0 8 0 1 0 0
0 8 0 1 0

объяснение

#~0<3+/\0,~0,|  Input: array A
             |  Get the absolute value of each in A
           0,   Prepend a 0
        0,~     Append a 0
    3  \        For each subarray of size 3, left to right
     +/           Reduce it using addition to find the sum
  0<            Test if each sum is greater than one
                (Converts positive values to one with zero remaining zero)
#~              Select the values from A using the previous as a mask and return

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

миль
источник
Будет 0<работать на месте 0~:?
Згарб
@Zgarb Инфиксы размера 3 могут быть положительными или отрицательными после обработки.
миль
Ах, я забыл об отрицательных ценностях.
Згарб
6

MATL , 8 байт

tg3:Z+g)

Выход - строка с числами, разделенными пробелами. Пустой массив на выходе отображается как ничто (даже не перевод строки).

Попробуйте онлайн! Или проверьте все тестовые случаи .

объяснение

Код преобразует входные данные в логический тип, то есть ненулевые записи становятся true(или 1), а нулевые записи становятся false(или 0). Это тогда свернуто с ядром [1 2 3]. Ненулевое значение вызывает ненулевой результат в этой позиции и в соседних позициях. Преобразование в логическое дает trueзначения, которые должны быть сохранены, поэтому индексация ввода с тем, который производит желаемый результат.

t    % Input array implicitly. Duplicate
g    % Convert to logical: nonzero becomes true, zero becomes false
3:   % Push array [1 2 3]
Z+   % Convolution, keeping size of first input
g    % Convert to logical
)    % Index into original array. Implicitly display
Луис Мендо
источник
5

Джольф, 14 байт

Теперь, когда я думаю об этом, Джольф - это Ява языков игры в гольф. вздохи Попробуй здесь.

ψxd||H.nwS.nhS

объяснение

ψxd||H.nwS.nhS
ψxd             filter input over this function
   ||           or with three args
     H           the element
      .nwS       the previous element
          .nhS   or the next element
Конор О'Брайен
источник
5

Python 3, 55 байт

lambda s:[t[1]for t in zip([0]+s,s,s[1:]+[0])if any(t)]
RootTwo
источник
1
Вау. Я не знаю, видел ли ты ответ @xnor до этого, но у тебя точно такой же код, с той лишь разницей, что имя лямбда. Если вы использовали его код, поверьте ему, если нет, какое сумасшедшее совпадение!
Тео
Не смотрел ни на кого код.
RootTwo
3
@ T.Lukin На самом деле нередко можно придумать один и тот же код. Вы можете видеть это на Anarchy Golf, где код скрыт до истечения срока, и несколько человек сходятся в одном решении, подобном этому .
xnor
4

Желе , 9 байт

0,0jo3\Tị

Попробуйте онлайн! или проверьте все контрольные примеры .

Как это работает

0,0jo3\Tị  Main link. Argument: A (array)

0,0        Yield [0, 0].
   j       Join, separating with A. This prepends and appends a 0 to A.
    o3\    Reduce each group of three adjacent integers by logical OR.
       T   Truth; get the indices of all truthy results.
        ị  At-index; retrieve the elements of A at those indices.
Деннис
источник
4

Perl, 34 + 1 ( -pфлаг) = 35 байт

s/([^1-9]0 |^)\K0 ?(?=0|$)//&&redo

Требуется -p флаг для запуска. Принимает список номеров как вменяемый. Например :

perl -pe 's/([^1-9]0 |^)\K0 ?(?=0|$)//&&redo' <<< "0 0 0 8 0 1 0 0
0 0 0
-5 0 5"
папа
источник
Я получу, 5если я введу 50 0.
февраля
@feersum исправлено, спасибо
Дада
4

Haskell, 48 байтов

p%(h:t)=[h|any(/=0)$p:h:take 1t]++h%t
p%e=e
(0%)

Просматривает предыдущий элемент p, первый элемент hи элемент после (если есть), и, если они есть, отличны от нуля, добавляет первый элемент h.

Условие any(/=0)$p:h:take 1tдлительное, в частности take 1t. Я буду искать способ сократить его, возможно, путем сопоставления с образцом.

XNOR
источник
4

Retina , 42 35 33 байта

7 байтов благодаря Мартину Эндеру.

(? <= ^ | \ b0) 0 (? = $ | 0)

 +

^ | $

Последняя строка необходима.

Проверьте все тестовые случаи одновременно. (Немного изменен, чтобы запускать все тестовые сценарии одновременно.)

Похоже, идеальный язык для этого ... все еще побежден большинством ответов.

Дрянная Монахиня
источник
Я бы просто отказался от скобок из формата ввода / вывода.
Мартин Эндер
3

Mathematica, 43 байта

ArrayFilter[If[#.#>0,#[[2]],Nothing]&,#,1]&
alephalpha
источник
3

C 96 байтов

Вызов f()с указателем на список целых чисел и указатель на размер списка. Список и размер изменяются на месте.

i,t,e,m;f(int*p,int*n){int*s=p;for(i=m=e=0;i++<*n;s+=t=m+*s||i<*n&&p[1],e+=t,m=*p++)*s=*p;*n=e;}

Попробуйте это на Ideone .

owacoder
источник
Стиль параметра K & R часто короче, но не здесь - f(int*p,int*n)сохраняет байт. Или определите sв качестве третьего параметра (это не передается. Это нормально).
Угорен
3

Брахилог , 44 38 байт

,0gL:?:Lc:1fzbh.
~c[A:.:B],[0:0:0]'.l3

Попробуйте онлайн!

Этот язык хорош как доказательство того, что мы будем использовать.

Предикат 0 (основной предикат)

,0gL:?:Lc:1fzbh.
 0gL               [0] = L    (assignment works both ways)
   L:?:Lc          [L:input:L] = temp
         :1f       find all solutions of predicate 1 with temp as input
            zbh.   then transpose and take the middle row and assign to output

Предикат 1 (вспомогательный предикат)

~c[A:.:B],[0:0:0]'.l3
~c[A:.:B]                 input is in the form of [A:output:B]
         ,                and
          [0:0:0]'.       output is not [0:0:0]
                  .l3     and length of output is 3
Дрянная Монахиня
источник
2

Matlab с инструментарием обработки изображений, 27 байт

@(a)a(~imerode(~a,~~(1:3)))

Это анонимная функция.

Пример использования:

>> @(a)a(~imerode(~a,~~(1:3)))
ans = 
    @(a)a(~imerode(~a,~~(1:3)))
>> ans([0 0 0 8 0 1 0 0])
ans =
     0     8     0     1     0
Луис Мендо
источник
1
Я imerodeтоже об этом думал , но мои версии продолжали быть длиннее, чем моя текущая, хорошая работа =)
flawr
2

Утилиты Bash + GNU, 25

grep -vC1 ^0|grep -v \\-$

Принимает ввод как разделенный новой строкой список.

Ideone - с добавлением кода тестового драйвера для запуска всех тестовых сценариев путем преобразования в / из пробела и перевода строки.

Цифровая травма
источник
2

Чеддер , 78 байт

a->([[]]+a.map((e,i)->e|(i?a[i-1]:0)|(i-a.len+1?a[i+1]:0)?[e]:[])).reduce((+))

Тестирование.

У Cheddar нет фильтра, поэтому фильтрация выполняется путем обертывания нужных элементов и преобразования ненужных элементов в пустые массивы, а затем объединения всего.

Например, [0,0,0,8,0,1,0,0]становится [[],[],[0],[8],[0],[1],[0],[]], и тогда будет конкатенированный массив [0,8,0,1,0].

Дрянная Монахиня
источник
.reduce((+))->.sum
Downgoat
@ Downgoat Когда ты это исправил?
Утренняя монахиня
о, извини, неважно Я думал, что вы суммируете массив. не присоединяется к массивам
Downgoat
1

APL, 14 байтов

{⍵/⍨×3∨/0,⍵,0}

Тест:

      {⍵/⍨×3∨/0,⍵,0}2 0 4 ¯3 0 0 0 3 0 0 2 0 0
2 0 4 ¯3 0 0 3 0 0 2 0

Объяснение:

  • 0,⍵,0: добавить ноль в начало и конец ⍵
  • ×3∨/: найти знак GCD каждой группы из трех смежных чисел (это будет 0, если все они равны нулю, и 1 в противном случае).
  • ⍵/⍨: выберите все элементы из ⍵, для которых результат был 1.
Мэринус
источник
1

Ruby 2.x, 63 байта

f=->(x){x.select.with_index{|y,i|x[i-1].to_i|y|x[i+1].to_i!=0}}

Кредит, где это должно произойти, это - по существу порт превосходного ответа Нила ES6.

Это также моя первая подача pcg. ура.

to_json
источник
1

Brain-Flak 142 байта

Попробуйте онлайн!

(<()>)(()){{}([]<([]){{}({}<>)<>({}<>)<>({}<>)<>(<>({}<>)<>({}<>)<>({})<>){{}((<()>))}{}{}([][()])}{}{}<>{}([]){{}({}<>)<>([])}{}<>>[[]])}{}{}

объяснение

(<()>)                    #Pad the top with an extra zero
(()){{}([]<...>[[]])}{}   #Until the stack height remains the same
 ([]){{}...([][()])}{}    #Until the stack height is one
  ({}<>)<>                #Move the top three to the other stack
  ({}<>)<>
  ({}<>)<>
  (...)                   #Push the sum of the top three
   <>({}<>)               #Move the second and third back
   <>({}<>)
   <>({})<>               #Leave the top of the stack
  {{}...}{}               #If the sum is not zero
   ((<()>))               #Add a buffer to the top of the stack
  {}                      #Pop the buffer/middle value
 {}                       #Remove extra zero
 <>                       #Switch to the off stack
 {}                       #Remove extra zero
 ([]){{}({}<>)<>([])}{}<> #Move the entire off stack back
Мастер пшеницы
источник
Ссылка пуста. Вы можете вставить код и ввести, нажмите «сохранить» и использовать полученную ссылку
Луис Мендо
@LuisMendo К сожалению, я не могу использовать tryitonline, поэтому я просто связался с URL.
Пшеничный волшебник
Почему вы не можете получить доступ к tryitonline?
DJMcMayhem
@DJMcMayhem У меня не было JavaScript в моем браузере. <s> Я исправлю это сейчас. </ s> Я вижу, вы уже сделали это, спасибо.
Пшеничный волшебник