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]

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.


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.


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.


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.


'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.


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

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

5

Python 3, 55 bajtów

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

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

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"

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.




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 .


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

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

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.


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


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

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.


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

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,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.