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]

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.


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.


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.


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.


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


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

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

5

Python 3, 55 byte

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

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.

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"

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.


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.


Saya baru saja meninggalkan tanda kurung dari format I / O.
Martin Ender

3

Mathematica, 43 byte

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

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 .


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

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

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.


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


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

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.


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

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.