Simpan nonzero dan tetangga mereka

26

Diambil dari pertanyaan ini di Stack Overflow. Terima kasih juga kepada @miles dan @Dada karena menyarankan input uji yang mengatasi beberapa kasus sudut.

Tantangan

Diberikan array nilai integer, hapus semua nol yang tidak diapit oleh beberapa nilai bukan nol.

Secara setara, sebuah entri harus disimpan baik jika bukan nol atau jika nol yang langsung dekat dengan nilai bukan nol.

Entri yang disimpan harus mempertahankan dalam output urutan yang mereka miliki di input.

Contoh

Diberikan

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

nilai-nilai yang harus dihapus ditandai dengan x:

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

dan hasilnya harus

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

Aturan

Array input mungkin kosong (dan kemudian output juga harus kosong).

Format input dan output fleksibel seperti biasa: array, daftar, string, atau apa pun yang masuk akal.

Golf kode, paling sedikit terbaik.

Uji kasus

[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
sumber
Bisakah saya menggunakan _2bukan -2? Beberapa bahasa menggunakan format itu.
Leaky Nun
Akankah kita memilikinya -0?
Leaky Nun
@LeakyNun 1 Ya 2 Tidak
Luis Mendo
Apakah angka akan pernah memiliki angka nol di depan? Suka [010 0 0 01 1]?
FryAmTheEggman
@FryAmTheEggman Nope
Luis Mendo

Jawaban:

16

JavaScript (ES6), 35 byte

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

Bekerja pada pelampung juga untuk dua byte tambahan.

Neil
sumber
10

Python, 50 byte

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

Fungsi rekursif yang membutuhkan tuple. Termasuk elemen pertama jika ada nilai bukan nol di antara dua elemen pertama atau nilai sebelumnya yang disimpan dari waktu lalu. Kemudian, hapus elemen pertama dan berulang. Elemen sebelumnya disimpan dalam daftar tunggal p, yang secara otomatis dikemas ke daftar dan mulai kosong (terima kasih kepada Dennis untuk 3 byte dengan ini).


55 byte:

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

Menghasilkan semua potongan panjang-3 dari daftar, pertama menempatkan nol pada awal dan akhir, dan mengambil elemen middle dari mereka yang tidak semuanya nol.

Pendekatan berulang ternyata lebih lama (58 byte)

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

Ini tidak bekerja karena b,*lmembutuhkan Python 3, tetapi Python 3 inputmemberikan string. Inisialisasi juga jelek. Mungkin pendekatan rekursif yang sama akan berhasil.

Sayangnya, metode pengindeksan

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

tidak berfungsi karena l[-1:2]diartikan -1sebagai akhir dari daftar, bukan titik sebelum mulainya.

Tidak
sumber
10

Haskell, 55 48 byte

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

Contoh penggunaan: h [0,0,0,8,0,1,0,0]-> [0,8,0,1,0].

scanrmembangun kembali daftar input xdengan tambahan 0di awal dan akhir. Dalam setiap langkah, kami memadukan pola 3 elemen dan mempertahankan elemen tengah jika setidaknya ada satu elemen non-nol.

Terima kasih @xnor selama 7 byte dengan beralih dari zip3ke scanr.

nimi
sumber
Akan menyenangkan untuk dilakukan h x=[snd t|t<-zip3(0:x)x$tail x++[0],(0,0,0)/=t], tetapi saya kira tidak ada cara singkat untuk benar-benar mendapatkan elemen kedua dari 3-tuple.
xnor
Bergantian keluar lebih pendek untuk mendapatkan tiga kali lipat dari yang scandari zip3: h x=[b|a:b:c:_<-scanr(:)[0]$0:x,any(/=0)[a,b,c]].
xnor
8

Matlab, 29 27 byte

Input harus terdiri dari 1*nmatriks (jika n=0memungkinkan). (Ini akan menimbulkan kesalahan untuk 0*0matriks.)

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

Konvolusi adalah kunci kesuksesan.

cacat
sumber
's'bukannya 'same'<- :-D
Luis Mendo
Trik itu berfungsi banyak kali dengan builtins =)
flawr
Saya telah melihat trik itu, bahkan untuk pertanyaan non-golf, dengan bendera 'UniformOutpout'(dapat dimengerti). Tetapi saya tidak tahu tentang yang ini
Luis Mendo
1
Bisakah Anda menggunakan ~~abukan a.*a?
feersum
2
@feersum Matlab sayangnya menolak untuk membelit logicalarray. Ini sering merupakan masalah bagi built-in yang tidak ditulis dalam Matlab itu sendiri. Kalau tidak, array logis berperilaku sangat mirip dengan yang bernomor. Mungkin berfungsi dalam pemikiran Octave, tetapi saya belum menginstalnya saat ini.
flawr
6

J, 17 14 byte

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

Disimpan 3 byte dengan bantuan dari @ Zgarb.

Pemakaian

   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

Penjelasan

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

Coba di sini.

mil
sumber
Akan 0<bekerja di tempat 0~:?
Zgarb
@Zgarb Infiks ukuran 3 dapat berupa positif atau negatif setelah diproses.
mil
Ah, saya lupa tentang nilai negatifnya.
Zgarb
6

MATL , 8 byte

tg3:Z+g)

Output adalah string dengan angka yang dipisahkan oleh spasi. Array kosong pada output ditampilkan sebagai tidak ada (bahkan bukan baris baru).

Cobalah online! Atau verifikasi semua kasus uji .

Penjelasan

Kode mengubah input menjadi tipe logis, yaitu entri yang bukan nol menjadi true(atau 1) dan entri nol menjadi false(atau 0). Ini kemudian dililit dengan kernel [1 2 3]. Nilai bukan nol menyebabkan hasil bukan nol pada posisi itu dan pada posisi tetangganya. Konversi ke logika memberikan truenilai yang harus dijaga, jadi mengindeks input dengan yang menghasilkan output yang diinginkan.

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
sumber
5

Jolf, 14 byte

Sekarang saya memikirkannya, Jolf adalah Java dari bahasa golf. mendesah Coba di sini.

ψxd||H.nwS.nhS

Penjelasan

ψ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
sumber
5

Python 3, 55 byte

lambda s:[t[1]for t in zip([0]+s,s,s[1:]+[0])if any(t)]
RootTwo
sumber
1
Wow. Saya tidak tahu apakah Anda melihat @ xnor menjawab sebelum ini, tetapi Anda memiliki kode yang sama persis, dengan satu-satunya perbedaan adalah nama lambda. Jika Anda memang menggunakan kodenya, beri dia kredit, jika tidak, sungguh kebetulan yang gila!
Theo
Tidak melihat kode siapa pun.
RootTwo
3
@ T.Lukin Sebenarnya bukan hal yang aneh untuk membuat kode yang sama. Anda dapat melihat ini terjadi di Anarchy Golf, di mana kode disembunyikan hingga batas waktu, dan beberapa orang bertemu pada solusi yang sama seperti ini .
xnor
4

Jelly , 9 byte

0,0jo3\Tị

Cobalah online! atau verifikasi semua kasus uji .

Bagaimana itu bekerja

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
sumber
4

Perl, 34 + 1 ( -pbendera) = 35 byte

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

Membutuhkan flag -p untuk dijalankan. Mengambil daftar nomor sebagai imput. Contohnya :

perl -pe 's/([^1-9]0 |^)\K0 ?(?=0|$)//&&redo' <<< "0 0 0 8 0 1 0 0
0 0 0
-5 0 5"
Dada
sumber
Saya dapatkan 5jika saya input 50 0.
feersum
@feersum diperbaiki, terima kasih
Dada
4

Haskell, 48 byte

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

Melihat elemen sebelumnya p, elemen pertama h, dan elemen setelah (jika ada), dan jika ada yang bukan nol, tambahkan dulu elemen pertama h.

Kondisinya any(/=0)$p:h:take 1tpanjang, khususnya take 1t. Saya akan mencari cara untuk mempersingkatnya, mungkin dengan pencocokan pola.

Tidak
sumber
4

Retina , 42 35 33 byte

7 byte berkat Martin Ender.

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

 +

^ | $

Baris terakhir diperlukan.

Verifikasi semua testcans sekaligus. (Sedikit dimodifikasi untuk menjalankan semua testcass sekaligus.)

Sepertinya bahasa yang sempurna untuk melakukan ini ... masih dikalahkan oleh sebagian besar jawaban.

Biarawati Bocor
sumber
Saya baru saja meninggalkan tanda kurung dari format I / O.
Martin Ender
3

Mathematica, 43 byte

ArrayFilter[If[#.#>0,#[[2]],Nothing]&,#,1]&
alephalpha
sumber
3

C, 96 byte

Panggil f()dengan penunjuk ke daftar bilangan bulat, dan penunjuk ke ukuran daftar. Daftar dan ukuran dimodifikasi di tempat.

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

Cobalah di ideone .

owacoder
sumber
Gaya parameter K&R seringkali lebih pendek, tetapi tidak di sini - f(int*p,int*n)menyimpan satu byte. Atau definisikan ssebagai parameter ke-3 (itu tidak lulus. Ini semacam OK).
ugoren
3

Brachylog , 44 38 byte

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

Cobalah online!

Bahasa ini bagus untuk membuktikan hal-hal, yang akan kita gunakan.

Predikat 0 (predikat utama)

,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

Predikat 1 (predikat bantu)

~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
Biarawati Bocor
sumber
2

Matlab dengan Image Processing Toolbox, 27 byte

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

Ini adalah fungsi anonim.

Contoh penggunaan:

>> @(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
sumber
1
Saya juga memikirkannya imerode, tetapi versi saya tetap lebih lama dari versi saya saat ini, kerja bagus =)
flawr
2

Utilitas Bash + GNU, 25

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

Menerima input sebagai daftar yang dipisahkan oleh baris baru.

Ideone - dengan kode test driver ditambahkan untuk menjalankan semua testcases bersama dengan mengkonversi ke / dari spasi dan dipisahkan oleh baris.

Trauma Digital
sumber
2

Cheddar , 78 byte

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

Suite uji.

Cheddar tidak memiliki filter, jadi penyaringan dilakukan dengan membungkus elemen yang kita inginkan dan mengubah elemen yang tidak kita inginkan menjadi array kosong, dan kemudian menggabungkan semuanya.

Misalnya, [0,0,0,8,0,1,0,0]menjadi [[],[],[0],[8],[0],[1],[0],[]], dan kemudian array gabungan akan menjadi [0,8,0,1,0].

Biarawati Bocor
sumber
.reduce((+))->.sum
Downgoat
@Downgoat Kapan Anda memperbaikinya?
Leaky Nun
oh maaf maaf Saya pikir Anda menjumlahkan array. tidak bergabung dengan array
Downgoat
1

APL, 14 byte

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

Uji:

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

Penjelasan:

  • 0,⍵,0: tambahkan nol ke awal dan akhir ⍵
  • ×3∨/: temukan tanda GCD dari setiap kelompok yang terdiri dari tiga angka yang berdekatan (ini akan menjadi 0 jika semuanya nol dan 1 sebaliknya).
  • ⍵/⍨: pilih semua item dari ⍵ yang hasilnya 1.
marinus
sumber
1

Ruby 2.x, 63 byte

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

Terima kasih karena sudah waktunya, ini pada dasarnya adalah port jawaban ES6 superior Neil.

Ini juga pengiriman pcg pertama saya. yay.

to_json
sumber
1

Brain-Flak 142 byte

Cobalah online!

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

Penjelasan

(<()>)                    #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
Wisaya Gandum
sumber
Tautan kosong. Anda dapat menempelkan kode dan memasukkan, tekan "simpan" dan gunakan tautan yang dihasilkan
Luis Mendo
@LuisMendo Sayangnya saya tidak bisa menggunakan tryitonline jadi saya hanya menautkan ke url.
Wheat Wizard
Mengapa Anda tidak bisa mengakses tryitonline?
DJMcMayhem
@DJMcMayhem Saya tidak punya javascript di browser saya. <s> Saya akan memperbaikinya sekarang. </s> Saya tahu Anda sudah melakukannya, terima kasih.
Wheat Wizard