Тримайте ненулі та їх сусідів


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? Досить декілька мов використовують цей формат.
Leaky Nun

Чи будемо мати -0?
Leaky Nun

@LeakyNun 1 Так 2 Ні
Луїс Мендо

Чи будуть коли-небудь числа мати провідні нулі? Як [010 0 0 01 1]?
FryAmTheEggman

@FryAmTheEggman Nope
Луїс Мендо

Відповіді:


16

JavaScript (ES6), 35 байт

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

На плавках працює також два додаткові байти.


10

Пітон, 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як кінець списку, а не крапка перед його початком.


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

Матлаб, 29 27 байт

Вхід повинен складатися з 1*nматриці (де n=0це можливо). (Це призведе до помилки для 0*0матриць.)

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

Конволюція - запорука успіху.


's'замість 'same'<- :-D
Луїс Мендо

Цей трюк спрацьовує багато разів із вбудованими =)
помилка

Я бачив цю хитрість, навіть у питаннях, що не стосуються гольфу, із прапором 'UniformOutpout'(зрозуміло). Але я не знав про це
Луїс Мендо

1
Чи можете ви використовувати ~~aзамість a.*a?
feersum

2
@feersum Matlab, на жаль, відмовляється згортати logicalмасиви. Це часто є проблемою для вбудованих модулів, які не записані в самій Matlab. В іншому випадку логічні масиви дуже поводяться, як чисельні. Це може спрацювати в думці Octave, але наразі у мене його немає.
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)]

1
Ого. Я не знаю, чи ви бачили відповідь @xnor до цього, але у вас точно такий же код, з тією лише різницею, як ім'я лямбда. Якщо ви все-таки використовували його код, дайте йому кредит, якщо ні, який шалений збіг!
Тео

Не дивився на чийсь код.
RootTwo

3
@ T.Lukin Насправді не рідкість придумати той самий код. Ви можете бачити це на Anarchy Golf, де код ховається до граничного терміну, і кілька людей сходяться на одному і тому ж рішенні, як це .
xnor


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

@feersum виправлено, дякую
Dada

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. Я буду шукати спосіб скоротити його, можливо, шляхом узгодження зразка.


4

Сітківка , 42 35 33 байт

7 байт завдяки Мартіну Ендеру.

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

 +

^ | $

Останній рядок необхідний.

Перевірте всі тести одразу. (Трохи модифікований для запуску всіх тестів одразу.)

Схоже, ідеальна мова для цього ... все-таки зазнала поразки від більшості відповідей.


Я б просто відкинув дужки у форматі вводу / виводу.
Мартін Ендер


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 .


Стиль параметрів K&R часто коротший, але тут немає - f(int*p,int*n)зберігає байт. Або визначте sяк 3-й параметр (це не передано. Це начебто ОК).
угорен

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

Тестовий набір.

У Чеддара немає фільтра, тому фільтрація проводиться шляхом загортання потрібних нам елементів і перетворення елементів, які ми не хочемо, у порожні масиви, а потім об'єднує все.

Наприклад, [0,0,0,8,0,1,0,0]стає [[],[],[0],[8],[0],[1],[0],[]], і тоді буде об'єднаний масив [0,8,0,1,0].


.reduce((+))->.sum
Пуховина

@Downgoat Коли ви це виправили?
Leaky Nun

о, вибачте ніколи. Я думав, ви підсумуєте масив. не приєднуючись до масивів
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: додати нуль до початку та кінця of
  • ×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.

Це також моє перше подання на ПК. так.


1

Мозок-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 На жаль, я не можу використовувати трийтолін, тому я просто пов'язаний з URL-адресою.
Пшеничний майстер

Чому ви не можете отримати доступ до трийтонлайн?
DJMcMayhem

@DJMcMayhem У мене в браузері не було JavaScript. <s> Я зараз це виправлю. </s> Я бачу, що ви вже зробили це завдяки.
Пшеничний майстер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.