Fusil à tableau généralisé


22

Un golf simple pour commencer la semaine! Vous disposez de trois tableaux: le tableau de base B , le tableau de valeurs V et le tableau d'index I . Vous devez produire un autre tableau dans lequel les valeurs de Vsont insérées dans Bles indices spécifiés par I. Voici un exemple:

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

Les indices pointent aux positions suivantes dans le tableau de base:

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

Ainsi, en insérant les éléments correspondants du tableau de valeurs, le résultat devrait être:

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

Règles

Vous pouvez écrire un programme ou une fonction, en prenant une entrée via STDIN (ou l'alternative la plus proche), des arguments de ligne de commande ou des arguments de fonction et sortir le résultat via STDOUT (ou l'alternative la plus proche), la valeur de retour de la fonction, ou en modifiant le tableau donné comme Bparamètre .

Si votre soumission est une fonction Iet Vpeut être modifiée de n'importe quelle manière, ainsi que Bsi elle n'est pas utilisée pour la sortie.

Vous pouvez émettre les hypothèses suivantes sur l'entrée:

  • Tous les éléments du tableau de base et de valeur seront des entiers non négatifs.
  • Le tableau de valeurs aura au plus un élément de plus que le tableau de base.
  • Le tableau de valeurs et le tableau d'index auront le même nombre d'éléments.
  • Le tableau d'index ne contiendra pas d'indices répétés et tous les indices seront dans la plage.
  • Les tableaux de base et de valeur peuvent contenir des éléments répétés.
  • Tout ou partie des tableaux peut être vide.
  • Vous ne devez pas supposer que les indices sont donnés dans un ordre particulier.
  • Vous pouvez recevoir des entrées et produire des sorties dans n'importe quel format de chaîne ou de liste pratique et sans ambiguïté. Vous pouvez également choisir de recevoir les trois tableaux dans un ordre différent.
  • Vous pouvez choisir entre l'indexation basée sur 0 et celle basée sur 1.

Il s'agit du code golf, donc la réponse la plus courte (en octets) l'emporte.

Cas de test

Donné au format B V I => Resultpour l'indexation basée sur 0. Si vous utilisez une indexation basée sur 1, incrémentez les éléments du troisième tableau de 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]

Faites-moi savoir si vous rencontrez d'autres cas de bord intéressants, et je les ajouterai.

Classement

Voici un extrait de pile pour générer à la fois un classement régulier et un aperçu des gagnants par langue.

Pour vous assurer que votre réponse s'affiche, veuillez commencer votre réponse avec un titre, en utilisant le modèle Markdown suivant:

# Language Name, N bytes

Nest la taille de votre soumission. Si vous améliorez votre score, vous pouvez conserver les anciens scores dans le titre, en les barrant. Par exemple:

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


4
Que pensez-vous NULLd'un tableau vide pour les langues où se trouve un tableau vide NULL?
Alex A.

@AlexA. Si c'est une commune / la représentation du tableau vide dans ladite langue (s), je suis très bien avec ça.
Martin Ender

3
Un golf simple ? C'est la chose la plus difficile que j'ai faite à CJam toute la semaine. : P
Dennis

Réponses:


13

Pyth, 14 octets

s.icFPQmedSCtQ

Manifestation.

Ce programme prend les entrées comme un triplet de listes dans l'ordre Base, Indices, Values.

Explication sur l'exemple [5, 1, 4, 1, 3], [5, 0, 3], [0, 0, 7]:

  1. Prenez l'entrée: implicite, Q est l'entrée.

  2. Faire l'index, les paires de valeurs: CtQ=[(5, 0), (0, 0), (3, 7)]

  3. Triez les paires dans un ordre d'index croissant: SCtQ =[(0, 0), (3, 7), (5, 0)]

  4. Retirez la valeur de chaque paire: medSCtQ =[0, 7, 0]

  5. Divisez la liste de base à l'emplacement des indices: cFPQ =[[], [5, 1, 4], [1, 3], []]

  6. Entrelacement 3 et 4: .icFPQmedSCtQ =[[], 0, [5, 1, 4], 7, [1, 3], 0, []]

  7. Combinez en une seule liste: s.icFPQmedSCtQ=[0, 5, 1, 4, 7, 1, 3, 0]


Zut. Depuis quand avons-nous une méthode d'entrelacement? Je voulais juste poster ssC,cFPQamedSCtQ].
Jakube

5
@Jakube isaac l'a commis sournoisement il y a 6 jours.
orlp


3
@Jakube puisque Pyth peut se développer pour résoudre n'importe quel problème. C'est le problème des langues de golf. Les langues ésotériques existent pour le bien des langues ésotériques; car ils sont conçus * par la suite.
sentiao

@sentiao Pour être honnête, le langage hôte (Python) a été entrelacé sous un nom différent pendant un certain temps.
Mego

16

Python 2, 54

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

Prend l'entrée comme B,I,V . Modifie l'entrée Blors de l'appel (merci à Martin Büttner de me le rappeler c'est possible).

Utilise mappour appeler B.insertsur chaque paire index / élément. Pour éviter le problème du déplacement des index de liste à mesure que les éléments sont insérés, trie les paires par ordre décroissant d'index par un laid zip / tri / décompression. Sinon pour la question du changement, nous pourrions simplement fairemap(B.insert,*X) .

Ancienne méthode (65):

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

5

Haskell, 62 octets

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

Exemple d'utilisation: f [5,1,4,1,3] [0,0,7] [5,0,3] -> [0,5,1,4,7,1,3,0].

Comment ça marche: augmentez la liste de base avec des indices "et demi" à partir de 0.5(par ex.[(0.5,5),(1.5,1),(2.5,4),(3.5,1),(4.5,3)] ) et concaténez-la avec les paires index-valeur. Triez et jetez l'index.

Remarque : je ne sais pas si je triche ici. D'un point de vue mathématique, c'est bien, mais un programmeur pourrait faire valoir que la liste des indices [5,0,3]n'est pas une liste de Integerscomme demandé, mais une liste de Fractionals(pour être exact, le type est polymorphe, mais doit appartenir à la Fractionalclasse, par exempleFloat ou Double).


5

Rubis, 60 59 53 octets

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

Et la version non golfée

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

2
Vous pouvez raccourcir ce en faisant une fonction sans nom au lieu: ->a,b,c{...}. Il y a aussi des chances qu'il insertn'y ait pas besoin de parenthèses.
Martin Ender

@ MartinBüttner Je connaissais la fonction sans nom avec le lambda, mais je ne pensais pas que c'était dans l'esprit du défi (qui demande généralement une fonction nommée). Merci d'avoir repéré les parens.
Dylan Frese

À moins que le défi ne demande spécifiquement une fonction nommée, les fonctions non nommées sont toujours acceptables . Et je n'ai pas demandé de fonction nommée (je ne le fais jamais;)).
Martin Ender

5

CJam, 34 23 18 octets

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

Ma première soumission CJam. Les conseils sont les bienvenus, je suis sûr qu'il y a beaucoup à jouer au golf.

16 octets enregistrés avec l'aide de @ MartinBüttner et @Dennis.

Fonction attendant l'entrée sur la pile dans l'ordre B V I (I est le plus haut).

Exemple d'utilisation:

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

Méthode:

  • associer le ie élément du tableau aveci+0.5
  • associer des valeurs d'insertion à des positions d'insertion
  • fusionner les deux tableaux résultants
  • tableau de tri basé sur les éléments de position
  • conserver les éléments de valeur

Cette approche en virgule flottante est très intelligente et (malheureusement) meilleure que la mienne. Vous pouvez descendre à 19 octets avec q~.5fm.\2/\ee+$1f=pet à 18 octets en utilisant une fonction anonyme:{.5fm.\2/\ee+$1f=}
Dennis

Même idée sans l'astuce virgule flottante: {.\2/\ee+{0=}$1f=}(toujours 18 octets)
Dennis

@Dennis Merci, je n'ai pas pu trouver l' get array elementopérateur pour 1f=. Je le laisserai cependant comme un programme complet.
randomra

Ton appel. Cela vous dérange-t-il que je vous demande pourquoi vous vous opposez à la publication d'une fonction?
Dennis

@Dennis Je viens de démarrer CJam et je ne savais pas comment utiliser les fonctions. Maintenant, je l'ai compris alors j'ai changé la réponse à cela.
randomra

5

K, 22 21 octets

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

Nous définissons une fonction {…}à 3 arguments avec les variables implicites x, yet zreprésentant respectivement la liste de départ, la liste de valeurs et la liste d'index. L'opérateur "cut" ( _) est utilisé pour séparer la liste de départ en une liste triée d'indices donnés ( (z@<z)). Nous entrelacons les valeurs (après les avoir triées de manière correspondante) avec les morceaux séparés du tableau d'origine en formant une liste ( (a;b)), en prenant sa transposition (+ ) et en aplatissant le résultat (,// ).

Exemple d'utilisation:

  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

Les espaces autour du trait de soulignement sont nécessaires car K autorise les traits de soulignement dans les identificateurs. K5 supprime cette ambiguïté potentielle. Si nous pouvions compter sur les indices en ordre croissant et que les traits de soulignement n'étaient pas des identificateurs valides, nous pourrions utiliser le programme 13 octets bien plus agréable:

{,//+(y;z_x)}

(soupir.)

modifier:

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

Rompre la symétrie, mais nous pouvons enregistrer un octet en utilisant le crochet-indexation ( […]) au lieu de l' @opérateur d'indexation infixe . Habituellement, cela rallonge les programmes, mais dans ce cas, nous avions quand même besoin de parens pour trier zavant d'effectuer la coupe.


4

Pyth, 17 octets

ssC,cFPQamedSCtQ]

@isaacg a déjà battu ma solution. Mais comme ma documentation est terminée, je vais tout de même la publier.

Cela prend l'entrée au format B, I, V. Vous pouvez l'essayer ici: démonstration ou suite de tests

Explication:

J'utilise l'exemple B = [5,1,4,1,3], I = [5,0,3], V = [0,0,7]de l'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

Une fonction avec 3 paramètres de tableau, renvoyant un tableau. Bizarrement, cette fonction modifie son iparamètre (comme l'a gentiment permis OP)

Testez l'exécution de l'extrait, Firefox uniquement comme d'habitude.

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>


Par curiosité, qu'en est-il du code qui le rend spécifique à Firefox? Est-ce parce que c'est ES6?
Alex A.

@ AlexA.it parce que c'est ES6, oui. En particulier, le fat arrow functionn'est pas implémenté même dans la version développeur de Chrome (AFAIK)
edc65

En effet, même la version canarienne de Chrome ne le prend pas en charge.
DocMax

4

Mathematica, 52 51 octets

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

Exemple:

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}

Explication:

En utilisant l'exemple ci-dessus.

  • 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}
  • Prenez ensuite l'union (triée) de ces deux listes. (=>{0.5 -> 0, 1 -> 5, 2 -> 1, 3 -> 4, 3.5 -> 7, 4 -> 1, 5 -> 3, 5.5 -> 0} )
  • Et puis prenez le dernier élément de chaque paire. (=> {0, 5, 1, 4, 7, 1, 3, 0})


3

R, 75 octets

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}

Cela crée une fonction sans nom. Pour l'appeler, donnez-lui un nom, par exemple f=function.... Notez que les tableaux doivent être indexés 1 car c'est exactement ainsi que R roule.

Non golfé + explication:

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
}

Exemples:

> 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

Les suggestions sont les bienvenues comme toujours!


2

CJam, 19 octets

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

Ceci est un programme complet qui lit les tableaux B , I et V (un par ligne, dans cet ordre) à partir de STDIN.

Essayez-le en ligne dans l' interpréteur CJam .

Comment ça marche

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 octets

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

Il s'agit d'une fonction anonyme qui extrait B , V et I (de haut en bas) de la pile et laisse en retour un seul tableau sur la pile.

Essayez-le en ligne dans l' interpréteur CJam .

Comment ça marche

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

Rubis, 48 ​​octets

Je pense que cela est conforme aux règles, mais veuillez vérifier.

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

Fonction sans nom prenant les trois tableaux en entrée. Génère une chaîne qui peut être analysée sans ambiguïté dans un tableau de nombres avec l'expression rubyx.split(/:+/).map(&:to_i) .

Cas de test sur ideone .

Je pourrais économiser 3 octets de plus, mais le format de sortie [1,2,[nil,5]]étire un peu trop les règles, bien que ce soit sans ambiguïté.


Je pense que le format actuel est correct. Les tableaux imbriqués avec des nilvaleurs d' entrelacement sont un peu extensibles. Mais dans les deux cas, cela ne gagne pas le concours, donc je ne suis pas vraiment inquiet de toute façon.
Martin Ender

1

R, 60

Comme une fonction sans nom qui prend b, v et i

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

Développe b avec NAs Remplit les lacunes où nécessaire avec v Renvoie le vecteur sans NAs

> 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

pas exactement un gagnant, mais bon.

En supposant que B, V et I ne sont pas nuls. v (minuscule v) est la longueur des tableaux de valeurs / indicateurs. R est le tableau retourné. r est la longueur du tableau retourné. x, y et i sont tous des entiers temporaires.

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

étendu:

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 octets

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

Dans ⎕IO ← 0 pour faire correspondre les cas de test.

C'est un algorithme standard: le vecteur d'index du premier argument est ajouté aux index donnés (3e argument). calcule la permutation qui trierait les index dans l'ordre croissant. Puisque l'algorithme de tri d'APL est stable par définition, la permutation calculée place l'élément de la caténation des deuxième et premier arguments au bon endroit.

Par exemple :

    {(∊⌽2↑⍵)[⍋(2⊃⍵),⍳≢⊃⍵]}(5 1 4 1 3)(0 0 7)(5 0 3)
0 5 1 4 7 1 3 0
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.