Generalized Array Riffle

22

Ein einfacher Start in die Woche! Sie erhalten drei Arrays: das Basis-Array B , das Wert-Array V und das Index-Array I . Sie sollten ein anderes Array erzeugen, in das die Werte von an den durch angegebenen Indizes Veingefügt Bwerden I. Hier ist ein Beispiel:

Base:    [5, 1, 4, 1, 3]
Values:  [0, 0, 7]
Indices: [5, 0, 3]

Die Indizes zeigen auf folgende Positionen im Basisarray:

[ 5, 1, 4, 1, 3 ]
 ^        ^    ^
 0        3    5

Wenn Sie also die entsprechenden Elemente aus dem Wertearray einfügen, sollte das Ergebnis sein:

[0, 5, 1, 4, 7, 1, 3, 0]

Regeln

Sie können ein Programm oder eine Funktion schreiben, Eingaben über STDIN (oder die nächstgelegene Alternative), Befehlszeilenargumente oder Funktionsargumente vornehmen und das Ergebnis über STDOUT (oder die nächstgelegene Alternative), Funktionsrückgabewert oder durch Ändern des als BParameter angegebenen Arrays ausgeben .

Wenn es sich bei Ihrer Einreichung um eine Funktion handelt, die auf irgendeine Weise geändert werden kann Iund nicht für die Ausgabe verwendet wird.VB

Sie können die folgenden Annahmen bezüglich der Eingabe treffen:

  • Alle Elemente des Basis- und Wertearrays sind nicht negative Ganzzahlen.
  • Das Wertearray enthält höchstens ein Element mehr als das Basisarray.
  • Das Wertearray und das Indexarray haben die gleiche Anzahl von Elementen.
  • Das Index-Array enthält keine wiederholten Indizes, und alle Indizes befinden sich im Bereich.
  • Die Basis- und Wertearrays können wiederholte Elemente enthalten.
  • Einige oder alle Arrays sind möglicherweise leer.
  • Sie dürfen nicht davon ausgehen, dass die Indizes in einer bestimmten Reihenfolge angegeben sind.
  • Sie können Eingaben empfangen und Ausgaben in jedem geeigneten, eindeutigen Zeichenfolgen- oder Listenformat erstellen. Sie können die drei Arrays auch in einer anderen Reihenfolge erhalten.
  • Sie können zwischen 0-basierter und 1-basierter Indizierung wählen.

Dies ist Codegolf, daher gewinnt die kürzeste Antwort (in Bytes).

Testfälle

Wird im Format B V I => Resultfür die 0-basierte Indizierung angegeben. Wenn Sie eine 1-basierte Indizierung verwenden, erhöhen Sie die Elemente des dritten Arrays um 1.

[] [] [] => []
[] [1] [0] => [1]
[1,2] [] [] => [1,2]
[1,2] [3] [0] => [3,1,2]
[1,2] [3] [1] => [1,3,2]
[1,2] [3] [2] => [1,2,3]
[0,0,0] [1,1,1,1] [0,1,2,3] => [1,0,1,0,1,0,1]
[5,1,4,1,3] [0,0,7] [5,0,3] => [0,5,1,4,7,1,3,0]
[1,2,3,4] [4,3,2,1] [4,0,3,1] => [3,1,1,2,3,2,4,4]

Lassen Sie mich wissen, wenn Sie auf andere interessante Randfälle stoßen, und ich werde sie hinzufügen.

Bestenliste

Hier ist ein Stack-Snippet, um sowohl eine reguläre Rangliste als auch eine Übersicht der Gewinner nach Sprache zu erstellen.

Um sicherzustellen, dass Ihre Antwort angezeigt wird, beginnen Sie Ihre Antwort mit einer Überschrift. Verwenden Sie dazu die folgende Markdown-Vorlage:

# Language Name, N bytes

Wo Nist die Größe Ihres Beitrags? Wenn Sie Ihren Score zu verbessern, Sie können alte Rechnungen in der Überschrift halten, indem man sich durch das Anschlagen. Zum Beispiel:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Martin Ender
quelle
4
Wie steht es mit NULLeinem leeren Array für Sprachen, in denen ein leeres Array vorhanden ist NULL?
Alex A.
@AlexA. Wenn es ein gemeinsames / ist die in der Sprache (n) Darstellung des leeren Array, mir geht es gut damit.
Martin Ender
3
Ein einfaches Golfspiel ? Das ist das Schwierigste, was ich die ganze Woche in CJam gemacht habe. : P
Dennis

Antworten:

13

Pyth, 14 Bytes

s.icFPQmedSCtQ

Demonstration.

Dieses Programm nimmt die Eingaben als 3-Tupel-Listen in der Reihenfolge Basis, Indizes, Werte.

Erklärung zum Beispiel [5, 1, 4, 1, 3], [5, 0, 3], [0, 0, 7]:

  1. Nehmen Sie die Eingabe: implizit ist Q die Eingabe.

  2. Machen Sie den Index, Wertepaare: CtQ=[(5, 0), (0, 0), (3, 7)]

  3. Sortieren Sie die Paare in aufsteigender Reihenfolge: SCtQ=[(0, 0), (3, 7), (5, 0)]

  4. Nimm den Wert aus jedem Paar: medSCtQ=[0, 7, 0]

  5. Teilen Sie die Basisliste am Ort der Angaben auf: cFPQ=[[], [5, 1, 4], [1, 3], []]

  6. Interleave 3 und 4: .icFPQmedSCtQ=[[], 0, [5, 1, 4], 7, [1, 3], 0, []]

  7. In einer Liste zusammenfassen: s.icFPQmedSCtQ=[0, 5, 1, 4, 7, 1, 3, 0]

isaacg
quelle
Verdammt. Seit wann gibt es eine Interleave-Methode? Ich wollte nur posten ssC,cFPQamedSCtQ].
Jakube
5
@ Jakube Isaac hat es vor 6 Tagen heimlich begangen.
Orlp
@ Jakube Since github.com/isaacg1/pyth/commit/…
isaacg
3
@ Jakube seit Pyth kann wachsen, um jedes Problem zu lösen. Das ist das Problem mit Golfsprachen. Esoterische Sprachen existieren für esoterische Sprachen; wie sie entworfen sind * danach.
Sentiao
@sentiao Um fair zu sein, die Host-Sprache (Python) hat eine Weile unter einem anderen Namen verschachtelt .
Mego
16

Python 2, 54

lambda B,*X:map(B.insert,*zip(*sorted(zip(*X))[::-1]))

Übernimmt die Eingabe als B,I,V. Ändert die Eingabe, Bwenn sie aufgerufen wird (danke an Martin Büttner, der mich daran erinnert hat, dass dies möglich ist).

Verwendet map, um B.insertjedes Index / Element-Paar aufzurufen . Um zu vermeiden, dass sich die Listenindizes beim Einfügen von Elementen verschieben, sortieren Sie die Paare in absteigender Reihenfolge des Indexes durch hässliches Zippen / Sortieren / Entpacken. Wenn das Problem der Verlagerung nicht wäre, könnten wir es einfach tun map(B.insert,*X).

Alte Methode (65):

B,V,I=input()
for i,v in sorted(zip(I,V))[::-1]:B[i:i]=v,
print B
xnor
quelle
5

Haskell, 62 Bytes

import Data.List
f b v i=map snd$sort$zip[0.5,1.5..]b++zip i v

Anwendungsbeispiel: f [5,1,4,1,3] [0,0,7] [5,0,3]-> [0,5,1,4,7,1,3,0].

So funktioniert es: Ergänzen Sie die Basisliste mit "anderthalb" -Indizes, die bei 0.5(z. B. [(0.5,5),(1.5,1),(2.5,4),(3.5,1),(4.5,3)]) beginnen, und verknüpfen Sie sie mit den Index-Wert-Paaren. Sortieren und verwerfen Sie den Index.

Bemerkung : Ich weiß nicht, ob ich hier betrüge. Aus mathematischer Sicht ist es in Ordnung, aber ein Programmierer könnte argumentieren, dass die Liste der Indizes [5,0,3]keine Liste der Integersangeforderten Indizes ist , sondern eine Liste der Indizes Fractionals(um genau zu sein, der Typ ist polymorph, muss aber zur FractionalKlasse gehören, z. B. Floatoder Double).

nimi
quelle
5

Ruby, 60 59 53 Bytes

->a,b,c{c.zip(b).sort.reverse.map{|i,v|a.insert i,v}}

Und die ungolfed version

def riffle(array, values, indices)
    indices.zip(values).sort.reverse.each do |index, value|
        array.insert(index, value)
    end
end
Dylan Frese
quelle
2
Sie können dies verkürzen , indem sie eine unbenannte Funktion machen statt: ->a,b,c{...}. Es besteht auch die Möglichkeit, insertdass keine Klammern erforderlich sind.
Martin Ender
@ MartinBüttner Ich wusste von der unbenannten Funktion mit dem Lambda, aber ich hatte nicht das Gefühl, dass dies im Geiste der Herausforderung lag (die normalerweise nach einer benannten Funktion verlangt). Vielen Dank, dass Sie die Eltern gesehen haben.
Dylan Frese
Sofern bei der Abfrage nicht ausdrücklich nach einer benannten Funktion gefragt wird, sind nicht benannte Funktionen immer zulässig . Und ich habe nicht nach einer benannten Funktion gefragt (das tue ich nie;)).
Martin Ender
5

CJam, 34 23 18 Bytes

{.\2/\ee+{0=}$1f=}

Mein erster CJam-Beitrag. Tipps sind willkommen, ich bin mir sicher, dass Golf viel zu bieten hat.

16 Bytes mit Hilfe von @ MartinBüttner und @Dennis gespeichert.

Die Funktion erwartet die Eingabe auf dem Stapel in der angegebenen Reihenfolge B V I(I ist die oberste).

Anwendungsbeispiel:

[5 1 4 1 3] [0 0 7] [5 0 3] {.\2/\ee+{0=}$1f=}~

Methode:

  • Paaren Sie das idritte Element des Arrays miti+0.5
  • Verbinden Sie Insert-Werte mit Insert-Positionen
  • Führen Sie die resultierenden zwei Arrays zusammen
  • Array nach Positionselementen sortieren
  • Wertelemente behalten
randomra
quelle
Dieser Gleitkomma-Ansatz ist sehr clever und (leider) besser als meiner. q~.5fm.\2/\ee+$1f=pMit einer anonymen Funktion können Sie bis zu 19 Bytes mit und bis zu 18 Bytes erreichen:{.5fm.\2/\ee+$1f=}
Dennis
Gleiche Idee ohne Fließkomma-Trick: {.\2/\ee+{0=}$1f=}(immer noch 18 Bytes)
Dennis
@ Tennis Danke, ich konnte den get array elementOperator für nicht finden 1f=. Ich werde es jedoch als vollständiges Programm belassen.
Randomra
Ihr Anruf. Stört es Sie, wenn ich Sie frage, warum Sie gegen die Veröffentlichung einer Funktion sind?
Dennis
@Dennis Ich habe gerade CJam gestartet und war mir nicht sicher, wie ich die Funktionen nutzen sollte. Jetzt habe ich es herausgefunden und die Antwort darauf geändert.
Randomra
5

K, 22-21 Bytes

{,//+(y@<z;(z@<z)_ x)}

Wir definieren eine 3 Argumentfunktion {…}mit den impliziten Variablen x, yund zdie die Startliste, die Werteliste und die Indexliste, respectively. Der "cut" -Operator ( _) wird verwendet, um die Startliste an der sortierten Liste gegebener Indizes ( (z@<z)) aufzuteilen . Wir verschachteln Werte (nachdem wir sie entsprechend sortiert haben) mit den aufgeteilten Teilen des ursprünglichen Arrays, indem wir eine Liste bilden ( (a;b)), deren Transponierung nehmen ( +) und das Ergebnis abflachen ( ,//).

Anwendungsbeispiel:

  f:{,//+(y@<z;(z@<z)_ x)}
{,//+(y@<z;(z@<z)_ x)}

  f[1 2 3 4;4 3 2 1;4 0 3 1]
3 1 1 2 3 2 4 4

  f[5 1 4 1 3;0 0 7;5 0 3]
0 5 1 4 7 1 3 0

Leerzeichen um den Unterstrich sind erforderlich, da K Unterstriche in Bezeichnern zulässt. K5 beseitigt diese potenzielle Mehrdeutigkeit. Wenn wir auf die aufsteigenden Indizes zählen könnten und Unterstriche keine gültigen Bezeichner wären, könnten wir das viel schönere 13-Byte-Programm verwenden:

{,//+(y;z_x)}

(Seufzer.)

bearbeiten:

{,//+(y@<z;(z@<z)_ x)} / before
{,//+(y@<z;z[<z]_ x)}  / after

Bricht die Symmetrie, aber wir können ein Byte speichern, indem wir Bracket-Indexing ( […]) anstelle des Infix- @Indexing-Operators verwenden. Normalerweise werden Programme dadurch länger, aber in diesem Fall mussten die Pars trotzdem sortiert werden, zbevor der Schnitt ausgeführt werden konnte.

JohnE
quelle
4

Pyth, 17 Bytes

ssC,cFPQamedSCtQ]

@isaacg hat meine Lösung schon geschlagen. Aber da ich meine Dokumentation fertig hatte, werde ich sie trotzdem posten.

Dies übernimmt die Eingabe im Format B, I, V. Sie können es hier ausprobieren: Demonstration oder Test Suite

Erläuterung:

Ich verwende das Beispiel B = [5,1,4,1,3], I = [5,0,3], V = [0,0,7]aus dem OP.

                    implicit: Q = input()
      PQ            all elements but last of Q   => [[5,1,4,1,3], [5,0,3]]
    cF              split B it the indices in I  => [[], [5,1,4], [1,3], []]

              tQ    all elements but first of Q  => [[5,0,3], [0,0,7]]
             C      zip                          => [(5,0), (0,0), (3,7)]
            S       sort                         => [(0,0), (3,7), (5,0)]
         med        extract the end of each pair => [0,7,0]
        a       ]   append an empty list         => [0,7,0,[]]

   ,                create a pair => ([[], [5,1,4], [1,3], []], [0,7,0,[]])
  C                 zip           => [([],0), ([5,1,4],7), ([1,3],0), ([],[])]
 s                  sum           => ([],0,[5,1,4],7,[1,3],0,[],[])
s                   sum           => [0,5,1,4,7,1,3,0]
Jakube
quelle
4

JavaScript (ES6), 75

Eine Funktion mit 3 Array-Parametern, die ein Array zurückgibt. Seltsamerweise ändert diese Funktion ihren iParameter (wie freundlicherweise von OP erlaubt)

Testen Sie das Snippet, Firefox nur wie gewohnt.

f=(b,v,i,j=0)=>b.concat(v).map(p=>(p=i.indexOf(j))<0?b[j++]:(i[p]=-1,v[p]))

// TEST
out=x=>O.innerHTML+=x+'\n'

test=[
{ b:[], v:[], i:[], k:[] },
{ b:[], v:[1], i:[0], k:[1] },
{ b:[1,2], v:[], i:[], k:[1,2] },
{ b:[1,2], v:[3], i:[0], k:[3,1,2] },
{ b:[1,2], v:[3], i:[1], k:[1,3,2] },
{ b:[1,2], v:[3], i:[2], k:[1,2,3] },
{ b:[0,0,0], v:[1,1,1,1], i:[0,1,2,3], k:[1,0,1,0,1,0,1] },
{ b:[5,1,4,1,3], v:[0,0,7], i:[5,0,3], k:[0,5,1,4,7,1,3,0] },
{ b:[1,2,3,4], v:[4,3,2,1], i:[4,0,3,1], k:[3,1,1,2,3,2,4,4] }
];

test.forEach(x=>{
  r = f(x.b,x.v,x.i.slice(0)) // pass a copy of i, as the function will alter it
  ok = ''+r==''+x.k
  s='Test ' + (ok?'OK':'FAIL')
  +'\n B ['+x.b
  +']\n V ['+x.v
  +']\n I ['+x.i
  +']\n Result ['+r
  +']\n Check  ['+x.k
  +']\n'
  out(s)
  
})
<pre id=O></pre>

edc65
quelle
Was ist mit dem Code, der aus Neugier für Firefox spezifisch ist? Liegt es daran, dass es sich um ES6 handelt?
Alex A.
@ AlexA.it ist, weil es ES6 ist, ja. Insbesondere das fat arrow functionist auch in der Entwicklerversion von Chrome (AFAIK) nicht implementiert
edc65
Tatsächlich unterstützt es nicht einmal die kanarische Version von Chrome.
DocMax
4

Mathematica, 52 51 Bytes

Last/@(Tr@#2->#&~MapIndexed~#⋃Thread[#3+.5->#2])&

Beispiel:

In[1]:= f = Last/@(Tr@#2->#&~MapIndexed~#⋃Thread[#3+.5->#2])&;

In[2]:= f[{5, 1, 4, 1, 3}, {0, 0, 7}, {5, 0, 3}]

Out[2]= {0, 5, 1, 4, 7, 1, 3, 0}

Erläuterung:

Im obigen Beispiel.

  • Tr@#2->#&~MapIndexed~# => {1 -> 5, 2 -> 1, 3 -> 4, 4 -> 1, 5 -> 3}
  • Thread[#3+.5->#2] => {5.5 -> 0, 0.5 -> 0, 3.5 -> 7}
  • Nehmen Sie dann die (sortierte) Vereinigung dieser beiden Listen. (=> {0.5 -> 0, 1 -> 5, 2 -> 1, 3 -> 4, 3.5 -> 7, 4 -> 1, 5 -> 3, 5.5 -> 0})
  • Und dann nimm das letzte Element von jedem Paar. (=> {0, 5, 1, 4, 7, 1, 3, 0})
Alephalpha
quelle
3

CJam, 30 29 Bytes

q~.\2/$z~0@+2ew@f{\~@<>}.\e_p

Das ist zu lang. Ich habe das Gefühl, dass dies keine Vorlage für eine Golfsprache ist: |

Probieren Sie es hier online aus

Optimierer
quelle
3

R, 75 Bytes

function(b,v,i){n=b;j=0;for(g in v)n=append(n,g,i[j<-j+1]+sum(i<i[j])-1);n}

Dies erzeugt eine unbenannte Funktion. Um es zu nennen, geben Sie ihm einen Namen, z f=function.... Beachten Sie, dass die Arrays 1-indiziert sein müssen, da R genau so rollt.

Ungolfed + Erklärung:

f <- function(b, v, i) {
    # Initialize the output vector to b
    n <- b

    # Initialize an index over the indices
    j <- 0

    # Loop over the values to insert
    for(g in v) {
        # Get the index of the next given insertion index
        j <- j + 1

        # Insert g into n.
        # The position at which to insert the value is determined by
        # adding the number of indices less than the current one and
        # subtracting 1. The subtraction is because we're using the
        # `after` argument in the `append` function.

        n <- append(n, g, i[j] + sum(i < i[j]) - 1)
    }

    # Return n
    n
}

Beispiele:

> f(c(), c(), c())
[1] NULL

> f(c(0, 0, 0), c(1, 1, 1, 1), c(1, 2, 3, 4))
[1] 1 0 1 0 1 0 1

> f(c(5, 1, 4, 1, 3), c(0, 0, 7), c(6, 1, 4))
[1] 0 5 1 4 7 1 3 0

Vorschläge sind wie immer willkommen!

Alex A.
quelle
2

CJam, 19 Bytes

l~_,)N*q~.{t}~.\N-p

Dies ist ein vollständiges Programm, das die Arrays B , I und V liest (eines pro Zeile in dieser Reihenfolge) aus STDIN liest.

Probieren Sie es online im CJam-Interpreter aus .

Wie es funktioniert

l~    e# Evaluate the first line of input.
_,)   e# Compute the array length and add 1.
N*    e# Push a string of that many linefeeds.
q~    e# Evaluate the remaining input.
.{t}~ e# Vectorized array set: for each index in the array from line 2, replace the
      e# LF at that index by the corresponding element of the array from line 3.
.\    e# Interleave the two arrays on the stack.
N-    e# Remove the linefeeds.
p     e# Print.

CJam, 20 Bytes

{Qa+@@.{a2$2$=+t}e_}

Dies ist eine anonyme Funktion, die B , V anzeigt und I (von oben nach unten) aus dem Stapel entfernt und im Gegenzug ein einzelnes Array auf dem Stapel belässt.

Probieren Sie es online in der CJam-Interpreter aus .

Wie es funktioniert

Qa+      e# Append [[]] to B.
@@       e# Rotate V and I on top of B.
.{       e# For each v in V and the corresponding i in I:
   a     e#     Push [v].
   2$2$= e#     Retrieve b := B[i].
   +     e#     Append to push [v b].
         e#     The stack now consists of: B i [v b]
   t     e#     Set B[i] := [v b].
}        e#
e_       e# Flatten B.
Dennis
quelle
1

Ruby, 48 Bytes

Ich denke, dies entspricht den Regeln, aber bitte überprüfen Sie.

->b,v,i{l=-1;i.map{|j|b[j]=[v[l+=1],b[j]]};b*?:}

Unbenannte Funktion, die die drei Arrays als Eingabe verwendet. Gibt einen String aus, der mit dem Ruby-Ausdruck eindeutig in ein Array von Zahlen zerlegt werden kannx.split(/:+/).map(&:to_i) .

Testfälle auf ideone .

Ich könnte 3 weitere Bytes einsparen, aber das Ausgabeformat [1,2,[nil,5]]dehnt die Regeln ein bisschen zu sehr aus, obwohl es eindeutig ist.

blutorange
quelle
Ich finde das aktuelle Format okay. Verschachtelte Arrays mit Interleaving- nilWerten sind etwas gedehnt. Aber in beiden Fällen gewinnt dies den Wettbewerb nicht, so dass ich mir darüber auch keine Sorgen mache.
Martin Ender
1

R 60

Als unbenannte Funktion, die b, v und i nimmt

function(b,v,i){e=c(NA,rbind(b,NA));e[i*2+1]=v;e[!is.na(e)]}

Erweitert b mit NAs Füllt die erforderlichen Lücken mit v Gibt den Vektor ohne NAs zurück

> f=function(b,v,i){e=c(NA,rbind(b,NA));e[i*2+1]=v;e[!is.na(e)]}
> f(c(), c(), c())
logical(0)
> f(c(0, 0, 0), c(1, 1, 1, 1), c(0, 1, 2, 3))
[1] 1 0 1 0 1 0 1
> f(c(5, 1, 4, 1, 3), c(0, 0, 7), c(5, 0, 3))
[1] 0 5 1 4 7 1 3 0
MickyT
quelle
1

Java, 253, 226, 219, 209

nicht gerade ein Gewinner, aber na ja.

Angenommen, B, V und ich sind nicht null. v (Kleinbuchstabe v) ist die Länge der Values ​​/ Indicies-Arrays. R ist das zurückgegebene Array. r ist die Länge des zurückgegebenen Arrays. x, y und ich sind alle temporäre ints.

int[]f(int[]B,int[]V,int[]I){int v=V.length,r=B.length+v,x,y,i;int[]R=java.utils.Arrays.copyOf(B,r);for(x=0;x<v;x++){i=I[x];for(y=0;y<x;y++)if(I[x]>I[y])i++;for(y=r-2;y>=i;y--)R[y+1]=R[y];R[i]=V[x];}return R;}

erweitert:

int[]f( int[] B, int[] V, int[] I ) {
    int v = V.length, //length of Values
        r = B.length + v, //length of the result
        x, y, i; //temps
        int[] R = java.utils.Arrays.copyOf( B, r );       
        for( x = 0; x < v; x++ ) {
        i = I[x];
        for( y = 0; y < x; y++ )
            if( I[x] > I[y] )
                i++;
        for( y = r - 2; y >= i; y-- )
            R[y+1] = R[y];
        R[i] = V[x];
    }
    return R;
}
Jack Ammo
quelle
1

APL, 22 Bytes

{(∊⌽2↑⍵)[⍋(2⊃⍵),⍳≢⊃⍵]}

In ⎕IO ← 0, um die Testfälle abzugleichen.

Es ist ein Standardalgorithmus: Der Indexvektor des ersten Arguments wird an die angegebenen Indizes angehängt (3. Argument). berechnet die Permutation, die die Indizes in aufsteigender Reihenfolge sortieren würde. Da der Sortieralgorithmus von APL per Definition stabil ist, setzt die berechnete Permutation das Element der Verkettung des zweiten und ersten Arguments an die richtige Stelle.

Zum Beispiel :

    {(∊⌽2↑⍵)[⍋(2⊃⍵),⍳≢⊃⍵]}(5 1 4 1 3)(0 0 7)(5 0 3)
0 5 1 4 7 1 3 0
lstefano
quelle