Tampón a prueba de desbordamiento

23

Fondo

¡Los programadores en estos días parecen no poder mantener sus buffers rectos! Una fuente común de error es intentar usar un índice de matriz que es demasiado grande para el búfer. Su tarea es implementar un búfer donde los índices grandes se reduzcan a un tamaño que el búfer pueda manejar. Como decido exactamente qué es lo mejor para todos, implementará este búfer según mis especificaciones precisas.

Visión general

Tiene un búfer de solo inserción que crece en tamaño a medida que se le agregan elementos. El tampón es cero indexados, y también indexados modulo su tamaño actual. La regla especial para este desafío es esta:

  • Para insertar un elemento en el índice i medio para calcular j , j = i % buffer.length()e insertar el nuevo elemento después de que el j-ésimo elemento de la lista.

El único caso especial es si el búfer está vacío, ya que el módulo aritmético cero no funciona. Por lo tanto, si el búfer está actualmente vacío, el nuevo elemento será el índice 0 .

Si el búfer tiene solo un elemento, siempre está insertando después del elemento 0 . Esta es solo una instancia del caso general.

Si el búfer contiene 6 elementos: [4, 9, 14, 8, 5, 2]y se le indica que inserte un nuevo ítem 10en el índice 15 , lo encuentra 15 % 6 == 3y luego inserta el nuevo 10después del 8índice 3, lo que da un búfer resultante de [4, 9, 14, 8, 10, 5, 2]

Problema

Escriba una función o programa que tome una lista ordenada de enteros positivos e índices de enteros positivos en los que insertarlos.

Comience con un búfer vacío y agregue los enteros especificados al búfer en los índices correspondientes.

Salida de la lista ordenada de enteros que están en el búfer después de que se hayan realizado todas las inserciones especificadas.

Este es un desafío de código de golf, por lo que gana el código más corto.

Pautas de entrada

Puede tomar las listas de entrada como mejor le parezca. Ejemplos:

  • Lista de pares: [ [1,1], [2,4], [3,9], [4,16], [5,25]...]
  • Lista de artículos y lista de índice: [1, 2, 3, 4, 5...], [1, 4, 9, 16, 25]
  • Aplanado: [1, 1, 2, 4, 3, 9, 4, 16, 5, 25 ...]
  • etc.

Puede suponer que la entrada siempre contiene al menos un elemento y el índice correspondiente.

Casos de prueba

Caja de cuadrados desde arriba:

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

Los generé al azar:

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

Implementación de referencia de 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
turbulencia también
fuente
¿Se puede tomar la entrada en reversa?
FlipTack
Sí, creo que la entrada puede ser más o menos tan flexible como quieras.
turbulencetoo

Respuestas:

4

MATL , 24 22 bytes

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

La entrada es una matriz (con un ;separador de fila) que contiene los valores en la primera fila y los índices en la segunda.

La salida es una matriz de columnas, que se muestra como números separados por nuevas líneas.

Pruébalo en línea! O verifique todos los casos de prueba , con cada resultado mostrado en una sola línea.

Explicación

"          % 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
fuente
8

Perl, 37 bytes

35 bytes de código + 2 bytes para -lpbanderas.

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

Pruébalo en línea!

La implementación es bastante sencilla, se spliceinserta en la matriz @Fen el índice1+<>%(@F||1) (tenga en cuenta que @F||1maneja el caso de que la matriz esté vacía).

Solo unas pocas palabras sobre las llaves (aparentemente) inigualables }{(porque tenía un comentario al respecto, y creo que es bastante extraño para las personas que no conocen a Perl), y es un truco bastante común en los juegos de golf de Perl: la
-pbandera rodea el código con (aproximadamente) while(<>){ CODE } continue { print }, (el continuese ejecuta después de cada iteración). Entonces, con esos incomparables }{ , cambio mi código a while(<>) { CODE}{ } continue { print }. Por lo tanto, crea un bloque vacío justo después de mi código (pero eso no es un problema), y continuese ejecuta solo una vez, después de while(es decir, cuando se ha leído toda la entrada).

Dada
fuente
3
Eso }{me está volviendo loco ...
ETHproductions
@ETHproductions Estoy acostumbrado, pero me encanta mostrárselo a otras personas, ¡siempre piensan que algo está mal! :) (La desventaja es que se mete con mi sangría emacs ..)
Dada
1
Eso }{me recuerda a esta ilusión
Luis Mendo
Sí, lo hice. :-)
Dennis
5

ES6 (Javascript), 58,57,5350 bytes

Golfed

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

Toma una matriz de pares índice-valor, como entrada.

EDICIONES

  • Use &&para devolver el valor, -1 byte
  • Eliminado |0(ya que aparentemente el empalme puede manejar NaN bien), -2 bytes
  • Hizo b=[]un segundo "argumento" para map () , -2 bytes (Thx @ETHproductions!)
  • Se reemplazó b.length con map () index (i), -3 bytes (Thx @Patrick Roberts!)

Prueba

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 ]
zepelín
fuente
1
Bien, debería haber intentado enfoques no recursivos. Creo que puedes hacerloa=>a.map(e=>...,b=[])&&b
ETHproductions
2
Puede restar 3 bytes cambiando e=>a (e,i)=>y utilizar ien lugar deb.length
Patrick Roberts
@PatrickRoberts ¡Esa es una buena idea! Gracias !
zepelín
5

Haskell , 70 69 bytes

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

Pruébalo en línea! Uso: foldl(!)[] [(1,5),(2,4),(3,7)]. ¡Guardado un byte gracias a @nimi!

Explicación:

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

Solución sin calcular el módulo: (90 bytes)

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

Pruébalo en línea!

Laikoni
fuente
j<-1+i`mod`length bGuarda un byte.
nimi
4

Python 2 , 64 62 58 56 bytes

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

¡Gracias a @xnor por jugar 2 bytes!

Pruébalo en línea!

Dennis
fuente
¿Se puede hacer en (len(x)or 1)lugar de inicializar la longitud?
xnor
Buscando un camino más corto. Ambos len(x or[0])y -~len(x[1:])corbata.
xnor
4

Python 2 , 62 60 bytes

Toma la entrada como una lista de pares, imprime el resultado. Editar: Outgolfed por Dennis

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

Pruébalo en línea!

Esto es bastante simple: recorra la entrada, inserte los elementos en el lugar correcto y luego imprima el resultado. Decidir en qué índice insertar se realiza 1+y%(len(b)or 1). Esta es la forma estándar de hacer indexación modular, con el or 1manejo del caso límite de una lista vacía.

FlipTack
fuente
3

JavaScript (ES6), 60 bytes

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

Fragmento de prueba

ETHproducciones
fuente
2

V , 38 40 35 bytes

Esta respuesta dobla la definición de lista, y normalmente no es un lenguaje que usaría para la manipulación de listas, pero quería usar el [count]/{regex}que agregué recientemente a V. La entrada se toma como [index] [num] [index] [num] ...y se devuelve como [num] [num] [num].

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

Pruébalo en línea!

Hexdump para 2 personajes ocultos:

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

Explicación

El código hasta dG@"formatea todos los \d+ \d+pares para que una lista 1 2 3 4 5 6 termine como

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

y luego dG@"ejecuta todo eso como código V como el siguiente:

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
fuente
Solo digo, el estado de no competencia es solo para idiomas o características de idiomas que son más nuevos que el desafío
Kritixi Lithos el
Ah, gracias, no lo sabías. Lo haré cumplir
nmjcman101
2

PHP, 72 92 bytes

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

toma la entrada aplanada de los argumentos de la línea de comandos. Corre con -nr.

Titus
fuente
Estoy bastante seguro de que esta respuesta no es válida: obtuve un Fatal error: Uncaught DivisionByZeroError: Modulo by zero, lo arreglé, luego lo intenté 1 1 1 2 1 3y obtuve [1=>null]como salida en lugar de[1,3,2]
user59178
Todavía se sobrescribe en j+1lugar de insertar después j, ¿no? 18 1 7 11 35 3 22 16=> en [1,11,16]lugar de[1,11,16,3]
user59178
@ user59178: Oh, me había perdido la insertpalabra clave. Gracias; fijo.
Tito
2

Java 7, 125 124 bytes

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

Acepta una lista plana de valores seguida de índices. Para el caso de prueba de cuadrados, la entrada seríanew int[] {1, 2, 3, 4, 5, 6, 7, 8, 1, 4, 9, 16, 25, 36, 49, 64}

Pruébalo en línea!

Meter
fuente
1

Mathematica, 62 bytes

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

La función pura con el primer argumento se #espera que sea una lista de pares. Comenzando con la lista vacía {}, dejó Foldla lista de entrada #con la siguiente función:

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
fuente
1

Perl 6 , 51 bytes

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

Toma la entrada aplanada.

smls
fuente
1

Clojure, 87 bytes

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