Aralıkları onar


30

Bazıları ile değiştirilen pozitif tamsayıların bir listesinin girişi göz önüne alındığında, listeyi yerine değiştirilen 0eksik sayılarla 0çıkarın.

Giriş listesinin özellikleri:

  • Liste her zaman en az 2 uzunluğunda olacaktır.

  • Girdi listesini a"orijinal liste" (yani, sayılar 0s ile değiştirilmeden önceki liste ) olarak tanımlayalım b. Herhangi biri için n, a[n]ya b[n]da 0.

  • Herhangi biri için n, b[n]ya b[n-1] + 1da b[n-1] - 1. Yani, içindeki sayılar her dizinde öncekinden bdaima değişecektir 1. İlk öğe, elbette, bu kuraldan muaftır.

  • İçerisinde sıfır her çalışma için aek ile değiştirilebilir (birbirini takip eden unsurlar 0ile) xişleminin başlangıcında indeksini temsil eden y ucunu temsil eden, a[x-1]için a[y+1]her zaman ya da sadece azalan sadece arttırılması ya da olacaktır. Bu nedenle, sıfırları doldurmanın sadece bir yolu olacaktır.

    • Bu aynı zamanda dizinin ilk veya son elemanının sıfır olamayacağı anlamına gelir.

Daha basit bir ifadeyle, sıfır sırasını doldurmak için, onu önceki sayıdan sonraki sayıya kadar olan bir aralık ile değiştirmeniz yeterlidir. Örneğin, bir giriş

1 2 0 0 0 6 7

çıktı gerekir

1 2 3 4 5 6 7

Bu olduğundan, bayttaki en kısa kod kazanır.

Test durumları:

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

0Programımız yerine başka bir değer alabilir nullmiyiz?
Downgoat

@Downgoat Hayır, eksik numaralar olarak verilmelidir 0.
Doorknob

Yanıtlar:


15

JavaScript (ES6), 72 66 64 54 53 bayt

@Neil sayesinde 12 bayt kaydedildi!

@IsmaelMiguel sayesinde 1 bayt kaydedildi

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

JavaScript için oldukça iyi.


Çevrimiçi deneyin (tüm tarayıcılar çalışır)

açıklama

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`

1
Sanırım bu a.find((q,r)=>r>i&&q)>b?++b:--baynıb+=a.find((q,r)=>r>i&&q)>b||-1
Ismael Miguel

@IsmaelMiguel bu akıllı, teşekkürler!
Downgoat

Rica ederim. Senin için işe yaradığı için memnunum.
Ismael Miguel,

Ben sadece && ile değiştirebileceğinizi düşünüyorum. (Cevapta bir tane ve açıklamada iki tane olduğunu farkettim)
Charlie Wynn

7

Matl , 11 12 bayt

fGXzGn:3$Yn

Dilin / derleyicinin şu anki sürümü (13.0.0) ile çalışır .

Çevrimiçi deneyin!

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 (*)

7

Haskell, 68 61 58 bayt

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

Kullanım örneği: 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].

Nasıl çalışır: girişten sıfırları kaldırın, sonra arayın g. Let a, birinci ve olmak bkalan listenin daha sonra ikinci eleman. Listeleri ayukarıdan aşağıya b-1ve aaşağıdan b+1(bir tanesi boş olacak) ve abırakılan bir tekrarlamalı arama ile birleştirin .

Düzenleme: @ Zgarb 3 bayt kaydetti. Teşekkürler!


6

Mathematica, 59 bayt

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

Test durumu

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

4

Perl, 47 45 44 39 37 bayt

İçin +1 içerir -p

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

Listeyi stdin'de bekliyor. Örnek: echo 1 0 3 0 1 | perl -p dosyası.pl


Burada bazı kopya yapıştırarak görüyorum .. ;-) Güzel btw yapılır.
Kenney,

3

Jöle, 12 11 bayt

ḢWW;ḟ0Ṫr¥\F

Çevrimiçi deneyin!

Alternatif sürüm, 8 bayt (yarışmaz)

Ne yazık ki, Jelly's popbu mücadeleden önce çıkan en son sürümde yinelenebilir hale gelmedi. Bu sorun giderildi ve aşağıdaki sürüm geçerli sürümde çalışıyor.

ḟ0Ṫr¥\FḊ

Çevrimiçi deneyin!

Nasıl çalışır

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

Alternatif sürümde, ḢWW;gereksiz hale gelir. Ancak, ilk eleman patlamadan önce yinelenebilir hale getirildiği için aslında değiştirilmez. Final , ilk elemanın kopyasını kaldırır.


3

Retina, 39 34 31 bayt

@Martin sayesinde 3 bayt kaydedildi.

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

Girdiyi alır ve çıktı olarak verir.

Kod, her boş yeri (0) tekrarlayarak doldurur previous_number - 1 + 2 * if_next_nonzero_number_bigger. previous_number - 1olduğu $1ve if_next_nonzero_number_biggerbir $3.

Ondalık G / Ç ile kod, tüm test durumlarında çevrimiçi tercümanda görebildiğiniz sürece 51 bayttır .


Birinciyi, göz alıcıdaki ilk atlamayı bırakarak kaydedebilirsiniz 1.
Martin Ender

@ MartinBüttner Hakkı düzenlendi.
randomra

2

GNU Sed ( execbash kullanarak genişletme ile ), 61

Skor -rseçeneği için +1'i içerir .

:
s/( 0)+ /../
s/\w+..\w+/{&}/
s/.*/bash -c 'echo &'/e
/ 0/b
  • 0S çalışmasını bulun ve değiştirin..
  • {1..4}Yerel uç noktalar için olduğu gibi bash parantezi genişletmesi oluşturmak için uç nokta numaralarının etrafına parantez koyun . Buradaki bas-kül genişlemelerinin güzelliği , üretilen dizinin, başlangıç ​​veya sonun daha büyük olmasına bakılmaksızın, her zaman doğru yönde çalışmasıdır.
  • Kullan eseçeneğini sbu bağ genişlemeyi değerlendirmek için bash seslenmek komuta
  • Başka bir 0s bulunursa, başa dön.

Ideone.


2

Python 2, 195 111 bayt (teşekkürler 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

Giriş: bir [list]inç olmalıdır
Çıkış: [list]in


Bunun için üzgünüm! Sabit. Başınız için teşekkürler.
vageli

Telaşa gerek yok. Güzel çözüm. :) kullanarak 112 bayt var elimizde bu senin aynı yaklaşımı olan, sadece biraz daha golfed. Ayrıca Python'da golf oynamak için bir kaç ipucumuz var .
Alex A.

1

Perl, 85 82 bayt

için +1 içerir -p

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

Listeyi stdin'de bekliyor. Örnek: echo 1 0 3 0 1 | perl -p file.pl.

Bu iç içe geçmiş bir regexp kullanır. Biraz okunabilir:

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.

1

Python 2, 92 88 bayt

(Kaldırılan ara değişken)

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

1

Pyth, 17 bayt

u+G+treGHHfTtQ[hQ

Çalışma şekli:

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)

Başka bir deyişle: sıfırların tümü girişten kaldırılır, ardından her öğe arasına özel bir aralık eklenir. Bu aralık, yalnızca birindeki öğelerdeki sıfır uzunluktur.



1

Vim: 231 Anahtar Komutları

Bir karakterden önceki ^ herhangi bir o karakteri yazarken kontrolü elinizde tutmanız gerektiğini belirtir.

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 

Adımlar böylece bunu da yönetebilirsiniz!

  1. Çizgiyi Vim'e kopyala
  2. Yazıp :s/\^V/<Ctrl-V><Ctrl-V>/genter tuşuna basın (ikisi size mavi bir ^ V vermelidir)
  3. Yazıp :s/\^R/<Ctrl-V><Ctrl-R>/genter tuşuna basın (şimdi mavi ^ Rs görmelisiniz)
  4. Yazın :s/\^X/<Ctrl-V><Ctrl-X>/gve enter tuşuna basın (artık mavi ^ x'ler görmelisiniz)
  5. Yazıp :s/\^O/<Ctrl-V><Ctrl-O>/genter tuşuna basın
  6. Yazıp :s/\^A/<Ctrl-V><Ctrl-A>/genter tuşuna basın
  7. tip :s/\^\[/<Ctrl-V><Ctrl-[>/g enter tuşuna basın (bu komut biraz farklıdır, çünkü ['dan kaçmam gerekiyordu)
  8. tip 0"yy$ . Komut şimdi y kaydında saklanır
  9. Bir satırdaki girişi ayarlayın ve @y

Birisi komutu paylaşmanın daha iyi bir yolunu biliyorsa, lütfen bana bildirin. Bunun uzun olduğunu biliyorum, ama bulabildiğim en iyisi bu.

Giriş çıkış

Giriş dizesi, dosyadaki herhangi bir satırda yalnız olmalıdır. 1 0 0 4 3 0 0 0 7

Çıktı basitçe giriş dizesinin üzerine yazacaktır 1 2 3 4 3 4 5 6 7

açıklama

Algoritma

  1. Sıfır olmayan bir numaradan başlayın, son sayı olmadığından emin olun.
  2. Sıfır olmayan bir sonraki sayıyı bulun
  3. Farklarını al. Cevap negatifse, aralığı tamir etmek için azaltmalısınız, aksi halde aralığı onarmak için artırmalısınız.
  4. İlk karaktere geri dönün ve önceki sayıyı artırarak / azaltarak her sıfırı değiştirin.
  5. Son karaktere ulaşana kadar tekrarla

Kullanılan Makrolar

@ e - Sonu kontrol et. Son sayının kendisine eklenmiş bir e değeri olacaktır. İmlecin altındaki sayının sonunda bir e varsa, e'yi silin ve yürütmeyi durdurun. Aksi takdirde, @b ile bir enterpolasyon döngüsü başlatın.

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

@b - İnterpolasyon döngüsüne başlayın. Çıkarma işlemi (s) için imlecin altındaki numarayı kaydedin ve ardından bir sonraki sıfır olmayan terimi bulun (f)

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

@s - @d içinde kullanılacak çıkarma komutunu saklar. Basitçe (val)^Xnerede(val) interpolasyon adımının başlangıcında sayısıdır. Bu, @b komutu ile ayarlanır.

f - Sıfır olmayan bir sonraki terimi bulun. Geçerli değeri adsız kayıt defterine yazın, ardından bir @f @dsonraki satıra yazın ve sonra @z çalıştırın. Bu, eğer sayı sıfır ise, bu komutu tekrarlar ve eğer değilse @d komutunu çalıştırır.

wmbyiwo@f @d^[@z

@z - Adsız kayıt 0 ise koşullu çalıştır. Bu komut, formattaki yeni bir satırda iki komut bekler command1 command2. Adsız sicil 0 ise command1, yürütülür, aksi takdirde command2yürütülür. Hiçbir komutun içinde boşluk kalmayacağını unutmayın.

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

@t - Geçici komut kaydı. Yürütmeden önce çeşitli komutları kısa bir süre için saklar. Öncelikle if ifadelerinde kullanılır.

@d - İnterpolasyon yönünü belirleyin. Dizideki ilk sayıyı imlecin altındaki sayıdan çıkarır (@s). Sonuç negatifse, enterpolasyon azalmalıdır, böylece ^ X @a olarak kaydedilir. Aksi takdirde, artmalıyız ki ^ A @a'ya kaydedilir. Bu kaydedildikten sonra, bu enterpolat döngüsünün başına geri dönün ve gerçekte enterpolasyon yapmak için @i çalıştırın

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

@a - Mağazalar ya ^Aya^X İnterpolasyon adımında . Bu @d komutu ile ayarlanır.

@i - İnterpolat. Geçerli konumdaki numarayı @x'e kopyalayın ve bir sonraki sayıya geçin. Bu sayı sıfırsa, @x ile değiştirin ve yukarı veya aşağı doğru şekilde değiştirmek için @a komutunu çalıştırın, ardından bu komutu tekrarlayın. Sayı sıfır değilse, bu enterpolasyon döngüsünün sonuna ulaştık. Bu numara ile başlangıç ​​olarak yeni bir numara başlatılmalıdır, bu yüzden sonu kontrol etmek ve tekrar çalıştırmak için @e komutunu çalıştırın.

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

@ x - Geçici depolama kaydı. İnterpolat komutunda kullanılır (@i)

Tuş vuruşlarını yıkmak

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

0

Python 3.5, 159 bayt

özyinelemeli bir çözüm

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)

Ungolfed

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)

Golflü çözümde, koşulları h*True=hveh*False=[]

Sonuç

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


0

MATLAB, 39 38 37 bayt

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

İçindeki noktalar arasında doğrusal olarak enterpolasyon yapan adsız işlev a. find(a)sıfır olmayan elemanları indekslerinin bir dizidir ave a(a>0)pozitif değerler bulunmaktadır. Bir arkadaş önerisi >yerine 1 byte tasarruf ettim ~=.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.