Überlaufsicherer Puffer

23

Hintergrund

Heutzutage können Programmierer ihre Puffer nicht gerade halten! Eine häufige Fehlerquelle ist der Versuch, einen Array-Index zu verwenden, der für den Puffer zu groß ist. Ihre Aufgabe ist es, einen Puffer zu implementieren, in dem große Indizes auf eine Größe reduziert werden, die der Puffer verarbeiten kann. Da ich genau entscheide, was für jeden das Beste ist, implementieren Sie diesen Puffer nach meinen genauen Spezifikationen.

Überblick

Sie haben einen Puffer nur zum Einfügen, der größer wird, wenn Elemente hinzugefügt werden. Der Puffer ist nullindexiert und auch modulo seiner aktuellen Größe indexiert . Die Sonderregel für diese Herausforderung lautet:

  • So fügen Sie ein Element am Index i bedeuten , zu berechnen , j , j = i % buffer.length()und setzen Sie das neue Element nach dem j - ten Elemente in der Liste.

Der einzige Sonderfall ist, wenn der Puffer leer ist, da das arithmetische Modulo Null nicht funktioniert. Wenn der Puffer derzeit leer ist, erhält das neue Element den Index 0 .

Wenn der Puffer nur ein Element enthält, wird immer nach dem 0. Element eingefügt . Dies ist nur ein Beispiel für den allgemeinen Fall.

Wenn der Puffer 6 Elemente enthält: [4, 9, 14, 8, 5, 2]und Sie aufgefordert werden, ein neues Element 10bei Index 15 einzufügen , finden Sie das 15 % 6 == 3und fügen Sie das Neue 10nach dem 8bei Index 3 ein , was einen resultierenden Puffer von ergibt [4, 9, 14, 8, 10, 5, 2]

Problem

Schreiben Sie eine Funktion oder ein Programm, das eine geordnete Liste positiver Ganzzahlen und positive Ganzzahlindizes zum Einfügen enthält.

Beginnen Sie mit einem leeren Puffer und fügen Sie die angegebenen Ganzzahlen an den entsprechenden Indizes zum Puffer hinzu.

Gibt die geordnete Liste der Ganzzahlen aus, die sich im Puffer befinden, nachdem alle angegebenen Einfügungen vorgenommen wurden.

Dies ist eine Code-Golf-Herausforderung, also gewinnt der kürzeste Code.

Eingaberichtlinien

Sie können die Eingabelisten nach Belieben übernehmen. Beispiele:

  • Liste der Paare: [ [1,1], [2,4], [3,9], [4,16], [5,25]...]
  • Artikelliste und Indexliste: [1, 2, 3, 4, 5...], [1, 4, 9, 16, 25]
  • Abgeflacht: [1, 1, 2, 4, 3, 9, 4, 16, 5, 25 ...]
  • etc.

Sie können davon ausgehen, dass die Eingabe immer mindestens ein Element und einen entsprechenden Index enthält.

Testfälle

Quadrate von oben:

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

Ich habe diese zufällig generiert:

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

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
quelle
Kann die Eingabe umgekehrt erfolgen?
FlipTack
Ja, ich denke, die Eingabe kann mehr oder weniger so flexibel sein, wie Sie möchten.
turbulencetoo

Antworten:

4

MATL , 24 22 Bytes

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

Eingabe ist eine Matrix (mit ;als Zeilentrennzeichen), die die Werte in der ersten Zeile und die Indizes in der zweiten Zeile enthält.

Die Ausgabe ist ein Spaltenarray, das als durch Zeilenumbrüche getrennte Zahlen angezeigt wird.

Probieren Sie es online! Oder überprüfen Sie alle Testfälle , wobei jedes Ergebnis in einer einzelnen Zeile angezeigt wird.

Erläuterung

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

Perl, 37 Bytes

35 Byte Code + 2 Byte für -lpFlags.

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

Probieren Sie es online!

Die Implementierung ist recht einfach, splicefügt das Array @Fam Index ein 1+<>%(@F||1)(Anmerkung, @F||1die den Fall behandelt , dass das Array leer ist).

Nur ein paar Worte zu den (scheinbar) unübertroffenen Klammern }{(weil ich einen Kommentar dazu hatte und ich denke, es ist ziemlich seltsam für Leute, die Perl nicht kennen), und es ist ein ganz normaler Trick in Perl-Golfspielen:
-pFlag umgibt den Code mit (ungefähr) while(<>){ CODE } continue { print }, ( continuewird nach jeder Iteration ausgeführt). Wenn diese nicht übereinstimmen }{ , ändere ich meinen Code in while(<>) { CODE}{ } continue { print }. Es wird also ein leerer Block direkt nach meinem Code erstellt (aber das ist kein Problem), und der continuewird nur einmal ausgeführt, nach dem while(dh wenn alle Eingaben gelesen wurden).

Dada
quelle
3
Das }{macht mich verrückt ...
ETHproductions
@ETHproductions Ich bin daran gewöhnt, aber ich liebe es, es anderen Leuten zu zeigen. Sie denken immer, dass etwas nicht stimmt! :) (der Nachteil ist, dass meine Emacs Einrückung ist durcheinander ..)
Dada
1
Das }{erinnert mich an diese Illusion
Luis Mendo
Ja, habe ich. :-)
Dennis
5

ES6 (Javascript), 58,57,5350 Bytes

Golf gespielt

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

Nimmt ein Array von Index-Wert-Paaren als Eingabe.

EDITS

  • Verwenden Sie &&, um den Wert -1 Byte zurückzugeben
  • Entfernt |0(da Spleiß offenbar mit NaN gut umgehen kann), -2 Bytes
  • Machte b=[]ein zweites "Argument" für map () , -2 Bytes (Thx @ETHproductions!)
  • B.length durch map () index (i), -3 bytes ersetzt (Thx @Patrick Roberts!)

Prüfung

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
quelle
1
Schön, ich hätte nicht-rekursive Ansätze ausprobieren sollen. Ich denke, Sie könnena=>a.map(e=>...,b=[])&&b
ETHproductions
2
Sie können 3 Bytes subtrahieren e=>, (e,i)=>indem Sie ianstelle vonb.length
Patrick Roberts den
@PatrickRoberts Das ist eine schöne Idee! Vielen Dank !
Zeppelin
5

Haskell , 70 69 Bytes

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

Probieren Sie es online! Verbrauch: foldl(!)[] [(1,5),(2,4),(3,7)]. Dank @nimi ein Byte gespart!

Erläuterung:

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

Lösung ohne Berechnung des Moduls: (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

Probieren Sie es online!

Laikoni
quelle
j<-1+i`mod`length bSpeichert ein 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

Vielen Dank an @xnor für das Golfen mit 2 Bytes!

Probieren Sie es online!

Dennis
quelle
Können Sie dies tun, (len(x)or 1)anstatt die Länge zu initialisieren?
xnor
Auf der Suche nach einem kürzeren Weg. Beides len(x or[0])und -~len(x[1:])Krawatte.
xnor
4

Python 2 , 62 60 Bytes

Nimmt die Eingabe als eine Liste von Paaren, druckt das Ergebnis. Edit: Outgolfed von Dennis

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

Probieren Sie es online!

Dies ist ganz einfach: Durchlaufen Sie die Eingabe, fügen Sie die Elemente an der richtigen Stelle ein und drucken Sie das Ergebnis aus. Die Entscheidung, in welchen Index eingefügt werden soll, erfolgt mit 1+y%(len(b)or 1). Dies ist die Standardmethode für die modulare Indizierung, bei der or 1der Randfall einer leeren Liste behandelt wird.

FlipTack
quelle
3

JavaScript (ES6), 60 Byte

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

Testschnipsel

ETHproductions
quelle
2

V , 38 40 35 Bytes

Diese Antwort beugt sich die Definition der Liste, und ist normalerweise nicht eine Sprache , die Sie für die Liste Manipulation verwenden würde, aber ich wollte verwenden , [count]/{regex}die ich vor kurzem V. hinzugefügt Der Eingang wie genommen [index] [num] [index] [num] ...und kehrte wie [num] [num] [num].

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

Probieren Sie es online!

Hexdump für 2 versteckte Zeichen:

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

Erläuterung

Der Code bis dG@"formatiert alle \d+ \d+Paare so, dass eine Liste 1 2 3 4 5 6 wie folgt enden würde

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

und dann dG@"führt das alles als V-Code wie folgt aus:

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
quelle
Nur zu sagen, der Wettbewerbsverbot-Status gilt nur für Sprachen oder
Sprachfunktionen
Ah, danke, dass du das nicht wusstest. Ich werde es anpassen
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);

Nimmt Eingaben, die von Befehlszeilenargumenten abgeflacht wurden. Laufen Sie mit -nr.

Titus
quelle
Ich bin mir ziemlich sicher, dass diese Antwort ungültig ist: Ich habe ein Fatal error: Uncaught DivisionByZeroError: Modulo by zero1 1 1 2 1 3[1=>null][1,3,2]
Problem
Es wird immer noch überschrieben, j+1anstatt danach einzufügen j, nein? 18 1 7 11 35 3 22 16=> [1,11,16]anstatt[1,11,16,3]
user59178
@ user59178: Oh, ich hatte das insertKeyword verpasst . Vielen Dank; Fest.
Titus
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;}

Akzeptiert eine flache Liste von Werten, gefolgt von Indizes. Für den Quadrattestfall wäre die Eingabenew int[] {1, 2, 3, 4, 5, 6, 7, 8, 1, 4, 9, 16, 25, 36, 49, 64}

Probieren Sie es online!

Sack
quelle
1

Mathematica, 62 Bytes

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

Reine Funktion, wobei als erstes Argument #eine Liste von Paaren erwartet wird. Beginnen Sie mit der leeren Liste {}und verlassen Sie Folddie Eingabeliste #mit der folgenden Funktion:

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
Genisis
quelle
1

Perl 6 , 51 Bytes

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

Nimmt die abgeflachte Eingabe auf.

smls
quelle
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
quelle