Coletar e colocar itens

13

O objetivo desse desafio é coletar itens selecionados em uma lista e movê-los para um determinado local na lista.

Como um exemplo visual, pegue os valores de entrada (representados por números inteiros em caixa preta) e uma lista correspondente de valores de verdade onde true indica que o item está selecionado (representado por caixas azuis, onde Té verdade e Fé falso):

insira a descrição da imagem aqui

O primeiro passo lógico é separar os itens marcados em verdade e não em suas listas correspondentes. Observe que a ordem relativa em cada lista deve ser mantida (ou seja, a ordem dos itens selecionados deve ser 1,4,5e a ordem dos itens não selecionados 2,3,6,7)!

insira a descrição da imagem aqui

A segunda etapa lógica recebe um índice na lista restante de itens não selecionados, insira todos os itens selecionados antes do item no índice especificado. Supondo que a indexação comece em 0, suponha que você queira inserir a seleção no índice 3. Isso corresponde ao local antes da 7caixa, portanto, os itens selecionados devem ser inseridos antes do 7.

insira a descrição da imagem aqui

A solução final é então 2,3,6,1,4,5,7.

Observe que este diagrama lógico mostra uma maneira de fazer isso; seu programa não precisa executar as mesmas etapas lógicas, desde que a saída sempre produz o mesmo resultado observável.

Entrada

Seu programa recebe três entradas:

  1. Uma lista de números inteiros representando os itens. Esta pode ser uma lista vazia. Essa lista sempre será composta por números inteiros positivos únicos, não necessariamente na ordem de classificação (ou seja, 5 não estarão na lista duas vezes).
  2. Uma lista de valores de verdade / falsidade com o mesmo comprimento da lista de itens, em que um valor de verdade representa que o item no mesmo índice foi selecionado.
  3. Um número inteiro que representa onde inserir a seleção. Você pode escolher qual é o índice do primeiro item da lista, desde que seja constante em todas as execuções do seu programa (por exemplo, o primeiro item pode ser o índice 0 ou o índice 1). Especifique a que convenção seu programa adere. Este índice deve estar no intervalo [starting_idx, ending_idx+1], ou seja, sempre será um índice válido. Para o índice de caso ending_idx+1, a seleção deve ser inserida no final da lista. Você pode supor que esse número inteiro caiba no tipo inteiro nativo do seu idioma.

A entrada pode vir de qualquer fonte desejada (stdio, parâmetro de função, etc.)

Resultado

A saída é uma lista que representa a sequência final de itens. Pode ser para qualquer fonte desejada (stdio, valor de retorno, parâmetro de saída da função, etc.). Você tem permissão para modificar qualquer uma das entradas no local (por exemplo, dada uma lista modificável como um parâmetro de função e ter sua função operando no local nessa lista).

Casos de teste

Todos os seguintes casos de teste assumem indexação baseada em 0. Eu usei 0 e 1 para indicar valores de falsidade / verdade respectivamente para a máscara de seleção.

Os casos de teste têm listas formatadas como [a,b,c], mas desde que suas listas de entrada representem uma sequência ordenada finita, tudo bem.

Entrada:

[]
[]
0

Resultado:

[]

Entrada:

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

Resultado:

[2,3,6,1,4,5,7]

Entrada:

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

Resultado:

[1,4,5,2,3,6,7]

Entrada:

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

Resultado:

[2,3,6,7,1,4,5]

Entrada:

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

Resultado:

[1,2,3,4,5,6,7]

Entrada:

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

Resultado:

[1,2,3,4,5,6,7]

Entrada:

[1,3,2,5,4,6]
[1,0,0,1,1,0]
3

Resultado:

[3,2,6,1,5,4]

Pontuação

Isso é código de golfe; a resposta mais curta em bytes vence. As brechas padrão são proibidas. Você tem permissão para usar quaisquer embutidos desejados.

helloworld922
fonte
A entrada e a saída podem ser como '"1 2 3", "1 0 0", 1'?
betseg
Sim, qualquer coisa que represente duas seqüências inteiras ordenadas finitas e um índice inteiro é bom.
precisa
A primeira matriz conterá itens negativos ou zero?
Leaky Nun
Quero dizer não, mas também estou intrigado com a solução que você tem e que exige isso. Então, sim, você pode assumir que a primeira lista contém apenas um número inteiro positivo.
precisa
@PeterTaylor no. Corrigi-o para ler "Uma lista de valores verdade / falsidade ...". Existe um bom nome para descrever o "tipo" de valores de verdade / falsidade? Tipo booleano?
precisa

Respostas:

10

MATL, 9 bytes

&)i:&)bwv

Esta solução aceita uma matriz de valores T(true) e F(false) como a segunda entrada. Também para o primeiro caso de teste, com matrizes vazias, ele não produz saída.

Experimente Online! e uma versão ligeiramente modificada para todos os casos de teste.

Explicação

    % Implicitly grab the first two inputs
&)  % Index into the first array using the boolean, places two items on the stack:
    % 1) The values where the boolean is TRUE and 2) the values where it is FALSE.
i   % Explicitly grab the third input (N)
:   % Create an array from 1...N
&)  % Index into the FALSE group using this array as an index. Puts two items on the stack:
    % 1) The first N elements of the FALSE group and 2) other members of the FALSE group
b   % Bubble the TRUE members up to the top of the stack
w   % Flip the top two stack elements to get things in the right order
v   % Vertically concatenate all arrays on the stack
    % Implicitly display the result
Suever
fonte
5

Mathematica, 66 62 bytes

Salvo 4 bytes de @MartinEnder .

a=#2~Extract~Position[#3,#4>0]&;##&@@@Insert[##~a~0,##~a~1,#]&

Função anônima. Pega o índice baseado em 1, a lista e os marcadores como entrada e retorna a lista reordenada como saída.

LegionMammal978
fonte
3

Haskell, 70 bytes

m%n=[e|(e,b)<-zip m n,b]
(l#s)p|(h,t)<-splitAt p$l%(not<$>s)=h++l%s++t

Exemplo de uso: ([1,2,3,4,5,6,7]#[True,False,False,True,True,False,False]) 3-> [2,3,6,1,4,5,7].

Como funciona:

m%n=[e|(e,b)<-zip m n,b]        -- helper function, that extracts the elements of m
                                -- with corresponding True values in n
(l#s)p                          -- l: list of values
                                   s: list of booleans
                                   p: position to insert
  |                   (not<$>s) -- negate the booleans in s
                    l%          -- extract elements of l
          splitAt p             -- split this list at index p
   (h,t)<-                      -- bind h to the part before the split
                                -- t to the part after the split
     = h++l%s++t                -- insert elements at True positions between h and t
nimi
fonte
3

JavaScript (ES6), 76 bytes

(a,b,c)=>(d=a.filter((_,i)=>!b[i]),d.splice(c,0,...a.filter((_,i)=>b[i])),d)
Neil
fonte
1

Gelatina , 10 bytes

¬+\>⁵Ḥ³oỤị

Experimente online!

Como funciona

¬+\>⁵Ḥ³oỤị  Main link.
            Arguments: x (list of Booleans), y (list of inputs), z (index)
¬           Logical NOT; invert all Booleans in x.
 +\         Take the cumulative sum.
            This replaces each entry with the number of zeroes up to that entry.
   >⁵       Compare the results with z.
            This yields 0 for the first z zeroes, 1 for all others. The behavior
            for ones is not important.
    Ḥ       Unhalve; multiply the previous resulting by 2.
     ³o     Take the element-wise logical NOT of x and the previous result.
            This replaces all but the first z zeroes in x with twos.
       Ụ    Grade up; sort the indices of the result according to the corr. values.
        ị   Retrieve the items of y at those indices.
Dennis
fonte
0

C #, 132 bytes

int[]r(int[]a,bool[]b,int l){var x=a.Where((i,j)=>!b[j]);return x.Take(l).Concat(a.Where((i,j)=>b[j])).Concat(x.Skip(l)).ToArray();}

ungolfed:

    public static int[] r(int[] a,bool[] b,int l)
    {
        var x = a.Where((i, j) => !b[j]);
        return x.Take(l).Concat(a.Where((i, j) => b[j])).Concat(x.Skip(l)).ToArray();
    }

idéias de melhoria apreciadas.

downrep_nation
fonte
0

Python 3, 91 bytes

def f(a,x,i):b=[c for c,z in zip(a,x)if z<1];return b[:i]+[c for c in a if(c in b)<1]+b[i:]

Onde aestá a lista de elementos / números, xé a True/Falselista e ié o índice.

Versão multilinha para melhor legibilidade:

def f(a,x,i):
    b=[c for c,z in zip(a,x)if z<1]
    return b[:i]+[c for c in a if(c in b)<1]+b[i:] 

Como funciona?

A chamada para zip(a,x)os resultados em uma lista de tuplas em que cada um deles contém a informação: (element,0|1). Em seguida, uma compreensão da lista é usada para determinar os elementos que têm um 0/Falsevalor associado e os armazena na variável b.

Portanto, [c for c,z in zip(a,x)if z<1]cria uma lista que contém todos os elementos que têm um valor 0( False) associado.

Depois disso, a lista de elementos que têm um True|1valor associado (o qual é determinado pela verificação de que os elementos de anão estão presentes em b: [c for c in a if(c in b)<1]) é inserido na lista com todos os elementos que têm um 0( Falsevalor) associado (lista b) no índice especificado ie a lista resultante é retornada.

Ioannes
fonte
0

Python 3, 106 93 bytes

def f(x,y,z):
 t,f=[],[]
 for n in range(len(x)):(f,t)[y[n]].append(x[n])
 f[z:z]=t
 return f

Versão antiga:

def f(x,y,z):
 t,f=[],[]
 for n in range(len(x)):
  if y[n]:t+=[x[n]]
  else:f+=[x[n]]
 f[z:z]=t
 return f
Daniel
fonte