Buffer a prova di troppo pieno


23

sfondo

Al giorno d'oggi i programmatori non riescono a mantenere dritti i loro buffer! Una fonte comune di errore sta tentando di utilizzare un indice di array troppo grande per il buffer. Il tuo compito è implementare un buffer in cui indici di grandi dimensioni sono ridotti a una dimensione gestibile dal buffer. Poiché decido esattamente ciò che è meglio per tutti, implementerai questo buffer secondo le mie specifiche precise.

Panoramica

Hai un buffer di solo inserimento che aumenta di dimensioni man mano che gli elementi vengono aggiunti ad esso. Il buffer è a zero, e anche a modulo indicizzato la sua dimensione attuale. La regola speciale per questa sfida è questa:

  • Per inserire un elemento di indice i mezzi per calcolare j , j = i % buffer.length()e inserire il nuovo elemento dopo il j-esimo elemento della lista.

L'unico caso speciale è se il buffer è vuoto, poiché il modulo zero aritmetico non funziona. Pertanto, se il buffer è attualmente vuoto, il nuovo elemento sarà indice 0 .

Se il buffer ha un solo elemento, allora si inserisce sempre dopo il 0 ° elemento. Questa è solo un'istanza del caso generale.

Se il buffer contiene 6 elementi: [4, 9, 14, 8, 5, 2]e ti viene chiesto di inserire un nuovo elemento 10nell'indice 15 , lo trovi 15 % 6 == 3, quindi inserisci il nuovo 10dopo l' 8indice 3 che fornisce un buffer risultante di [4, 9, 14, 8, 10, 5, 2]

Problema

Scrivi una funzione o un programma che includa un elenco ordinato di numeri interi positivi e indici interi positivi in ​​cui inserirli.

Inizia con un buffer vuoto e aggiungi gli interi specificati al buffer negli indici corrispondenti.

Emette l'elenco ordinato di numeri interi che si trovano nel buffer dopo aver effettuato tutti gli inserimenti specificati.

Questa è una sfida di code-golf, quindi vince il codice più corto.

Linee guida di input

Puoi prendere le liste di input come preferisci. Esempi:

  • Elenco di coppie: [ [1,1], [2,4], [3,9], [4,16], [5,25]...]
  • Elenco articoli ed elenco indice: [1, 2, 3, 4, 5...], [1, 4, 9, 16, 25]
  • appiattito: [1, 1, 2, 4, 3, 9, 4, 16, 5, 25 ...]
  • eccetera.

Si può presumere che l'input contenga sempre almeno un elemento e un indice corrispondente.

Casi test

Caso quadrati dall'alto:

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

Ho generato questi in modo casuale:

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

Implementazione di riferimento di 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

L'ingresso può essere preso al contrario?
FlipTack

Sì, penso che l'input possa essere più o meno flessibile come desideri.
turbulencetoo

Risposte:


4

MATL , 24 22 byte

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

L'input è una matrice (con ;come separatore di riga) contenente i valori nella prima riga e gli indici nella seconda.

L'output è un array di colonne, visualizzato come numeri separati da newline.

Provalo online! Oppure verifica tutti i casi di test , con ogni risultato visualizzato su una sola riga.

Spiegazione

"          % 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 byte

35 byte di codice + 2 byte per i -lpflag.

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

Provalo online!

L'implementazione è piuttosto semplice, si spliceinserisce in array @Fall'indice 1+<>%(@F||1)(si noti che@F||1 gestisce il caso dell'array essendo vuoto).

Solo poche parole sulle parentesi graffe (apparentemente) senza pari }{(perché avevo un commento a riguardo, e penso che sia abbastanza strano per le persone che non conoscono il Perl), ed è un trucco abbastanza comune nei golf del Perl: la
-pbandiera circonda il codice con (approssimativamente) while(<>){ CODE } continue { print }, ( continueviene eseguito dopo ogni iterazione). Quindi, con quelli senza eguali }{ , cambio il mio codice in while(<>) { CODE}{ } continue { print }. Quindi crea un blocco vuoto subito dopo il mio codice (ma questo non è un problema), e continueviene eseguito solo una volta, dopo il while(cioè quando è stato letto tutto l'input).


3
Questo }{mi sta facendo impazzire ...
ETHproductions

@ETHproductions Ci sono abituato ma amo mostrarlo ad altre persone, pensano sempre che qualcosa non vada! :) (il rovescio della medaglia è che è in disordine con il mio rientro di emacs ..)
Dada

1
Questo }{mi ricorda questa illusione
Luis Mendo il

Si l'ho fatto. :-)
Dennis,

5

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

golfed

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

Accetta una matrice di coppie indice-valore, come input.

EDITS

  • Utilizzare &&per restituire un valore, -1 byte
  • Rimosso |0(poiché pare che la giunzione sia in grado di gestire bene NaN), -2 byte
  • Fatto b=[] un secondo "argomento" per mappare () , -2 byte (Thx @ETHproductions!)
  • Sostituito b.length con map () index (i), -3 byte (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 ]

1
Bene, avrei dovuto provare approcci non ricorsivi. Penso che tu possa farea=>a.map(e=>...,b=[])&&b
ETHproductions

2
È possibile sottrarre 3 byte cambiando e=>a (e,i)=>ed usando ial posto dib.length
Patrick Roberts

@PatrickRoberts È una bella idea! Grazie !
Zeppelin,

5

Haskell , 70 69 byte

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

Provalo online! Uso: foldl(!)[] [(1,5),(2,4),(3,7)]. Salvato un byte grazie a @nimi!

Spiegazione:

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

Soluzione senza calcolare il modulo: (90 byte)

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

Provalo online!


j<-1+i`mod`length bsalva un byte.
nimi,

4

Python 2 , 64 62 58 56 byte

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

Grazie a @xnor per giocare a golf con 2 byte!

Provalo online!


Puoi fare (len(x)or 1)invece di inizializzare la lunghezza?
xnor

Alla ricerca di un modo più breve. Entrambi len(x or[0])e -~len(x[1:])pareggio.
xnor

4

Python 2 , 62 60 byte

Prende l'input come un elenco di coppie, stampa il risultato. Modifica: superato da Dennis

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

Provalo online!

Questo è abbastanza semplice: fai scorrere l'input, inserendo gli elementi nella posizione corretta, quindi stampa il risultato. Decidere con quale indice inserire 1+y%(len(b)or 1). Questo è il modo standard per eseguire l'indicizzazione modulare, con la or 1gestione del caso limite di un elenco vuoto.


3

JavaScript (ES6), 60 byte

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

Test snippet


2

V , 38 40 35 byte

Questa risposta piega la definizione di lista, e normalmente non è una lingua che useresti per manipolare la lista, ma volevo usare quella [count]/{regex}che ho recentemente aggiunto a V. L'input è preso come [index] [num] [index] [num] ...e restituito come [num] [num] [num].

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

Provalo online!

Hexdump per 2 personaggi nascosti:

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

Spiegazione

Il codice fino a dG@"formattare tutte le \d+ \d+coppie in modo che un elenco 1 2 3 4 5 6 finisca come

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

e quindi dG@"esegue tutto ciò come codice V come il seguente:

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, grazie non lo sapevi. Lo renderò conforme
nmjcman101,

2

PHP, 72 92 byte

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

accetta input appiattiti dagli argomenti della riga di comando. Corri con -nr.


Sono abbastanza sicuro che questa risposta non sia valida: ho ottenuto un Fatal error: Uncaught DivisionByZeroError: Modulo by zero, risolto quello, quindi 1 1 1 2 1 3ho provato e ottenuto [1=>null]come output invece di[1,3,2]
user59178

Sovrascrive ancora j+1anziché inserire dopo j, no? 18 1 7 11 35 3 22 16=> [1,11,16]anziché[1,11,16,3]
user59178

@ user59178: Oh, mi ero perso la insertparola chiave. Grazie; fisso.
Tito

2

Java 7, 125 124 byte

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

Accetta un elenco semplice di valori seguito da indici. Per il caso di test dei quadrati l'input sarebbenew int[] {1, 2, 3, 4, 5, 6, 7, 8, 1, 4, 9, 16, 25, 36, 49, 64}

Provalo online!


1

Mathematica, 62 byte

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

La pura funzione con il primo argomento #dovrebbe essere un elenco di coppie. A partire dall'elenco vuoto {}, ha lasciato Foldl'elenco di input #con la seguente funzione:

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 byte

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

Accetta l'input appiattito.


1

Clojure, 87 byte

#(reduce(fn[r[v i]](let[[b e](split-at(+(mod i(max(count r)1))1)r)](concat b[v]e)))[]%)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.