Zachowaj nonzeros i ich sąsiadów

26

Zaczerpnięte z tego pytania w Stack Overflow. Dziękujemy również @miles i @Dada za sugerowanie danych testowych dotyczących niektórych przypadków narożnych.

Wyzwanie

Biorąc pod uwagę tablicę wartości całkowitych, usuń wszystkie zera, które nie są flankowane przez jakąś niezerową wartość.

Odpowiednio, wpis powinien zostać zachowany, jeśli jest niezerowy lub jeśli zero jest bezpośrednio bliskie niezerowej wartości.

Przechowywane wpisy powinny zachować w danych wyjściowych kolejność, jaką miały na wejściu.

Przykład

Dany

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

wartości, które należy usunąć, są oznaczone x:

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

i tak wynik powinien być

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

Zasady

Tablica wejściowa może być pusta (a następnie dane wyjściowe również powinny być puste).

Formaty wejściowe i wyjściowe są jak zwykle elastyczne: tablica, lista, ciąg znaków lub cokolwiek rozsądnego.

Kod golfa, najmniej najlepszy.

Przypadki testowe

[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]
Luis Mendo
źródło
Czy mogę użyć _2zamiast -2? Wiele języków korzysta z tego formatu.
Leaky Nun
Będziemy mieli -0?
Leaky Nun
@LeakyNun 1 Tak 2 Nie
Luis Mendo
Czy liczby będą miały początkowe zera? Jak [010 0 0 01 1]?
FryAmTheEggman
@FryAmTheEggman Nope
Luis Mendo

Odpowiedzi:

16

JavaScript (ES6), 35 bajtów

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

Działa również na liczbach zmiennoprzecinkowych dla dwóch dodatkowych bajtów.

Neil
źródło
10

Python, 50 bajtów

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

Funkcja rekurencyjna, która wymaga krotki. Obejmuje pierwszy element, jeśli pomiędzy pierwszymi dwoma elementami lub poprzednią wartością zapisaną od czasu ostatniego jest niezerowa wartość. Następnie usuwa pierwszy element i powtarza się. Poprzedni element jest przechowywany na liście singleton p, która automatycznie pakuje się na listę i zaczyna jako pusta (dzięki Dennisowi za 3 bajty z tym).


55 bajtów:

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

Generuje wszystkie fragmenty długości o długości 3, najpierw umieszczając zera na początku i na końcu, i przyjmuje elementy środkowe tych, które nie wszystkie są zerowe.

Podejście iteracyjne okazało się dłuższe (58 bajtów)

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

To nie działa dokładnie, ponieważ b,*lwymaga Python 3, ale Python 3 inputdaje ciąg znaków. Inicjalizacja jest również brzydka. Może zadziałałoby podobne podejście rekurencyjne.

Niestety metoda indeksowania

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

nie działa, ponieważ l[-1:2]interpretuje -1jako koniec listy, a nie punkt przed jej rozpoczęciem.

xnor
źródło
10

Haskell, 55 48 bajtów

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

Przykład użycia: h [0,0,0,8,0,1,0,0]-> [0,8,0,1,0].

scanrodbudowuje listę danych wejściowych xz dodatkową 0na początku i na końcu. Na każdym etapie dopasowujemy wzór 3 elementy i zachowujemy środkowy, jeśli jest co najmniej jeden element niezerowy.

Dzięki @xnor za 7 bajtów, przełączając się z zip3na scanr.

nimi
źródło
Byłoby miło to zrobić h x=[snd t|t<-zip3(0:x)x$tail x++[0],(0,0,0)/=t], ale wydaje mi się, że nie ma krótkiego sposobu na uzyskanie drugiego elementu 3-krotnego.
xnor
Okazuje się krótsze, aby uzyskać trójek Spośród scanniż zip3: h x=[b|a:b:c:_<-scanr(:)[0]$0:x,any(/=0)[a,b,c]].
xnor
8

Matlab, 29 27 bajtów

Dane wejściowe muszą składać się z 1*nmacierzy (gdzie n=0jest to możliwe). (Zgłasza błąd dla 0*0macierzy).

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

Konwolucja jest kluczem do sukcesu.

wada
źródło
's'zamiast 'same'<- :-D
Luis Mendo
Ta sztuczka często działa z wbudowanymi =)
flawr
Widziałem tę sztuczkę, nawet w przypadku pytań niezwiązanych z golfem, z flagą 'UniformOutpout'(co zrozumiałe). Ale nie wiedziałem o tym
Luis Mendo
1
Czy możesz użyć ~~azamiast a.*a?
feersum
2
@feersum Matlab niestety odmawia zwołania logicaltablic. Jest to często problem w przypadku wbudowanych, które nie są napisane w samym Matlabie. W przeciwnym razie tablice logiczne zachowują się bardzo podobnie do tablic numerycznych. To może działać w myślach Octave, ale w tej chwili nie mam go zainstalowanego.
flawr
6

J, 17 14 bajtów

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

Zapisano 3 bajty z pomocą @ Zgarb.

Stosowanie

   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

Wyjaśnienie

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

Wypróbuj tutaj.

mile
źródło
Czy 0<działałby zamiast 0~:?
Zgarb,
@Zgarb Przyrostki rozmiaru 3 mogą być dodatnie lub ujemne po przetworzeniu.
mile
Ach, zapomniałem o wartościach ujemnych.
Zgarb,
6

MATL , 8 bajtów

tg3:Z+g)

Dane wyjściowe to ciąg znaków z liczbami oddzielonymi spacjami. Pusta tablica na wyjściu jest wyświetlana jako nic (nawet nowa linia).

Wypróbuj online! Lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie

Kod przekształca dane wejściowe na typ logiczny, tzn. Niezerowe wpisy stają się true(lub 1), a zero wpisów staje się false(lub 0). Jest to następnie rozwiązywane z jądrem [1 2 3]. Niezerowa wartość powoduje niezerowy wynik na tej pozycji i na sąsiednich pozycjach. Konwersja na logiczną daje truewartości, które należy zachować, więc indeksowanie danych wejściowych za pomocą tego daje pożądane dane wyjściowe.

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
Luis Mendo
źródło
5

Jolf, 14 bajtów

Teraz, gdy o tym myślę, Jolf jest Javą języków golfowych. westchnienia Wypróbuj tutaj.

ψxd||H.nwS.nhS

Wyjaśnienie

ψ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
Conor O'Brien
źródło
5

Python 3, 55 bajtów

lambda s:[t[1]for t in zip([0]+s,s,s[1:]+[0])if any(t)]
RootTwo
źródło
1
Łał. Nie wiem, czy widziałeś @xnor odpowiedź wcześniej, ale masz dokładnie ten sam kod, z tą różnicą, że jest to nazwa lambda. Jeśli używałeś jego kodu, powiedz mu, jeśli nie, co za szalony zbieg okoliczności!
Theo,
Nie spojrzał na kod nikogo.
RootTwo
3
@ T.Lukin W rzeczywistości często zdarza się wymyślić ten sam kod. Możesz to zobaczyć na Anarchy Golf, gdzie kod jest ukryty do upływu terminu, a wiele osób zbiera się w tym samym rozwiązaniu jak to .
xnor
4

Galaretka , 9 bajtów

0,0jo3\Tị

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .

Jak to działa

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.
Dennis
źródło
4

Perl, 34 + 1 ( -pflaga) = 35 bajtów

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

Potrzebuje flagi -p do uruchomienia. Pobiera listę liczb jako imput. Na przykład :

perl -pe 's/([^1-9]0 |^)\K0 ?(?=0|$)//&&redo' <<< "0 0 0 8 0 1 0 0
0 0 0
-5 0 5"
Dada
źródło
Dostaję, 5jeśli wejdę 50 0.
feersum
@feersum naprawiono, dziękuję
Dada,
4

Haskell, 48 bajtów

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

Patrzy na poprzedni element p, pierwszy element hi element po (jeśli istnieje), a jeśli jest niezerowy, wstawia pierwszy element h.

Warunek any(/=0)$p:h:take 1tjest długi, w szczególności take 1t. Poszukam sposobu na jego skrócenie, być może poprzez dopasowanie wzoru.

xnor
źródło
4

Retina , 42 35 33 bajtów

7 bajtów dzięki Martinowi Enderowi.

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

 +

^ | $

Ostatni wiersz jest konieczny.

Zweryfikuj wszystkie przypadki testowe jednocześnie. (Nieznacznie zmodyfikowany, aby uruchomić wszystkie przypadki testowe jednocześnie).

Wygląda na idealny język do zrobienia tego w ... wciąż został pokonany przez większość odpowiedzi.

Leaky Nun
źródło
Po prostu zerwałbym nawiasy z formatu I / O.
Martin Ender,
3

Mathematica, 43 bajty

ArrayFilter[If[#.#>0,#[[2]],Nothing]&,#,1]&
alephalpha
źródło
3

C, 96 bajtów

Wywołaj f()wskaźnikiem do listy liczb całkowitych i wskaźnikiem wielkości listy. Lista i rozmiar są modyfikowane na miejscu.

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

Wypróbuj na ideone .

owacoder
źródło
Styl parametru K&R jest często krótszy, ale nie tutaj - f(int*p,int*n)oszczędza bajt. Lub zdefiniuj sjako trzeci parametr (który nie został przekazany. To rodzaj OK).
ugoren,
3

Brachylog , 44 38 bajtów

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

Wypróbuj online!

Ten język jest dobry do sprawdzania rzeczy, z czego będziemy korzystać.

Predykat 0 (główny predykat)

,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

Predykat 1 (predykat pomocniczy)

~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
Leaky Nun
źródło
2

Matlab z Przybornikiem przetwarzania obrazu, 27 bajtów

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

To anonimowa funkcja.

Przykładowe zastosowanie:

>> @(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
Luis Mendo
źródło
1
Też o tym myślałem imerode, ale moje wersje były dłuższe niż moja obecna, fajna robota =)
flawr
2

Narzędzia Bash + GNU, 25

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

Akceptuje dane wejściowe jako listę oddzieloną znakiem nowej linii.

Ideone - z dodanym kodem sterownika testowego, aby uruchomić wszystkie przypadki testowe razem poprzez konwersję do / z separacją spacji i separacją nowego wiersza.

Cyfrowa trauma
źródło
2

Cheddar , 78 bajtów

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

Zestaw testowy.

Cheddar nie ma filtra, więc filtrowanie odbywa się poprzez zawijanie pożądanych elementów i przekształcanie elementów, których nie chcemy, w puste tablice, a następnie łączenie wszystkiego.

Na przykład [0,0,0,8,0,1,0,0]staje się [[],[],[0],[8],[0],[1],[0],[]], a następnie byłaby skonkatenowana tablica [0,8,0,1,0].

Leaky Nun
źródło
.reduce((+))->.sum
Downgoat,
@Downgoat Kiedy to naprawiłeś?
Leaky Nun
o, przepraszam, nieważne. Myślałem, że sumujesz tablicę. nie dołączanie do tablic
Downgoat
1

APL, 14 bajtów

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

Test:

      {⍵/⍨×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

Wyjaśnienie:

  • 0,⍵,0: dodaj zero na początku i na końcu ⍵
  • ×3∨/: znajdź znak GCD każdej grupy trzech sąsiednich liczb (będzie to 0, jeśli wszystkie będą zerowe, a 1 w przeciwnym razie).
  • ⍵/⍨: wybierz wszystkie elementy z ⍵, dla których wynik to 1.
marinus
źródło
1

Ruby 2.x, 63 bajty

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

Kredyt tam, gdzie jest to należne, jest w istocie częścią doskonałej odpowiedzi Neila na ES6.

To także moje pierwsze zgłoszenie PCG. tak.

to_json
źródło
1

Brain-Flak 142 bajty

Wypróbuj online!

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

Wyjaśnienie

(<()>)                    #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
Kreator pszenicy
źródło
Link jest pusty. Możesz wkleić kod i dane wejściowe, nacisnąć „zapisz” i użyć wynikowego linku
Luis Mendo
@LuisMendo Niestety nie mogę użyć tryitonline, więc właśnie podłączyłem do adresu URL.
Wheat Wizard
Dlaczego nie możesz uzyskać dostępu do tryitonline?
DJMcMayhem
@DJMcMayhem Nie miałem javascript w przeglądarce. <s> Naprawię to teraz. </s> Widzę, że już to zrobiłeś, dziękuję.
Kreator pszenicy,