Riffle di array generalizzato


22

Un semplice golf per iniziare la settimana! Vengono forniti tre array: l' array base B , l' array value V e l' array index I . È necessario produrre un altro array in cui i valori da Vvengono inseriti negli Bindici specificati da I. Ecco un esempio:

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

Gli indici puntano alle seguenti posizioni nella matrice di base:

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

Quindi inserendo gli elementi corrispondenti dall'array value, il risultato dovrebbe essere:

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

Regole

È possibile scrivere un programma o una funzione, prendendo l'input tramite STDIN (o l'alternativa più vicina), gli argomenti della riga di comando o gli argomenti della funzione e producendo il risultato tramite STDOUT (o l'alternativa più vicina), il valore di ritorno della funzione o modificando l'array indicato come Bparametro .

Se l'invio è una funzione Ie Vpuò essere modificato in qualsiasi modo, nonché Bse non viene utilizzato per l'output.

È possibile formulare le seguenti ipotesi sull'input:

  • Tutti gli elementi dell'array base e value saranno numeri interi non negativi.
  • La matrice di valori avrà al massimo un altro elemento rispetto alla matrice di base.
  • La matrice di valori e la matrice di indice avranno lo stesso numero di elementi.
  • La matrice di indici non conterrà indici ripetuti e tutti gli indici saranno nell'intervallo.
  • Le matrici di base e di valore possono contenere elementi ripetuti.
  • Uno o tutti gli array possono essere vuoti.
  • Non si deve presumere che gli indici siano indicati in un ordine particolare.
  • È possibile ricevere input e produrre output in qualsiasi formato di elenco o stringa conveniente e inequivocabile. È inoltre possibile scegliere di ricevere i tre array in un ordine diverso.
  • Puoi scegliere tra indicizzazione basata su 0 e basata su 1.

Questo è il golf del codice, quindi vince la risposta più breve (in byte).

Casi test

Dato nel formato B V I => Resultper l'indicizzazione basata su 0. Se si utilizza l'indicizzazione basata su 1, incrementare di 1 gli elementi del terzo array.

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

Fammi sapere se ti imbatti in altri casi limite interessanti e li aggiungerò.

Classifica

Ecco uno snippet di stack per generare sia una classifica regolare che una panoramica dei vincitori per lingua.

Per assicurarti che la tua risposta venga visualizzata, ti preghiamo di iniziare la risposta con un titolo, usando il seguente modello Markdown:

# Language Name, N bytes

dov'è Nla dimensione del tuo invio. Se si migliora il punteggio, è possibile mantenere i vecchi punteggi nel titolo, colpendoli. Per esempio:

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


4
Come ti senti NULLper un array vuoto per le lingue in cui si trova un array vuoto NULL?
Alex A.

@AlexA. Se è un comune / la rappresentazione dell'array vuoto in detti linguaggi, sto bene con quello.
Martin Ender,

3
Un semplice golf ? Questa è la cosa più difficile che ho fatto in CJam per tutta la settimana. : P
Dennis,

Risposte:


13

Pyth, 14 byte

s.icFPQmedSCtQ

Dimostrazione.

Questo programma accetta gli input come 3-tuple di liste nell'ordine Base, Indici, Valori.

Spiegazione sull'esempio [5, 1, 4, 1, 3], [5, 0, 3], [0, 0, 7]:

  1. Prendi l'input: implicito, Q è l'input.

  2. Crea l'indice, coppie di valori: CtQ=[(5, 0), (0, 0), (3, 7)]

  3. Ordina le coppie in ordine crescente di indice: SCtQ=[(0, 0), (3, 7), (5, 0)]

  4. Prendi il valore da ogni coppia: medSCtQ=[0, 7, 0]

  5. Dividi l'elenco di base nella posizione delle indicazioni: cFPQ=[[], [5, 1, 4], [1, 3], []]

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

  7. Combina in un elenco: s.icFPQmedSCtQ=[0, 5, 1, 4, 7, 1, 3, 0]


Dannazione. Da quando abbiamo un metodo interleave? Volevo solo postare ssC,cFPQamedSCtQ].
Jakube,

5
@Jakube isaac l'ha commesso subdolamente in 6 giorni fa.
orlp,


3
@Jakube poiché Pyth può crescere per risolvere qualsiasi problema. Questo è il problema con le lingue del golf. Le lingue esoteriche esistono per il bene delle lingue esoteriche; come sono stati progettati * in seguito.
Sentiao,

@sentiao Per essere onesti, la lingua host (Python) ha avuto interfacce con un nome diverso per un po '.
Mego,

16

Python 2, 54

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

Accetta input come B,I,V. Modifica l'ingresso Bquando viene chiamato (grazie a Martin Büttner per avermi ricordato che è possibile).

Utilizza mapper chiamare B.insertogni coppia indice / elemento. Per evitare il problema degli indici della lista che si spostano quando vengono inseriti gli elementi, ordina le coppie in ordine decrescente di indice di un brutto zip / sort / unzip. Se non fosse per il problema del cambio, potremmo semplicemente fare map(B.insert,*X).

Vecchio metodo (65):

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

5

Haskell, 62 byte

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

Esempio di utilizzo: f [5,1,4,1,3] [0,0,7] [5,0,3]-> [0,5,1,4,7,1,3,0].

Come funziona: aumenta l'elenco di base con indici "e mezzo" a partire da 0.5(ad esempio [(0.5,5),(1.5,1),(2.5,4),(3.5,1),(4.5,3)]) e concatenalo con le coppie indice-valore. Ordina e scarta l'indice.

Nota : non so se sto tradendo qui. Da un punto di vista matematico va bene, ma un programmatore potrebbe sostenere che l'elenco degli indici [5,0,3]non è un elenco Integerscome richiesto, ma un elenco di Fractionals(per essere esatti, il tipo è polimorfico, ma deve appartenere alla Fractionalclasse, ad es. FloatO Double).


5

Rubino, 60 59 53 byte

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

E la versione non golfata

def riffle(array, values, indices)
    indices.zip(values).sort.reverse.each do |index, value|
        array.insert(index, value)
    end
end

2
È possibile ridurre questo facendo una funzione senza nome invece: ->a,b,c{...}. Inoltre è probabile che insertnon siano necessarie parentesi.
Martin Ender,

@ MartinBüttner Conoscevo la funzione senza nome con la lambda, ma non pensavo fosse nello spirito della sfida (che di solito richiede una funzione con nome). Grazie per aver individuato le parentesi, però.
Dylan Frese,

A meno che la sfida non richieda specificamente una funzione con nome , le funzioni senza nome sono sempre accettabili . E non ho chiesto una funzione con nome (non lo faccio mai;)).
Martin Ender,

5

CJam, 34 23 18 byte

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

La mia prima presentazione su CJam. I consigli sono i benvenuti, sono sicuro che ci sia molto da golf.

16 byte salvati con l'aiuto di @ MartinBüttner e @Dennis.

Funzione in attesa di input nello stack in ordine B V I(I è il più in alto).

Esempio di utilizzo:

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

Metodo:

  • associare l' ielemento th dell'array ai+0.5
  • accoppia valori di inserimento con posizioni di inserimento
  • unire i due array risultanti
  • ordina l'array in base agli elementi di posizione
  • mantenere gli elementi di valore

Questo approccio in virgola mobile è molto intelligente e (purtroppo) migliore del mio. Puoi scendere a 19 byte con q~.5fm.\2/\ee+$1f=pe a 18 byte usando una funzione anonima:{.5fm.\2/\ee+$1f=}
Dennis

Stessa idea senza il trucco a virgola mobile: {.\2/\ee+{0=}$1f=}(ancora 18 byte)
Dennis

@Dennis Grazie, non sono riuscito a trovare l' get array elementoperatore per 1f=. Lo lascerò comunque come un programma completo.
randomra,

La tua chiamata. Ti dispiace chiederti perché sei contrario a pubblicare una funzione?
Dennis,

@Dennis Ho appena avviato CJam e non ero sicuro di come utilizzare le funzioni. Ora l'ho capito, quindi ho cambiato la risposta.
randomra,

5

K, 22 21 byte

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

Si definisce una funzione 3 argomento {…}con le variabili implicite x, ye zrappresenta la lista di partenza, la lista valori e la lista degli indici, rispettivamente. L'operatore "cut" ( _) viene utilizzato per dividere l'elenco iniziale in un elenco ordinato di determinati indici ( (z@<z)). Interlacciamo i valori (dopo averli ordinati in modo corrispondente) con i blocchi suddivisi dell'array originale formando un elenco ( (a;b)), prendendo la sua trasposizione ( +) e appiattendo il risultato ( ,//).

Esempio di utilizzo:

  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

Gli spazi attorno al carattere di sottolineatura sono necessari perché K consente i caratteri di sottolineatura negli identificatori. K5 rimuove questa potenziale ambiguità. Se potessimo contare sugli indici in ordine crescente e i trattini bassi non fossero identificatori validi, potremmo usare il programma a 13 byte molto più bello:

{,//+(y;z_x)}

(sospiro.)

modificare:

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

Rompe la simmetria, ma possiamo salvare un byte usando parentesi-indexing ( […]) invece @dell'operatore di indicizzazione infix . Di solito questo rende i programmi più lunghi, ma in questo caso avevamo bisogno comunque delle parentesi per ordinare zprima di eseguire il taglio.


4

Pyth, 17 byte

ssC,cFPQamedSCtQ]

@isaacg ha già battuto la mia soluzione. Ma dato che ho finito la mia documentazione, la pubblicherò comunque.

Questo accetta l'input nel formato B, I, V. Puoi provarlo qui: Dimostrazione o Test Suite

Spiegazione:

Sto usando l'esempio B = [5,1,4,1,3], I = [5,0,3], V = [0,0,7]dell'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]

4

JavaScript (ES6), 75

Una funzione con 3 parametri di array, che restituisce un array. Stranamente, questa funzione modifica il suo iparametro (come gentilmente consentito da OP)

Prova a eseguire lo snippet, Firefox solo come al solito.

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>


Per curiosità, che dire del codice lo rende specifico per Firefox? È perché è ES6?
Alex A.,

@ AlexA.it è perché è ES6, sì. In particolare il fat arrow functionnon è implementato nemmeno nella versione per sviluppatori di Chrome (AFAIK)
edc65,

In effetti, nemmeno la build di Chrome delle Canarie lo supporta.
DocMax,

4

Mathematica, 52 51 byte

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

Esempio:

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}

Spiegazione:

Utilizzando l'esempio sopra.

  • 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}
  • Quindi prendi l'unione (ordinata) di queste due liste. (=> {0.5 -> 0, 1 -> 5, 2 -> 1, 3 -> 4, 3.5 -> 7, 4 -> 1, 5 -> 3, 5.5 -> 0})
  • E poi prendi l'ultimo elemento di ogni coppia. (=> {0, 5, 1, 4, 7, 1, 3, 0})

3

CJam, 30 29 byte

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

Questo è troppo lungo. Sento che questa non è una presentazione linguistica del golf: |

Provalo online qui


3

R, 75 byte

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}

Questo crea una funzione senza nome. Per chiamarlo, dagli un nome, ad esf=function... . Si noti che le matrici devono essere 1 indicizzate perché è così che R scorre.

Ungolfed + spiegazione:

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
}

Esempi:

> 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

I suggerimenti sono i benvenuti come sempre!


2

CJam, 19 byte

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

Questo è un programma completo che legge gli array B , I e V (uno per riga, in quell'ordine) da STDIN.

Provalo online nell'interprete CJam .

Come funziona

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 byte

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

Questa è una funzione anonima che visualizza B , V e I (dall'alto verso il basso) dallo stack e in cambio lascia un singolo array nello stack.

Provalo online nell'interprete CJam .

Come funziona

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.

1

Rubino, 48 byte

Penso che questo sia conforme alle regole, ma per favore controlla.

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

Funzione senza nome che accetta i tre array come input. Emette una stringa che può essere analizzata senza ambiguità in una matrice di numeri con l'espressione rubyx.split(/:+/).map(&:to_i) .

Casi di prova su ideone .

Potrei salvare altri 3 byte, ma il formato di output [1,2,[nil,5]] sta allungando un po 'troppo le regole, anche se non è ambiguo.


Penso che il formato attuale sia ok. Le matrici nidificate con nilvalori di interfogliatura sono un po 'allungate. Ma in entrambi i casi questo non sta vincendo il concorso, quindi non sono davvero preoccupato per entrambi.
Martin Ender,

1

R, 60

Come una funzione senza nome che accetta b, v e i

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

Espande b con NA Riempie gli spazi dove richiesto con v Restituisce il vettore senza NA

> 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

1

Java, 253, 226, 219, 209

non esattamente un vincitore, ma vabbè.

Supponendo che B, V e I non siano nulli. v (minuscola v) è la lunghezza delle matrici valori / indici. R è l'array restituito. r è la lunghezza dell'array restituito. x, y e io siamo tutti ints temporanei.

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

allargato:

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

1

APL, 22 byte

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

In ⎕IO ← 0 per abbinare i casi di test.

È un algoritmo standard: il vettore indice del primo argomento viene aggiunto agli indici dati (3 ° argomento). calcola la permutazione che ordinerebbe gli indici in ordine crescente. Poiché l'algoritmo di ordinamento di APL è stabile per definizione, la permutazione calcolata colloca l'elemento della catenazione del secondo e primo argomento nel posto giusto.

Per esempio :

    {(∊⌽2↑⍵)[⍋(2⊃⍵),⍳≢⊃⍵]}(5 1 4 1 3)(0 0 7)(5 0 3)
0 5 1 4 7 1 3 0
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.