Tampon anti-débordement

23

Contexte

Les programmeurs de nos jours n'arrivent pas à garder leurs tampons droits! Une source d'erreur courante essaie d'utiliser un index de tableau trop grand pour le tampon. Votre tâche consiste à implémenter un tampon où les grands indices sont réduits à une taille que le tampon peut gérer. Parce que je décide exactement ce qui est le mieux pour tout le monde, vous allez implémenter ce tampon selon mes spécifications précises.

Présentation

Vous disposez d'un tampon d'insertion uniquement dont la taille augmente à mesure que des éléments y sont ajoutés. Le tampon est indexé zéro, et également indexé modulo sa taille actuelle. La règle spéciale pour ce défi est la suivante:

  • Pour insérer un élément à l' index i signifie pour calculer j , j = i % buffer.length()et insérer le nouvel élément après l' jème élément dans la liste.

Le seul cas particulier est si le tampon est vide, car le module arithmétique zéro ne fonctionne pas. Ainsi, si le tampon est actuellement vide, le nouvel élément sera l'index 0 .

Si le tampon n'a qu'un seul élément, vous insérez toujours après le 0ème élément. Ce n'est là qu'un exemple du cas général.

Si le tampon contient 6 éléments: [4, 9, 14, 8, 5, 2]et on vous dit d'insérer un nouvel élément 10à l'index 15 , vous le trouvez 15 % 6 == 3, puis insérez le nouveau 10après l' 8index 3 qui donne un tampon résultant de [4, 9, 14, 8, 10, 5, 2]

Problème

Écrivez une fonction ou un programme qui prend une liste ordonnée d'entiers positifs et d'indices entiers positifs auxquels les insérer.

Commencez avec un tampon vide et ajoutez les entiers spécifiés au tampon aux indices correspondants.

Sortez la liste ordonnée des entiers qui sont dans le tampon une fois que toutes les insertions spécifiées ont été effectuées.

C'est un défi de code-golf, donc le code le plus court l'emporte.

Directives de saisie

Vous pouvez prendre les listes de saisie comme bon vous semble. Exemples:

  • Liste des paires: [ [1,1], [2,4], [3,9], [4,16], [5,25]...]
  • Liste d'articles et liste d'index: [1, 2, 3, 4, 5...], [1, 4, 9, 16, 25]
  • Aplati: [1, 1, 2, 4, 3, 9, 4, 16, 5, 25 ...]
  • etc.

Vous pouvez supposer que l'entrée contient toujours au moins un élément et l'index correspondant.

Cas de test

Cas de carrés d'en haut:

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

Je les ai générés au hasard:

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

Implémentation de référence 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
la source
L'entrée peut-elle être prise à l'envers?
FlipTack
Oui, je pense que l'entrée peut être plus ou moins aussi flexible que vous le souhaitez.
turbulencetoo

Réponses:

4

MATL , 24 22 octets

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

L'entrée est une matrice (avec ;comme séparateur de ligne) contenant les valeurs de la première ligne et les indices de la seconde.

La sortie est un tableau de colonnes, affiché sous forme de nombres séparés par des retours à la ligne.

Essayez-le en ligne! Ou vérifiez tous les cas de test , chaque résultat étant affiché sur une seule ligne.

Explication

"          % 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
la source
8

Perl, 37 octets

35 octets de code + 2 octets pour les -lpdrapeaux.

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

Essayez-le en ligne!

L'implémentation est assez simple, spliceinsère dans le tableau @Fà l'index 1+<>%(@F||1)(note qui @F||1gère le cas du tableau étant vide).

Juste quelques mots sur les accolades (apparemment) inégalées }{(parce que j'avais un commentaire à ce sujet, et je pense que c'est assez bizarre pour les gens qui ne connaissent pas Perl), et c'est une astuce assez courante dans les golfs de Perl: le
-pdrapeau entoure le code avec (grossièrement) while(<>){ CODE } continue { print }, (le continueest exécuté après chaque itération). Donc, avec ceux inégalés }{ , je change mon code en while(<>) { CODE}{ } continue { print }. Il crée donc un bloc vide juste après mon code (mais ce n'est pas un problème), et le continuen'est exécuté qu'une seule fois, après le while(c'est-à-dire lorsque toutes les entrées ont été lues).

Dada
la source
3
Ça }{me
rend dingue
@ETHproductions J'y suis habitué mais j'adore le montrer aux autres, ils pensent toujours que quelque chose ne va pas! :) (l'inconvénient est que ça dérange avec mon indentation emacs ..)
Dada
1
Cela }{me rappelle cette illusion
Luis Mendo
Oui je l'ai fait. :-)
Dennis
5

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

Golfé

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

Prend un tableau de paires index-valeur, en entrée.

MODIFICATIONS

  • Utilisez &&pour renvoyer la valeur, -1 octet
  • Supprimé |0(car l'épissure peut apparemment bien gérer NaN), -2 octets
  • Création d' b=[]un deuxième "argument" pour mapper () , -2 octets (Thx @ETHproductions!)
  • Remplacé b.length par map () index (i), -3 octets (Thx @Patrick Roberts!)

Tester

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 ]
Zeppelin
la source
1
Bien, j'aurais dû essayer des approches non récursives. Je pense que vous pouvez le fairea=>a.map(e=>...,b=[])&&b
ETHproductions
2
Vous pouvez soustraire 3 octets en changeant e=>à (e,i)=>et en utilisant au ilieu deb.length
Roberts Patrick
@PatrickRoberts C'est une bonne idée! Je vous remercie !
zeppelin
5

Haskell , 70 69 octets

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

Essayez-le en ligne! Utilisation: foldl(!)[] [(1,5),(2,4),(3,7)]. Un octet enregistré grâce à @nimi!

Explication:

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

Solution sans calculer le module: (90 octets)

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

Essayez-le en ligne!

Laikoni
la source
j<-1+i`mod`length benregistre un octet.
nimi
4

Python 2 , 64 62 58 56 octets

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

Merci à @xnor d'avoir joué au golf sur 2 octets!

Essayez-le en ligne!

Dennis
la source
Pouvez-vous faire (len(x)or 1)au lieu d'initialiser la longueur?
xnor
Vous cherchez un moyen plus court. Les deux len(x or[0])et la -~len(x[1:])cravate.
xnor
4

Python 2 , 62 60 octets

Prend la saisie sous forme de liste de paires, imprime le résultat. Edit: Outgolfed par Dennis

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

Essayez-le en ligne!

C'est assez simple - parcourez l'entrée, insérez les éléments au bon endroit, puis imprimez le résultat. Décider dans quel index insérer est fait avec 1+y%(len(b)or 1). Il s'agit de la méthode standard pour effectuer une indexation modulaire, avec le or 1pour gérer le cas de bord d'une liste vide.

FlipTack
la source
3

JavaScript (ES6), 60 octets

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

Extrait de test

ETHproductions
la source
2

V , 38 40 35 octets

Cette réponse plie la définition de liste, et n'est normalement pas un langage que vous utiliseriez pour la manipulation de liste, mais je voulais utiliser [count]/{regex}que j'ai récemment ajouté à V. L'entrée est prise comme [index] [num] [index] [num] ...et retournée comme [num] [num] [num].

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

Essayez-le en ligne!

Hexdump pour 2 personnages cachés:

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

Explication

Le code dG@"formate toutes les \d+ \d+paires de sorte qu'une liste 1 2 3 4 5 6 se termine comme

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

puis dG@"exécute tout cela en tant que code V comme suit:

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
la source
Je dis simplement que le statut de non-concurrence ne concerne que les langues ou les fonctionnalités linguistiques plus récentes que le défi
Kritixi Lithos
Ah, merci, vous ne le saviez pas. Je vais le rendre conforme
nmjcman101
2

PHP, 72 92 octets

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

prend l'entrée aplatie à partir des arguments de la ligne de commande. Courez avec -nr.

Titus
la source
Je suis assez certain que cette réponse n'est pas valide: j'ai obtenu Fatal error: Uncaught DivisionByZeroError: Modulo by zero, corrigé cela, puis essayé 1 1 1 2 1 3et obtenu [1=>null]en sortie au lieu de[1,3,2]
user59178
Il écrase toujours j+1plutôt que d'insérer après j, non? 18 1 7 11 35 3 22 16=> [1,11,16]plutôt que[1,11,16,3]
user59178
@ user59178: Oh, j'avais oublié le insertmot - clé. Merci; fixé.
Titus
2

Java 7, 125 124 octets

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

Accepte une liste plate de valeurs suivie d'index. Pour le cas de test des carrés, l'entrée seraitnew int[] {1, 2, 3, 4, 5, 6, 7, 8, 1, 4, 9, 16, 25, 36, 49, 64}

Essayez-le en ligne!

Poussée
la source
1

Mathematica, 62 octets

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

Fonction pure dont le premier argument #devrait être une liste de paires. En commençant par la liste vide {}, vous avez laissé Foldla liste d'entrée #avec la fonction suivante:

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
la source
1

Perl 6 , 51 octets

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

Prend l'entrée aplatie.

smls
la source
1

Clojure, 87 octets

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