Bufor odporny na przepełnienie

23

tło

Programiści w dzisiejszych czasach nie wydają się utrzymywać prostych buforów! Częstym źródłem błędu jest próba użycia indeksu tablicy, który jest zbyt duży dla bufora. Twoim zadaniem jest zaimplementowanie bufora, w którym duże indeksy zostaną zredukowane do rozmiaru, który bufor może obsłużyć. Ponieważ dokładnie decyduję, co jest najlepsze dla wszystkich, zaimplementujesz ten bufor zgodnie z moimi dokładnymi specyfikacjami.

Przegląd

Masz bufor tylko wstawiany, który powiększa się wraz z dodawaniem elementów. Bufor jest indeksowany zerowo, a także indeksuje modulo jego bieżący rozmiar. Specjalną zasadą dla tego wyzwania jest:

  • Aby wstawić element o indeksie i środki, aby obliczyć j , j = i % buffer.length()i wstawić nowy element po j pozycji na liście.

Jedynym szczególnym przypadkiem jest to, że bufor jest pusty, ponieważ moduł arytmetyczny zero nie działa. Tak więc, jeśli bufor jest obecnie pusty, nowy element będzie miał indeks 0 .

Jeśli bufor ma tylko jeden element, to zawsze po włożeniu 0th elementu. To tylko jeden przykład ogólnego przypadku.

Jeśli bufor zawiera 6 elementów: [4, 9, 14, 8, 5, 2]i powiedziano ci, aby wstawić nowy element 10o indeksie 15 , znajdziesz go 15 % 6 == 3, a następnie wstaw nowy 10po 8indeksie 3, co daje wynikowy bufor o wartości [4, 9, 14, 8, 10, 5, 2]

Problem

Napisz funkcję lub program, który pobierze uporządkowaną listę dodatnich liczb całkowitych i dodatnich wskaźników liczb całkowitych, w których je wstawisz.

Zacznij od pustego bufora i dodaj określone liczby całkowite do bufora przy odpowiednich indeksach.

Wyprowadza uporządkowaną listę liczb całkowitych znajdujących się w buforze po wykonaniu wszystkich określonych wstawek.

To wyzwanie dla golfa, więc wygrywa najkrótszy kod.

Wskazówki dotyczące wprowadzania danych

Możesz wziąć listy danych wejściowych, jeśli uznasz to za stosowne. Przykłady:

  • Lista par: [ [1,1], [2,4], [3,9], [4,16], [5,25]...]
  • Lista artykułów i lista indeksów: [1, 2, 3, 4, 5...], [1, 4, 9, 16, 25]
  • Spłaszczony: [1, 1, 2, 4, 3, 9, 4, 16, 5, 25 ...]
  • itp.

Możesz założyć, że dane wejściowe zawsze zawierają co najmniej jeden element i odpowiedni indeks.

Przypadki testowe

Kwadratowa obudowa od góry:

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

Wygenerowałem je losowo:

[(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]

Implementacja referencji Python3

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
turbulencetoo
źródło
Czy dane wejściowe można pobierać w odwrotnej kolejności?
FlipTack,
Tak, myślę, że dane wejściowe mogą być mniej więcej tak elastyczne, jak chcesz.
turbulencetoo

Odpowiedzi:

4

MATL , 24 22 bajtów

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

Dane wejściowe to macierz (z ;separatorem wierszy) zawierająca wartości w pierwszym rzędzie i indeksy w drugim.

Dane wyjściowe to tablica kolumn wyświetlana jako liczby oddzielone znakami nowej linii.

Wypróbuj online! Lub sprawdź wszystkie przypadki testowe , z każdym wynikiem wyświetlanym w jednym wierszu.

Wyjaśnienie

"          % 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)
Luis Mendo
źródło
8

Perl, 37 bajtów

35 bajtów kodu + 2 bajty na -lpflagi.

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

Wypróbuj online!

Implementacja jest dość prosta, splicewstawia tablicę @Fdo indeksu 1+<>%(@F||1)(pamiętaj, że @F||1obsługuje przypadek pustej tablicy).

Kilka słów o (pozornie) niedopasowanych nawiasach klamrowych }{(ponieważ miałem na ten temat komentarz i myślę, że jest to dość dziwne dla ludzi, którzy nie znają Perla) i jest to dość powszechna sztuczka w golfie w Perlu:
-pflaga otacza kod z (z grubsza) while(<>){ CODE } continue { print }, ( continuejest wykonywany po każdej iteracji). Więc z tymi nieporównywalnymi }{ zmieniam kod na while(<>) { CODE}{ } continue { print }. Tworzy więc pusty blok zaraz po moim kodzie (ale to nie jest problem) i continuejest wykonywany tylko raz, po while(tj. Kiedy wszystkie dane wejściowe zostały odczytane).

Dada
źródło
3
To }{doprowadza mnie do szału ...
ETHprodukcje
@ETHproductions Jestem do tego przyzwyczajony, ale uwielbiam pokazywać to innym ludziom, zawsze myślą, że coś jest nie tak! :) (minusem jest to, że jest bałagan z moim wcięciem Emacsa ..)
Dada
1
To }{mi przypomina tę iluzję
Luis Mendo,
Tak. :-)
Dennis
5

ES6 (JavaScript), 58,57,53, 50 bajtów

Grał w golfa

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

Pobiera tablicę par indeks-wartość jako dane wejściowe.

EDYCJE

  • Posługiwać się && do zwracania wartości, -1 bajt
  • Usunięto |0(ponieważ najwyraźniej splot dobrze radzi sobie z NaN), -2 bajty
  • Zrobił b=[]drugi „argument” dla map () , -2 bajtów (Thx @ETHproductions!)
  • Zamieniono b. Długość na map () indeks (i), -3 bajtów (Thx @Patrick Roberts!)

Test

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 ]
zepelin
źródło
1
Fajnie, powinienem był spróbować podejść nierekurencyjnych. Myślę, że dasz radęa=>a.map(e=>...,b=[])&&b
ETHprodukcje
2
Można odjąć 3 bajty zmieniając e=>się (e,i)=>i używając izamiastb.length
Patrick Roberts
@PatrickRoberts To niezły pomysł! Dziękuję Ci !
zeppelin
5

Haskell , 70 69 bajtów

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

Wypróbuj online! Zastosowanie: foldl(!)[] [(1,5),(2,4),(3,7)]. Zapisano jeden bajt dzięki @nimi!

Wyjaśnienie:

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

Rozwiązanie bez obliczania modułu: (90 bajtów)

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

Wypróbuj online!

Laikoni
źródło
j<-1+i`mod`length bzapisuje bajt.
nimi
4

Python 2 , 64 62 58 56 bajtów

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

Dzięki @xnor za grę w golfa z 2 bajtów!

Wypróbuj online!

Dennis
źródło
Czy możesz to zrobić (len(x)or 1)zamiast inicjowania długości?
xnor
Poszukuję krótszej drogi. Zarówno len(x or[0])i -~len(x[1:])remis.
xnor
4

Python 2 , 62 60 bajtów

Pobiera dane wejściowe jako listę par, drukuje wynik. Edycja: Outgolfed by Dennis

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

Wypróbuj online!

Jest to dość proste - wykonaj pętlę przez dane wejściowe, wstawiając elementy we właściwe miejsce, a następnie wydrukuj wynik. Podejmowanie decyzji, do którego indeksu należy wstawić 1+y%(len(b)or 1). Jest to standardowy sposób przeprowadzania indeksowania modułowego z or 1obsługą przypadku na krawędzi pustej listy.

FlipTack
źródło
3

JavaScript (ES6), 60 bajtów

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

Testowy fragment kodu

ETHprodukcje
źródło
2

V , 38 40 35 bajtów

Ta odpowiedź zagina definicję listy i zwykle nie jest językiem używanym do manipulowania listami, ale chciałem użyć tego, [count]/{regex}który niedawno dodałem do V. Dane wejściowe są pobierane jak [index] [num] [index] [num] ...i zwracane jak [num] [num] [num].

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

Wypróbuj online!

Hexdump dla 2 ukrytych postaci:

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

Wyjaśnienie

Kod do dG@"formatuje wszystkie \d+ \d+pary, aby lista 1 2 3 4 5 6 wyglądała podobnie

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

a następnie dG@"wykonuje to wszystko jako kod V, jak poniżej:

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
nmjcman101
źródło
Mówiąc wprost, status niekonkurujący dotyczy tylko języków lub funkcji językowych nowszych niż wyzwanie
Kritixi Lithos
Ach, dziękuję, że o tym nie wiedziałeś.
Sprawię,
2

PHP, 72 92 bajty

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

przyjmuje dane spłaszczone z argumentów wiersza poleceń. Uruchom z -nr.

Tytus
źródło
Jestem całkiem pewien, że ta odpowiedź jest nieprawidłowa: mam Fatal error: Uncaught DivisionByZeroError: Modulo by zero, naprawiłem to, a następnie próbowałem 1 1 1 2 1 3i otrzymałem [1=>null]jako dane wyjściowe zamiast[1,3,2]
user59178
Nadal zastępuje j+1zamiast wstawiać po j, nie? 18 1 7 11 35 3 22 16=> [1,11,16]zamiast[1,11,16,3]
user59178
@ user59178: Oh, przegapiłem insertsłowo kluczowe. Dzięki; naprawiony.
Tytus
2

Java 7, 125 124 bajty

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

Akceptuje płaską listę wartości oraz indeksy. W przypadku testu kwadratów dane wejściowe byłybynew int[] {1, 2, 3, 4, 5, 6, 7, 8, 1, 4, 9, 16, 25, 36, 49, 64}

Wypróbuj online!

Szturchać
źródło
1

Mathematica, 62 bajty

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

Czysta funkcja z pierwszym argumentem #powinna być listą par. Zaczynając od pustej listy {}, opuścił Foldlistę wejść #z następującą funkcją:

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
ngenisis
źródło
1

Perl 6 , 51 bajtów

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

Pobiera spłaszczone wejście.

smls
źródło
1

Clojure, 87 bajtów

#(reduce(fn[r[v i]](let[[b e](split-at(+(mod i(max(count r)1))1)r)](concat b[v]e)))[]%)
NikoNyrh
źródło