Generalized Array Riffle


22

Um simples golfe para começar a semana! Você recebe três matrizes: a matriz base B , a matriz de valor V e a matriz de índice I . Você deve produzir outra matriz na qual os valores Vsão inseridos Bnos índices especificados por I. Aqui está um exemplo:

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

Os índices apontam para as seguintes posições na matriz base:

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

Então, inserindo os elementos correspondentes da matriz de valores, o resultado deve ser:

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

Regras

Você pode escrever um programa ou função, recebendo entradas via STDIN (ou alternativa mais próxima), argumentos de linha de comando ou argumentos de função e gerar o resultado via STDOUT (ou alternativa mais próxima), valor de retorno da função ou modificando a matriz fornecida como Bparâmetro .

Se o seu envio for uma função Ie Vpuder ser modificado de qualquer forma, assim como Bse não for usado para saída.

Você pode fazer as seguintes suposições sobre a entrada:

  • Todos os elementos da matriz de base e valor serão números inteiros não negativos.
  • A matriz de valores terá no máximo mais um elemento que a matriz base.
  • A matriz de valores e a matriz de índices terão o mesmo número de elementos.
  • A matriz de índice não conterá índices repetidos e todos os índices estarão dentro do intervalo.
  • As matrizes base e valor podem conter elementos repetidos.
  • Qualquer uma ou todas as matrizes podem estar vazias.
  • Você não deve assumir que os índices são fornecidos em qualquer ordem específica.
  • Você pode receber entrada e produzir saída em qualquer formato conveniente ou inequívoco de sequência ou lista. Você também pode optar por receber as três matrizes em uma ordem diferente.
  • Você pode escolher entre indexação com base em 0 e com base em 1.

Isso é código de golfe, então a resposta mais curta (em bytes) vence.

Casos de teste

Fornecido no formato B V I => Resultpara indexação baseada em 0. Se você estiver usando a indexação baseada em 1, aumente os elementos da terceira matriz em 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]

Deixe-me saber se você se deparar com outros casos interessantes, e eu os adicionarei.

Entre os melhores

Aqui está um snippet de pilha para gerar uma classificação regular e uma visão geral dos vencedores por idioma.

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

# Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

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


4
Como você se sente em relação NULLa uma matriz vazia para idiomas em que está uma matriz vazia NULL?
Alex A.

@AlexA. Se é comum / a representação da matriz vazia no (s) dito (s) idioma (s), eu estou bem com isso.
Martin Ender

3
Um simples golfe ? Essa foi a coisa mais difícil que fiz no CJam a semana toda. : P
Dennis

Respostas:


13

Pitão, 14 bytes

s.icFPQmedSCtQ

Demonstração.

Este programa recebe as entradas como uma tupla de 3 listas na ordem Base, Índices, Valores.

Explicação no exemplo [5, 1, 4, 1, 3], [5, 0, 3], [0, 0, 7]:

  1. Tome a entrada: implícito, Q é a entrada.

  2. Faça o índice, pares de valores: CtQ=[(5, 0), (0, 0), (3, 7)]

  3. Classifique os pares em ordem crescente de índice: SCtQ=[(0, 0), (3, 7), (5, 0)]

  4. Tire o valor de cada par: medSCtQ=[0, 7, 0]

  5. Divida a lista base no local das indicações: cFPQ=[[], [5, 1, 4], [1, 3], []]

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

  7. Combine em uma lista: s.icFPQmedSCtQ=[0, 5, 1, 4, 7, 1, 3, 0]


Droga. Desde quando temos um método de intercalação? Só queria postar ssC,cFPQamedSCtQ].
Jakube 18/05

5
O @Jakube isaac o cometeu sorrateiramente há 6 dias.
orlp 18/05/19


3
@Jakube desde Pyth pode crescer para resolver qualquer problema. Esse é o problema com as línguas do golfe. As línguas esotéricas existem por causa das línguas esotéricas; como eles são projetados * depois.
sentiao

@sentiao Para ser justo, a linguagem host (Python) teve intercalação sob um nome diferente por um tempo.
Mego 30/06

16

Python 2, 54

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

Toma entrada como B,I,V. Modifica a entrada Bquando chamada (obrigado a Martin Büttner por me lembrar que isso é possível).

Usa mappara chamar B.insertcada par de índice / elemento. Para evitar que os índices da lista sejam alterados à medida que os elementos são inseridos, classifique os pares em ordem decrescente do índice com um feio zip / classificar / descompactar. Se não fosse a questão da mudança, poderíamos simplesmente fazer map(B.insert,*X).

Método antigo (65):

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

5

Haskell, 62 bytes

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

Exemplo de uso: f [5,1,4,1,3] [0,0,7] [5,0,3]-> [0,5,1,4,7,1,3,0].

Como funciona: aumente a lista base com índices "e meio" começando em 0.5(por exemplo [(0.5,5),(1.5,1),(2.5,4),(3.5,1),(4.5,3)]) e concatenando-a com os pares de valor-índice. Classifique e descarte o índice.

Observação : não sei se estou trapaceando aqui. Do ponto de vista matemático, tudo bem, mas um programador pode argumentar que a lista de índices [5,0,3]não é uma lista Integersconforme solicitado, mas uma lista de Fractionals(para ser exato, o tipo é polimórfico, mas deve pertencer à Fractionalclasse, por exemplo, Floatou Double)


5

Ruby, 60 59 53 bytes

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

E a versão ungolfed

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

2
Você pode encurtar este, tornando-a uma função sem nome em vez disso: ->a,b,c{...}. Também as chances são de insertque não precisa de parênteses.
Martin Ender

@ MartinBüttner Eu sabia sobre a função não nomeada com o lambda, mas não sentia que isso estivesse no espírito do desafio (que geralmente pede uma função nomeada). Obrigado por detectar os parênteses, no entanto.
Dylan Frese

A menos que o desafio solicite especificamente uma função nomeada, funções sem nome são sempre aceitáveis . E eu não pedi uma função nomeada (nunca peço;)).
Martin Ender

5

CJam, 34 23 18 bytes

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

Minha primeira submissão ao CJam. Conselhos são bem-vindos, tenho certeza de que há muito para jogar golfe.

16 bytes salvos com a ajuda de @ MartinBüttner e @Dennis.

Função que espera entrada na pilha em ordem B V I(I é a mais alta).

Exemplo de uso:

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

Método:

  • emparelhe o ielemento th da matriz comi+0.5
  • emparelhar valores de inserção com posições de inserção
  • mesclar as duas matrizes resultantes
  • matriz de classificação com base nos elementos de posição
  • manter elementos de valor

Essa abordagem de ponto flutuante é muito inteligente e (infelizmente) melhor que a minha. Você pode obter até 19 bytes com q~.5fm.\2/\ee+$1f=pe para 18 bytes usando uma função anônima:{.5fm.\2/\ee+$1f=}
Dennis

Mesma ideia sem o truque de ponto flutuante: {.\2/\ee+{0=}$1f=}(ainda 18 bytes)
Dennis

@ Dennis Obrigado, não consegui encontrar o get array elementoperador para 1f=. Vou deixar como um programa completo.
Aleatório # 20/15

Sua chamada. Você se importa de me perguntar por que você se opõe a postar uma função?
Dennis

@ Dennis Acabei de iniciar o CJam e não sabia ao certo como usar as funções. Agora eu descobri, então mudei a resposta para isso.
Random # 20/15

5

K, 22 21 bytes

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

Definimos uma função 3 argumento {…}com as variáveis implícitas x, ye zrepresentando a ordem de entrada, a lista de valores e a lista de dice, respectivamente. O operador "recortar" ( _) é usado para dividir a lista inicial na lista classificada dos índices fornecidos ( (z@<z)). Entrelaçamos valores (depois de ordená-los de maneira correspondente) com os pedaços divididos da matriz original, formando uma lista ( (a;b)), pegando sua transposição ( +) e achatando o resultado ( ,//).

Exemplo de uso:

  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

Os espaços ao redor do sublinhado são necessários porque K permite sublinhados nos identificadores. O K5 remove essa ambiguidade potencial. Se pudéssemos contar com os índices que vinham em ordem crescente e os sublinhados não eram identificadores válidos, poderíamos usar o programa de 13 bytes, muito mais agradável:

{,//+(y;z_x)}

(suspiro.)

editar:

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

Quebra a simetria, mas podemos salvar um byte usando bracket-indexing ( […]) em vez do @operador de indexação infix . Normalmente, isso torna os programas mais longos, mas, neste caso, precisávamos de parênteses para ordenar zantes de executar o corte.


4

Pitão, 17 bytes

ssC,cFPQamedSCtQ]

@isaacg já venceu minha solução. Mas como eu terminei minha documentação, vou postá-la de qualquer maneira.

Isso leva a entrada no formato B, I, V. Você pode experimentá-lo aqui: Demonstration or Test Suite

Explicação:

Estou usando o exemplo B = [5,1,4,1,3], I = [5,0,3], V = [0,0,7]do 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

Uma função com 3 parâmetros de matriz, retornando uma matriz. Estranhamente, essa função modifica seu iparâmetro (conforme gentilmente permitido pelo OP)

Teste a execução do snippet, o Firefox apenas como de costume.

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>


Por curiosidade, e o código o torna específico para o Firefox? É porque é o ES6?
18715 Alex A.

@ AlexA.it é porque é ES6, sim. Particularmente o fat arrow functionnão é aplicado mesmo na versão do desenvolvedor do Chrome (AFAIK)
edc65

Na verdade, nem mesmo a versão Canary do Chrome é compatível.
DocMax

4

Mathematica, 52 51 bytes

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

Exemplo:

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}

Explicação:

Usando o exemplo acima.

  • 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}
  • Em seguida, faça a união (classificada) dessas duas listas. (=> {0.5 -> 0, 1 -> 5, 2 -> 1, 3 -> 4, 3.5 -> 7, 4 -> 1, 5 -> 3, 5.5 -> 0})
  • E então pegue o último elemento de cada par. (=> {0, 5, 1, 4, 7, 1, 3, 0})


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}

Isso cria uma função sem nome. Para chamá-lo, dê um nome, por exemplo f=function.... Observe que as matrizes devem ser indexadas 1, porque é assim que R é rolado.

Ungolfed + explicação:

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
}

Exemplos:

> 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

Sugestões são bem-vindas como sempre!


2

CJam, 19 bytes

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

Este é um programa completo que lê as matrizes B , I e V (uma por linha, nessa ordem) do STDIN.

Experimente online no intérprete CJam .

Como funciona

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

Essa é uma função anônima que abre B , V e I (de cima para baixo) da pilha e deixa uma única matriz na pilha em troca.

Experimente online no intérprete CJam .

Como funciona

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

Ruby, 48 bytes

Acho que isso está em conformidade com as regras, mas verifique.

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

Função sem nome, tendo as três matrizes como entrada. Produz uma string que pode ser analisada sem ambiguidade em uma matriz de números com a expressão ruby x.split(/:+/).map(&:to_i).

Casos de teste em ideone .

Eu poderia salvar mais 3 bytes, mas o formato de saída [1,2,[nil,5]]está esticando as regras um pouco demais, embora seja inequívoco.


Eu acho que o formato atual está bom. Matrizes aninhadas com nilvalores de intercalação são um pouco exageradas. Mas, em ambos os casos, isso não está vencendo o concurso, então não estou realmente preocupado com isso de qualquer maneira.
Martin Ender

1

R, 60

Como uma função sem nome que recebe b, ve eu

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

Expande b com NAs Preenche as lacunas onde necessário com v Retorna o vetor sem 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

não é exatamente um vencedor, mas tudo bem.

Supondo que B, V e eu não sejam nulos. v (v minúsculo) é o comprimento das matrizes Valores / Indicações. R é a matriz retornada. r é o comprimento da matriz retornada. x, ye i são todos ints temporários.

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

expandido:

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 bytes

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

Em ⎕IO ← 0 para corresponder aos casos de teste.

É um algoritmo padrão: o vetor de índice do primeiro argumento é anexado aos índices fornecidos (terceiro argumento). calcula a permutação que classificaria os índices em ordem crescente. Como o algoritmo de classificação da APL é estável por definição, a permutação calculada coloca o elemento da catenação do segundo e primeiro argumento no lugar certo.

Por exemplo :

    {(∊⌽2↑⍵)[⍋(2⊃⍵),⍳≢⊃⍵]}(5 1 4 1 3)(0 0 7)(5 0 3)
0 5 1 4 7 1 3 0
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.