Perbaiki rentang

30

Diberikan input dari daftar bilangan bulat positif dengan beberapa diganti dengan 0, output daftar dengan angka-angka yang hilang yang diubah untuk 0diganti.

Karakteristik daftar input:

  • Daftar akan selalu memiliki paling sedikit 2.

  • Mari kita mendefinisikan daftar input sebagai adan "daftar asli" (yaitu, daftar sebelum nomor diganti dengan 0s) sebagai b. Untuk apa pun n, a[n]apakah b[n]atau 0.

  • Untuk apa pun n, b[n]apakah b[n-1] + 1atau b[n-1] - 1. Artinya, angka-angka di bakan selalu berubah 1setiap indeks dari sebelumnya. Elemen pertama, tentu saja, dibebaskan dari aturan ini.

  • Untuk setiap proses nol di a(yaitu, elemen berturut-turut diganti dengan 0), dengan xmewakili indeks awal menjalankan dan y mewakili akhir, a[x-1]untuk a[y+1]akan selalu menjadi hanya meningkat atau semata-mata menurun. Karena itu, hanya akan ada satu cara yang mungkin untuk mengisi nol.

    • Ini juga berarti bahwa baik elemen pertama maupun terakhir dari array tidak dapat bernilai nol.

Dalam istilah yang lebih sederhana, untuk mengisinya dengan angka nol, cukup ganti dengan rentang dari angka sebelum ke angka yang mengikutinya. Misalnya, input dari

1 2 0 0 0 6 7

harus keluar

1 2 3 4 5 6 7

Karena ini adalah , kode terpendek dalam byte akan menang.

Kasus uji:

In                      Out
-----------------------------------------------------
1 0 0 0 5 6 0 4 0 0 1 | 1 2 3 4 5 6 5 4 3 2 1
7 6 0 0 3 0 0 0 7 0 5 | 7 6 5 4 3 4 5 6 7 6 5
1 0 3 0 5 0 3 0 5 0 7 | 1 2 3 4 5 4 3 4 5 6 7
14 0 0 0 0 0 0 0 0 23 | 14 15 16 17 18 19 20 21 22 23
Gagang pintu
sumber
Alih-alih, apakah 0program kami dapat mengambil nilai lain seperti null?
Downgoat
@Downgoat Tidak, nomor yang hilang harus diberikan sebagai 0.
Gagang Pintu

Jawaban:

15

JavaScript (ES6), 72 66 64 54 53 byte

Disimpan 12 byte berkat @Neil!

Disimpan 1 byte berkat @IsmaelMiguel

a=>a.map((l,i)=>l?b=l:b+=a.find((q,r)=>r>i&&q)>b||-1)

Cukup bagus untuk JavaScript.


Coba online (semua browser berfungsi)

Penjelasan

a=>  // Function with arg `a`
  a.map((l,i)=>  // Loop through input
    l?             // If nonzero
      b=l          // Set `b` to current number
    :a.find((q,r)=>r>i&q) // Otherwise look for the next nonzero number
     >b?           // If it's increased since nonzero last number   
       ++b:--b)    // Increasing? increase `b` (the previous nonzero number)
                   // otherwise decrease `b`
Downgoat
sumber
1
Saya pikir itu a.find((q,r)=>r>i&&q)>b?++b:--bsama denganb+=a.find((q,r)=>r>i&&q)>b||-1
Ismael Miguel
@ IsmaelMiguel itu pintar, terima kasih!
Downgoat
Sama-sama. Saya senang itu berhasil untuk Anda.
Ismael Miguel
Saya pikir Anda dapat mengganti && hanya dengan & (Hanya memperhatikan Anda memiliki satu & dalam penjelasan dan dua di jawabannya)
Charlie Wynn
7

MATL , 11 12 byte

fGXzGn:3$Yn

Bekerja dengan rilis saat ini (13.0.0) dari bahasa / kompiler.

Cobalah online!

f        % implicitly input array. Indices of nonzero elements (*)
GXz      % push input and get its nonzero elements (**)
Gn:      % vector [1,2,...,n], where n is input length (***)
3$Yn     % interpolate at positions (***) from data (**) defined at positions (*)
Luis Mendo
sumber
7

Haskell, 68 61 58 byte

g(a:b:r)=[a..b-1]++[a,a-1..b+1]++g(b:r)
g x=x
g.filter(>0)

Contoh penggunaan: g.filter(>0) $ [7,6,0,0,3,0,0,0,7,0,5]->[7,6,5,4,3,4,5,6,7,6,5] .

Cara kerjanya: hapus nol dari input, lalu panggil g. Membiarkan amenjadi elemen pertama dan bkemudian kedua dari daftar yang tersisa. Menggabungkan daftar dari aatas ke b-1dan dari abawah ke b+1(salah satunya akan kosong) dan panggilan rekursif dengana menjatuhkan.

Sunting: @Zgarb menyimpan 3 byte. Terima kasih!

nimi
sumber
6

Mathematica, 59 byte

#//.{a___,x_,0..,y_,b___}:>{a,##&@@Range[x,y,Sign[y-x]],b}&

Kasus cobaan

%[{1,0,3,0,5,0,3,0,5,0,7}]
(* {1,2,3,4,5,4,3,4,5,6,7} *)
njpipeorgan
sumber
4

Perl, 47 45 44 39 37 byte

Termasuk +1 untuk -p

s%\S+%$p+=/\G(0 )+/?$'<=>$p:$&-$p%eg

Harapkan daftar di stdin. Contoh: echo 1 0 3 0 1 | perl -p file.pl

Ton Hospel
sumber
Saya melihat beberapa copy paste di sini .. ;-) Btw dilakukan dengan baik.
Kenney
3

Jelly, 12 11 byte

ḢWW;ḟ0Ṫr¥\F

Cobalah online!

Versi alternatif, 8 byte (tidak bersaing)

Sayangnya, Jelly's poptidak bisa menggunakan iterable, di versi terbaru yang ada sebelum tantangan ini. Ini telah diperbaiki, dan berikut ini berfungsi dalam versi saat ini.

ḟ0Ṫr¥\FḊ

Cobalah online!

Bagaimana itu bekerja

ḢWW;ḟ0Ṫr¥\F  Main link. Input: A (list)

Ḣ            Pop the first element of A. Let's call it a.
 WW          Yield [[a]].
   ;         Concatenate with the popped A.
             This wraps the first element of A in an array.
    ḟ0       Filter; remove all zeroes.
        ¥    Create a dyadic chain:
      Ṫ        Pop the last element of the left argument.
       r       Call range on the popped element and the right argument.
         \   Reduce the modified A by this chain.
          F  Flatten the resulting list of ranges.

Dalam versi alternatif, ḢWW;menjadi tidak perlu. Namun, karena elemen pertama dilemparkan ke iterable sebelum muncul, sebenarnya tidak dimodifikasi. Final menghapus duplikat elemen pertama.

Dennis
sumber
3

Retina, 39 34 31 byte

3 byte disimpan berkat @Martin.

+`1(1*) (?= +((1)\1)?)
$0$1$3$3

Mengambil input dan memberikan output secara unary.

Kode berulang mengisi setiap tempat kosong (0) previous_number - 1 + 2 * if_next_nonzero_number_bigger. previous_number - 1adalah $1dan if_next_nonzero_number_biggersekarang $3.

Dengan I / O desimal, kodenya adalah 51 byte, seperti yang dapat Anda lihat di penerjemah online dengan semua kasus uji .

randomra
sumber
Anda dapat menyimpan byte lain dengan menghilangkan byte pertama 1di lookahead.
Martin Ender
@ MartinBüttner Kanan, diedit.
randomra
2

GNU Sed (dengan execekstensi menggunakan bash), 61

Skor termasuk +1 untuk -ropsi sed.

:
s/( 0)+ /../
s/\w+..\w+/{&}/
s/.*/bash -c 'echo &'/e
/ 0/b
  • Temukan run 0s dan gantikan..
  • Letakkan kawat gigi di sekitar angka titik akhir untuk membuat ekspansi bash brace seperti {1..4}untuk titik akhir lokal. Keindahan dari ekspansi bash brace di sini adalah bahwa urutan yang dihasilkan akan selalu berjalan di arah yang benar, terlepas dari apakah awal atau akhir lebih besar.
  • Gunakan eopsi pada sperintah untuk memanggil bash untuk mengevaluasi ekspansi brace ini
  • Jika ada lagi 0yang ditemukan, melompat kembali ke awal.

Ideone.

Trauma Digital
sumber
2

Python 2, 195 111 byte (terima kasih Alex !)

t=input()
z=0
for i,e in enumerate(t):
 if e:
  while z:t[i-z]=e+z if l>e else e-z;z-=1
  l=e
 else:z+=1
print t

Input: harus berupa [list]int.
Keluaran: [list]dari int

vageli
sumber
Maaf soal itu! Tetap. Terimakasih atas peringatannya.
vageli
Jangan khawatir. Solusi bagus :) Anda bisa mendapatkannya hingga 112 byte menggunakan ini , yang merupakan pendekatan Anda yang sama, hanya bermain golf sedikit lebih. Kami juga memiliki kumpulan kiat untuk bermain golf di Python di sini .
Alex A.
1

Perl, 85 82 byte

termasuk +1 untuk -p

s/(\d+)(( 0)+) (\d+)/$s=$1;$e=$4;$_=$2;$c=$s;s!0!$c+=$e<=>$s!eg;"$s$_ $e"/e&&redo

Harapkan daftar di stdin. Contoh: echo 1 0 3 0 1 | perl -p file.pl.

Ini menggunakan regexp bersarang. Dapat dibaca:

s/(\d+)(( 0)+) (\d+)                  # match number, sequence of 0, number
 /
    $s=$1;                            # start number
    $e=$4;                            # end number
    $_=$2;                            # sequence of ' 0'
    $c=$s;                            # initialize counter with start number
    s!0! $c += $s <=> $e !eg          # replace all 0 with (in|de)cremented counter
    "$s$_ $e"                         # return replacement
 /e
&& redo                               # repeat until no more changes.
Kenney
sumber
1

Python 2, 92 88 byte

(Variabel perantara yang dihapus)

t=filter(bool,input())
print sum([range(o,p,cmp(p,o))for o,p in zip(t,t[1:])],[])+t[-1:]
Orez
sumber
1

Pyth, 17 byte

u+G+treGHHfTtQ[hQ

Cara kerjanya:

u                 reduce
              [hQ     seed: the first element of input, in a list
                      iterable:
          tQ              all except the first element of input
        fT                remove if 0
                      lambda: G is the list to be returned, H is the current item
 +G                       append to return list
    reGH                  a range from the last element of the return list and the current item
   +                      concatenated with
        H                 the last item (this step forms a bidirectional inclusive list)

Dengan kata lain: semua nol dihapus dari input, lalu rentang eksklusif dimasukkan di antara setiap elemen. Rentang ini adalah nol panjang pada elemen yang hanya satu terpisah.

Cameron McCluskie
sumber
1

05AB1E , 3 byte (tidak bersaing)

Ini adalah fitur yang ditambahkan setelah tantangan. Kode:

0KŸ

Penjelasan:

0K   # Remove all zeroes from the input list
  Ÿ  # Rangify, [1, 4, 1] would result into [1, 2, 3, 4, 3, 2, 1]

Cobalah online! atau Verifikasi semua kasus uji!

Adnan
sumber
1

Vim: 231 Perintah Utama

Perhatikan bahwa setiap ^ yang mendahului karakter berarti Anda harus memegang kendali saat mengetik karakter itu

mbomayiwo^V^R"^V^V^V^X ^V^["sy0dd`a@f ^["bc0yiwo^V^V^V^X^V^R"^V^[0l@sa^V^V^V^A-^V^[0f-"ayhdd`a@i ^["dc0mbyiwo^V^R"Exe@b^V^[0fel"ty2ldd`b@t ^["ec0wmbyiwo@f @d^V^[@z ^["fc0"xyiwwmbyiwocw^V^V^V^Rx^V^V^V^[@a@i @e^V^[@z ^["ic0IB0 B^V^R" ^V^OWB0 ^V^OA B0^V^[0*w"tyiWdd`b@t ^["zd0dd`bAe^[0@e 

Langkah-langkah agar Anda dapat menjalankan ini juga!

  1. Salin baris ke Vim
  2. Mengetik :s/\^V/<Ctrl-V><Ctrl-V>/g dan tekan enter (keduanya harus memberi Anda warna biru ^ V)
  3. Mengetik :s/\^R/<Ctrl-V><Ctrl-R>/g dan tekan enter (Anda akan melihat biru ^ Rs sekarang)
  4. Mengetik :s/\^X/<Ctrl-V><Ctrl-X>/g dan tekan enter (Anda akan melihat biru ^ Xs sekarang)
  5. Mengetik :s/\^O/<Ctrl-V><Ctrl-O>/g dan tekan enter
  6. Mengetik :s/\^A/<Ctrl-V><Ctrl-A>/g dan tekan enter
  7. Mengetik :s/\^\[/<Ctrl-V><Ctrl-[>/g dan tekan enter (perintah ini sedikit berbeda karena saya harus keluar dari [)
  8. Mengetik 0"yy$ . Perintah sekarang disimpan dalam register y
  9. Atur input pada saluran, dan jalankan dengan @y

Jika seseorang tahu cara yang lebih baik untuk membagikan perintah, beri tahu saya. Saya tahu ini panjang, tapi itu yang terbaik yang bisa saya lakukan.

Input output

String input harus sendiri pada baris apa pun dalam file. 1 0 0 4 3 0 0 0 7

Outputnya hanya akan menimpa string input 1 2 3 4 3 4 5 6 7

Penjelasan

Algoritma

  1. Mulai dari angka yang bukan nol, pastikan itu bukan angka terakhir
  2. Temukan nomor bukan nol berikutnya
  3. Ambil perbedaan mereka. Jika jawabannya negatif, Anda harus mengurangi perbaikan kisaran, jika tidak, kenaikan untuk memperbaiki kisaran.
  4. Kembali ke karakter pertama dan ganti setiap nol dengan menambah / mengurangi angka sebelumnya.
  5. Ulangi sampai Anda mencapai karakter terakhir

Macro Digunakan

@ e - Periksa akhir. Nomor terakhir akan memiliki e ditambahkan ke dalamnya. Jika angka di bawah kursor memiliki e di bagian akhir, hapus e dan hentikan eksekusi. Jika tidak, mulailah siklus interpolasi dengan @b.

mbyiwo^R"Exe@b^[0fel"ty2ldd`b@t

@b - Mulai siklus interpolasi. Simpan angka di bawah kursor untuk operasi pengurangan (@s) dan kemudian cari istilah non-nol berikutnya (@f)

mayiwo^R"^V^X ^["sy0dd`a@f

@ s - Menyimpan perintah pengurangan untuk digunakan dalam @d. Itu hanya di (val)^Xmana (val)nomor pada awal langkah interpolasi. Ini diatur oleh perintah @b.

@ f - Temukan istilah bukan nol berikutnya. Tulis nilai saat ini ke register tanpa nama, kemudian tulis @f @ddi baris berikutnya, dan kemudian jalankan @z. Ini akan mengulangi perintah ini jika angkanya nol, dan jalankan @d jika tidak.

wmbyiwo@f @d^[@z

@z - Eksekusi bersyarat jika register tanpa nama adalah 0. Perintah ini mengharapkan dua perintah pada baris baru dalam format command1 command2. Jika register tanpa nama adalah 0, command1dieksekusi, jika command2tidak dieksekusi. Perhatikan bahwa tidak ada perintah yang memiliki spasi di dalamnya.

 IB0 B^R" ^OWB0 ^OA B0^[0*w"tyiWdd`b@t`

@t - Register perintah sementara. Menyimpan berbagai perintah untuk waktu yang singkat sebelum menjalankannya. Digunakan terutama dalam pernyataan if.

@ d - Tentukan arah interpolasi. Kurangi angka pertama dalam urutan dari angka di bawah kursor (menggunakan @s). Jika hasilnya negatif, interpolasi harus menurun sehingga ^ X disimpan ke @a. Kalau tidak, kita harus naik sehingga ^ A disimpan ke @a. Setelah ini disimpan, kembali ke awal siklus interpolasi ini dan jalankan @i untuk benar-benar interpolasi

yiwo^V^X^R"^[0l@sa^V^A-^[0f-"ayhdd`a@i

@a - Menyimpan ^Aatau^X menambah atau mengurangi selama langkah interpolasi. Ini diatur oleh perintah @d.

@ i - Interpolasi. Salin nomor di lokasi saat ini ke @x dan pindah ke nomor berikutnya. Jika angka itu nol, ganti dengan @x dan jalankan @a untuk memodifikasinya naik atau turun, lalu ulangi perintah ini. Jika angkanya bukan nol, kami telah mencapai akhir dari siklus interpolasi ini. Yang baru harus dimulai dengan angka ini sebagai awal, jadi jalankan @e untuk memeriksa akhirnya dan jalankan lagi.

"xyiwwmbyiwocw^V^Rx^V^[@a@i @e^[@z

@x - Register penyimpanan sementara. Digunakan dalam perintah interpolasi (@i)

Memecah penekanan tombol

mbo :Set b mark to current position and open a new line below to write macros
mayiwo^V^R"^V^V^V^X ^V^["sy0dd`a@f ^["bc0 :Write to @b and reset line

yiwo^V^V^V^X^V^R"^V^[0l@sa^V^V^V^A-^V^[0f-"ayhdd`a@i ^["dc0 :Write to @d and reset line

mbyiwo^V^R"Exe@b^V^[0fel"ty2ldd`b@t ^["ec0 :Write to @e and reset line

wmbyiwo@f @d^V^[@z ^["fc0 :Write to @f and reset line

"xyiwwmbyiwocw^V^V^V^Rx^V^V^V^[@a@i @e^V^[@z ^["ic0 :Write to @i and reset line

IB0 B^V^R" ^V^OWB0 ^V^OA B0^V^[0*w"tyiWdd`b@t ^["zd0 :Write to @z and reset line

dd`b :Delete this line and move cursor back to original line

Ae^[ :Append an e to the last number

0@e  :Move to the beginning of the line and run
Dominic A.
sumber
0

Python 3.5, 159 byte

solusi rekursif

def f(s):
 h=s[0]
 g=lambda s,h,v:h*(h[-1]==s[0])if len(s)==1else(g(s[1:],h+[h[-1]-v],-v)+g(s[1:],h+[h[-1]+v],+v))*(s[0]==0 or h[-1]==s[0])
 return g(s,[h],1)

Tidak disatukan

def f(s):
    h=s[0]
    def g(s,h,v):
        if len(s)==1:
            if h[-1]!=s[0]:
                r=[]
            else:
                r=h
        else:
            if s[0]==0:
                r=g(s[1:],h+[h[-1]+v],v)
            elif h[-1]!=s[0]:
                r=[]
            else:
                r=g(s[1:],h+[h[-1]-v],-v)+g(s[1:],h+[h[-1]+v],+v)
        return r
return g(s,[h],1)

Dalam solusi golf, saya mengganti kondisi dengan menggunakan fakta itu h*True=hdanh*False=[]

Hasil

>>> f([7, 6, 0, 0, 3, 0, 0, 0, 7, 0, 5])
[7, 6, 5, 4, 3, 4, 5, 6, 7, 6, 5]
Erwan
sumber
0

Perl 6 , 54 byte

{$_=$^a;1 while s/:s(\d+) 0 + (\d+)/{+~$0...+~$1}/;$_}
seseorang
sumber
0

MATLAB, 39 38 37 byte

@(a)interp1(find(a),a(a>0),find(a/0))

Fungsi anonim yang diinterpolasi secara linear antara titik-titik di a. find(a)adalah array indeks elemen bukan nol adan a(a>0)merupakan nilai positif. Disimpan 1 byte berkat saran teman >daripada ~=.

MattWH
sumber