Taşma Korumalı Tampon


23

Arka fon

Programcılar bugünlerde tamponlarını düz tutuyor gibi görünmüyor! Yaygın bir hata kaynağı, arabellek için çok büyük bir dizi dizini kullanmaya çalışıyor. Göreviniz, büyük dizinlerin arabelleğin işleyebileceği bir boyuta indirgendiği bir tampon uygulamaktır. Çünkü herkes için neyin en iyisi olduğuna tam olarak karar verdim, bu tamponu tam özelliklere göre uygulayacaksın.

genel bakış

Öğeler eklendikçe boyut olarak büyüyen yalnızca ekleme arabelleğiniz var. Tampon, sıfır indeksli ve ayrıca şu anki büyüklüğünde modulo indekslenmiştir . Bu meydan okuma için özel kural şudur:

  • Dizinde bir öğe eklemek için i hesaplamak için anlamı j , j = i % buffer.length()ve sonra yeni bir öğe eklemek j listesinde öğe.

Tek özel durum, eğer tampon boşsa, aritmetik modulo sıfır çalışmıyor. Dolayısıyla, eğer tampon şu anda boşsa, yeni madde endeks 0 olacaktır .

Arabellek yalnızca bir öğe içeriyorsa , her zaman 0 öğeden sonra eklersiniz . Bu genel davanın sadece bir örneği.

Arabellek 6 öğe içeriyorsa: [4, 9, 14, 8, 5, 2]ve 15.10 dizine yeni bir öğe eklemeniz istenirse , bunu bulursunuz ve ardından yenisini, sonuçtaki bir arabellek veren 3 dizininden sonra eklersiniz. 15 % 6 == 3108[4, 9, 14, 8, 10, 5, 2]

Sorun

Sıralı pozitif tamsayılar listesine ve bunların ekleneceği pozitif tamsayı indekslerine giren bir işlev veya program yazın.

Boş bir tamponla başlayın ve belirtilen tamsayıları ilgili indekslerdeki tampon belleğe ekleyin.

Belirtilen tüm eklemeler yapıldıktan sonra tamponda bulunan tam sayıların sıralı listesini çıkar.

Bu bir kod golf mücadelesidir, bu yüzden en kısa kod kazanır.

Giriş kuralları

Giriş listelerini uygun gördüğünüz halde alabilirsiniz. Örnekler:

  • Çiftlerin listesi: [ [1,1], [2,4], [3,9], [4,16], [5,25]...]
  • Öğe listesi ve dizin listesi: [1, 2, 3, 4, 5...], [1, 4, 9, 16, 25]
  • düzleşmiş: [1, 1, 2, 4, 3, 9, 4, 16, 5, 25 ...]
  • vb.

Girişin her zaman en az bir öğe ve karşılık gelen dizin içerdiğini varsayabilirsiniz.

Test durumları

Yukarıdaki kareler durumu:

[(1, 1), (2, 4), (3, 9), (4, 16), (5, 25), (6, 36), (7, 49), (8, 64)] -> [1, 2, 8, 7, 6, 5, 4, 3]

Bunları rastgele oluşturdum:

[(11, 9), (13, 14)] -> [11, 13]
[(1, 18), (11, 7), (3, 35), (16, 22)] -> [1, 11, 16, 3]
[(3, 16), (16, 37), (0, 28), (18, 24)] -> [3, 18, 0, 16]
[(7, 26), (8, 20), (11, 39), (1, 23), (17, 27)] -> [7, 8, 11, 1, 17]
[(15, 35), (17, 7), (16, 15), (1, 13), (2, 6), (11, 34)] -> [15, 17, 1, 2, 16, 11]
[(2, 13), (1, 20), (16, 25), (8, 21), (5, 2), (16, 37), (3, 0)] -> [2, 3, 8, 1, 16, 5, 16]
[(6, 20), (15, 15), (12, 26), (10, 27), (17, 13), (7, 18), (4, 16)] -> [6, 10, 17, 12, 7, 4, 15]
[(18, 9), (5, 34), (15, 4), (12, 29), (2, 5), (7, 0), (7, 10), (16, 38)] -> [18, 7, 15, 2, 16, 5, 7, 12]
[(0, 12), (12, 0), (4, 16), (15, 12), (6, 28), (8, 10), (11, 24), (0, 25)] -> [0, 11, 8, 6, 15, 0, 4, 12]
[(6, 12), (14, 13), (10, 33), (11, 35), (1, 3), (0, 28), (15, 27), (8, 10), (1, 2)] -> [6, 14, 10, 1, 11, 8, 15, 0, 1]
[(2, 29), (19, 30), (18, 17), (13, 3), (0, 21), (19, 19), (11, 13), (12, 31), (3, 25)] -> [2, 13, 3, 11, 0, 12, 19, 18, 19]

Python3 referans uygulaması

def f(inputs):
    # `inputs` is a list of pairs
    buff = []
    for item, index in inputs:
        if len(buff) == 0:
            buff.insert(0, item)
        else:
            insert_after = index % len(buff)
            buff.insert(insert_after+1, item)
    return buff

Giriş tersine alınabilir mi?
FlipTack

Evet, girişin istediğiniz kadar esnek ya da daha az olabileceğini düşünüyorum.
türbülanslı

Yanıtlar:


4

MATL , 24 22 bayt

"N?@2)yn\Q:&)@1)wv}@1)

Giriş, ;ilk satırdaki değerleri ve ikinci satırdaki değerleri içeren bir matristir ( satır ayırıcı olarak).

Çıktı, yeni satırlarla ayrılmış sayılar olarak görüntülenen bir sütun dizisidir.

Çevrimiçi deneyin! Veya tüm test durumlarını doğrulayın , her sonuç tek bir satırda gösterildi.

açıklama

"          % Input matrix (implicit). For each column 
  N        %   Number of elements in the stack
  ?        %   If nonzero (true for all iterations but the first)
    @2)    %     Push second element of current column: new index
    yn     %     Duplicate current buffer; push its number of elements
    \      %     Modulo
    Q      %     Add 1
    :&)    %     Split buffer at that point. This gives two pieces, one
           %     of which may be empty
    @1)    %     Push first element of current column: new value
    wv     %     Swap; concatenate all stack. This places the new value
           %     between the two pieces of the buffer
  }        %   Else (this is executed only in the first iteration)
    @1)    %     Push first element of current column: new value
           %   End (implicit)
           % End (implicit)
           % Display (implicit)

8

Perl, 37 bayt

-lpBayraklar için 35 bayt kod + 2 bayt .

splice@F,1+<>%(@F||1),0,$_}{$_="@F"

Çevrimiçi deneyin!

Uygulama oldukça basittir , dizine dizine spliceekler ( dizinin boş olması durumunda geçerlidir).@F1+<>%(@F||1)@F||1

(Görünüşte) eşsiz parantez hakkında sadece birkaç kelime }{(çünkü bu konuda bir yorum vardı ve Perl bilmeyen insanlar için oldukça garip olduğunu düşünüyorum) ve Perl golflerinde oldukça yaygın bir numara:
-pbayrak kodu çevreliyor (kabaca) ile while(<>){ CODE } continue { print }, ( continueher yinelemeden sonra yürütülür). Böylece eşleşmeyenlerle }{ , kodumu değiştiririm while(<>) { CODE}{ } continue { print }. Bu yüzden kodumdan hemen sonra boş bir blok yaratıyor (fakat bu bir problem değil) ve continuesadece (bir kere whiletüm girdilerin okunmasından sonra) sonra bir defa çalıştırılıyor .


3
Bu }{beni deli ediyor ...
ETHproductions

@ETProductions buna alışkınım ama başkalarına göstermeyi çok seviyorum, her zaman bir şeylerin yanlış olduğunu düşünüyorlar! :) (olumsuz taraf benim emacs girinti ile karışıklık ..)
Dada

1
Bu }{bana bu yanılsama
Luis Mendo

Evet yaptım. :-)
Dennis

5

ES6 (Javascript), 58,57,53, 50 bayt

golfed

a=>a.map((e,i)=>b.splice(1+e[1]%i,0,e[0]),b=[])&&b

Girdi olarak bir dizin-değer çiftleri dizisini alır.

DÜZENLEMELER

  • &&Değer, -1 bayt döndürmek için kullanın
  • Kaldırıldı |0(ek yeri görünüşte NaN'i çok iyi idare edebilir), -2 bayt
  • Eşlemek b=[]için ikinci bir "argüman" yaptım () , -2 bayt (Thx @ETHproductions!)
  • B.length, map () index (i), -3 bayt ile değiştirildi (Thx @Patrick Roberts!)

Ölçek

F=a=>a.map((e,i)=>b.splice(1+e[1]%i,0,e[0]),b=[])&&b

F([[11, 9], [13, 14]])
[ 11, 13 ]

F([[2, 29], [19, 30], [18, 17], [13, 3], [0, 21], [19, 19], [11, 13], [12, 31], [3, 25]])
[ 2, 13, 3, 11, 0, 12, 19, 18, 19 ]

1
Güzel, özyinelemeli olmayan yaklaşımları denemeliydim. Yapabileceğini düşünüyoruma=>a.map(e=>...,b=[])&&b
ETHproductions

2
Sen değiştirerek 3 bayt çıkarabilir e=>için (e,i)=>ve kullanma iyerineb.length
Patrick Roberts

@PatrickRoberts Bu güzel bir fikir! Teşekkür ederim !
zeplin

5

Haskell , 70 69 bayt

b!(x,i)|b==[]=[x]|j<-1+i`mod`length b=take j b++x:drop j b
foldl(!)[]

Çevrimiçi deneyin! Kullanımı: foldl(!)[] [(1,5),(2,4),(3,7)]. @Nimi sayesinde bir bayt kaydedildi!

Açıklama:

b!(x,i)                         -- b!(x,i) inserts x into list b at position i+1
 | b==[] = [x]                  -- if b is empty return the list with element x
 | j <- 1 + i `mod` length b    -- otherwise compute the overflow-save insertion index j
     = take j b ++ x : drop j b -- and return the first j elements of b + x + the rest of b
foldl(!)[]                      -- given a list [(1,2),(3,5),...], insert each element with function ! into the initially empty buffer

Modülü hesaplamadan çözüm: (90 bayt)

f h t(x,-1)=h++x:t
f h[]p=f[]h p
f h(c:t)(x,i)=f(h++[c])t(x,i-1)
g((x,_):r)=foldl(f[])[x]r

Çevrimiçi deneyin!


j<-1+i`mod`length bbir bayt kaydeder.
nimi

4

Python 2 , 64 62 58 56 bayt

x=[]
for n,i in input():x[i%(len(x)or 1)+1:0]=n,
print x

2 baytlık golf oynamak için @xnor'a teşekkürler!

Çevrimiçi deneyin!


(len(x)or 1)Uzunluğu başlatmak yerine yapabilir misin ?
xnor

Daha kısa bir yol arıyorum. Her ikisi de len(x or[0])ve -~len(x[1:])kravat.
Xnor

4

Python 2 , 62 60 bayt

Girişleri çiftler listesi olarak alır, sonucu basar. Düzenleme: Dennis tarafından Outgolfed

b=[]
for x,y in input():b.insert(1+y%(len(b)or 1),x)
print b

Çevrimiçi deneyin!

Bu oldukça basittir - girdiyi dolaştırın, öğeleri doğru yere yerleştirin ve sonucu yazdırın. Hangi dizinin ekleneceğine karar verilir 1+y%(len(b)or 1). Bu, or 1boş bir listenin kenar durumuyla başa çıkmak için modüler indekslemenin standart yoludur .


3

JavaScript (ES6), 60 bayt

f=([[q,r],...a],z=[])=>z.splice(r%z.length+1,0,q)+a?f(a,z):z

Test pasajı


2

V , 38 40 35 bayt

Bu cevap listenin tanımını büker ve normalde liste manipülasyon için kullanmak istiyorum bir dil değildir, ancak kullanmak istedi [count]/{regex}Geçenlerde girdi gibi alınır V. eklenen [index] [num] [index] [num] ...ve benzeri döndü [num] [num] [num].

Í ¨ä«© ½/¯ÜdÜ+òhea ±^
Hdd2xdG@"
X

Çevrimiçi deneyin!

2 gizli karakter için Hexdump:

00000000: cd20 a8e4 aba9 20bd 2faf dc64 dc2b f268  . .... ./..d.+.h
00000010: 6561 20b1 161b 5e0a 4864 6432 7864 4740  ea ...^.Hdd2xdG@
00000020: 220a 58                                  ".X

açıklama

dG@"Tüm \d+ \d+çiftleri biçimlendiren kod, böylece bir liste 1 2 3 4 5 6 gibi bitecek

a 2^[^3/\d\+
hea 4^[^5/\d\+
hea 6^[^

ve sonra bunların dG@"hepsini V kodu gibi çalıştırır:

a 2^[                 | insert " 2" and return to command mode
     ^                | LOOP: go to the first number
      3/\d\+          | find the 3rd number (0 indexed)
h                     | move one character left
 e                    | go to the end of the next word
  a 4^[               | append " 4" and return to command mode
       ^5/\d\+        | basically the same as LOOP on, just with different numbers


Ah, teşekkürler bunu bilmiyordun. Uygun hale getireceğim
nmjcman101

2

PHP, 72 92 bayt

for($b=[];++$i<$argc;)array_splice($b,$b?$argv[$i]%count($b)+1:0,0,$argv[++$i]);print_r($b);

komut satırı argümanlarından düzleştirilmiş girdiyi alır. İle koş -nr.


Bu cevabın geçersiz olduğuna oldukça eminim: bir fikrim var Fatal error: Uncaught DivisionByZeroError: Modulo by zero, düzelttim, sonra denedim 1 1 1 2 1 3ve çıktı [1=>null]olarak aldım[1,3,2]
user59178

Hala j+1sonra eklemek yerine, üzerine yazar j? 18 1 7 11 35 3 22 16=> [1,11,16]yerine[1,11,16,3]
user59178

@ user59178: insertAnahtar kelimeyi kaçırdım . Teşekkürler; sabit.
Titus

2

Java 7, 125 124 bayt

import java.util.*;List z(int[]a){List r=new Stack();for(int i=0,q=a.length/2;i<q;)r.add(i<1?0:a[i+q]%i+1,a[i++]);return r;}

İndekslerin takip ettiği düz bir değerler listesini kabul eder. Kareler test durumu için girişnew int[] {1, 2, 3, 4, 5, 6, 7, 8, 1, 4, 9, 16, 25, 36, 49, 64}

Çevrimiçi deneyin!


1

Mathematica, 62 bayt

Fold[Insert[#,#2[[1]],Mod[Last@#2,Tr[1^#]]+2/.0/0->-1]&,{},#]&

İlk argüman olan saf fonksiyon #çiftlerin listesi olması bekleniyor. Boş bir listeyle başlayarak {}, sol Foldgirdi listesi #aşağıdaki fonksiyonu ile:

Insert[                                            Insert
       #,                                          into the first argument
         #2[[1]],                                  the first element of the second argument
                 Mod[                              at the position given by the modulus of
                     Last@#2,                      the second element of the second argument
                             Tr[1^#]               with respect to the length of the first argument
                                    ]+2            plus 2 (plus 1 to account for 1-indexing, plus 1 because we are inserting after that position)
                                       /.          then replace
                                         0/0       Indeterminate
                                            ->     with
                                              -1   negative 1
                                                ]& End of function

1

Perl 6 , 51 bayt

{my @a;.map:{splice @a,(@a??$^b%@a+1!!0),0,$^a};@a}

Düzleştirilmiş girişi alır.


1

Clojure, 87 bayt

#(reduce(fn[r[v i]](let[[b e](split-at(+(mod i(max(count r)1))1)r)](concat b[v]e)))[]%)
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.