Separe uma lista em partes indexadas pares e indexadas ímpares


26

Inspirado por esta pergunta:

Crie uma função (ou um programa completo) que receba uma lista de números e a reorganize, de forma que os números indexados pares apareçam primeiro e os números indexados ímpares sigam. Os valores dos números em si não afetam a ordem - apenas seus índices. Todos os índices são baseados em zero.

Por exemplo:

Entrada: [0, 1, 2, 3, 4]

Saída: [0, 2, 4, 1, 3]

Outro exemplo:

Entrada: [110, 22, 3330, 4444, 55555, 6]

Saída: [110, 3330, 55555, 22, 4444, 6]

Use a representação mais natural para listas que seu idioma possui. Não há limitações de complexidade (por exemplo, alocar uma lista temporária é OK - não é necessário fazer isso no local).

PS Deve funcionar para a lista vazia (entrada vazia => saída vazia).


Esta é efetivamente o inverso das respostas atuais a esta pergunta
Peter Taylor

Podemos assumir que todos os elementos da lista são positivos ou não negativos ou algo assim?
Martin Ender

@ MartinBüttner Suponha algo razoável, talvez até que eles estejam no intervalo de 0 a 255.
anatolyg


Podemos gerar uma lista separada por vírgula?
Oliver

Respostas:



21

Python, 23 bytes

lambda x:x[::2]+x[1::2]

Experimente online


1
Por quê lambda ? Por que não muou nu? : P
Kritixi Lithos

1
@rayryeng eu só estava brincando como você pode ver pela ": P" no final do meu comentário :)
Kritixi Lithos

5
Sim, você definitivamente deve substituir lambdapor λe reduzir byte contagem por 5! : P
anatolyg

3
@anatolyg soa como uma ideia para envio de PEP !
Nick T

2
@ThomasKwa É a ferramenta certa para o trabalho: P
Mego

16

Pitão, 5

o~!ZQ

Experimente online ou execute um Conjunto de Testes

Explicação

o~!ZQ    ## implicit: Z = 0; Q = eval(input)
o   Q    ## sort Q using a supplied function
 ~!Z     ## Use the old value of Z, then set Z to be not Z
         ## This assigns a weight to each number in the list, for example given [0,1,2,3,4]
         ## This will give (value, weight) = [(0,0), (1,1), (2,0), (3,1), (4,0)]
         ## The values are sorted by weight and then by index
         ## This happens because Pyth is written in Python, which performs stable sorts

Gênio! Lindo.
Isaacg

Espere, como isso funciona?
justhalf

@justhalf Adicionei mais explicações, isso esclarece?
FryAmTheEggman

11

CJam, 7 bytes

{2/ze_}

Empurra um bloco (a coisa mais próxima de uma função sem nome) que transforma o elemento da pilha superior, conforme necessário.

Teste aqui.

Explicação

A explicação assume que o topo da pilha é a matriz [0 1 2 3 4]. Os valores reais não afetam o cálculo.

2/  e# Split the array into chunks of two: [[0 1] [2 3] [4]]
z   e# Zip/transpose, which works on ragged arrays: [[0 2 4] [1 3]]
e_  e# Flatten the result: [0 2 4 1 3]

9

Labirinto , 28 25 24 23 22 bytes

" >
?!?:|}\{@
@\?"":)!

Isso foi divertido louco! :) Esse é de longe o programa Labirinto mais densamente compactado que escrevi até agora. Eu tinha tantas versões em 20 e 21 bytes que quase funcionou que ainda estou duvidando que isso seja ótimo ...

Isso recebe a entrada como uma lista de números inteiros positivos (com um delimitador arbitrário) e imprime o resultado em STDOUT como números inteiros delimitados por alimentação de linha.

A busca por 20/21 bytes: verifiquei todos os programas no formulário

" XX
?!?X}\{@
@\?XX)!

onde Xexiste qualquer caractere razoável por força bruta, mas não encontrou soluções válidas. É claro que isso não significa que não exista uma solução mais curta, mas não é possível forçar programas de 20 bytes sem uma quantidade razoável de suposições em sua estrutura.

Explicação

(A explicação está um pouco desatualizada, mas ainda não estou convencida de que a solução seja ótima, então esperarei atualizando isso.)

Portanto, normalmente os programas de labirinto devem parecer labirintos. Enquanto o ponteiro de instruções estiver em um corredor, ele seguirá esse corredor. Quando o IP atinge qualquer tipo de junção, a direção é determinada com base no valor superior da pilha principal do labirinto (o labirinto possui duas pilhas, com uma quantidade infinita de zeros na parte inferior). Isso normalmente significa que qualquer loop não trivial será muito caro, porque se você tiver células que não sejam de parede em todo o lugar, tudo será uma junção e, na maioria dos casos, a parte superior da pilha não terá o valor certo para o IP. para seguir o caminho que você gostaria que ele seguisse. Então, o que você faz é aumentar os loops para que eles tenham um todo no centro, com apenas um ponto de entrada e saída bem definido cada.

Mas desta vez eu tive muita sorte e tudo se encaixou tão bem, que eu pude esmagar tudo em um grande grupo. :)

O fluxo de controle começa no _sul. O _empurra um zero para a pilha principal. Isso pode parecer um não operacional, mas isso aumenta a profundidade da pilha (não implícita) da 1qual precisaremos mais tarde.

?lê um número inteiro de STDIN. Se não houver mais números inteiros a serem lidos, isso empurrará zero. Nesse caso, o IP continua se movendo para o sul e @finaliza o programa imediatamente (porque a lista de entrada está vazia). Caso contrário, o IP vira para o leste.

Agora estamos entrando em um loop muito fechado com dois pontos de saída:

 !?;
 \?
  ;

!imprime o número inteiro de volta para STDOUT, deixando apenas um zero na pilha. O IP continua se movendo para o leste e ?lê o próximo número inteiro. Se isso for diferente de zero, vire à direita e seguimos para o sul. ?lê outro (o próximo índice par). Novamente, se for diferente de zero, vire à direita e seguimos para oeste.

Em seguida, \imprime um avanço de linha sem alterar a pilha, por isso vimos outra à direita, movendo para o norte. !imprime o próximo número inteiro do mesmo índice. Como agora há pelo menos um número inteiro de índice ímpar (positivo) na pilha, continuamos girando para a direita e o loop se repete.

Uma vez que qualquer um desses ?itens chegue ao final da lista, eles pressionam um zero e passam direto para o correspondente ;, que descarta esse zero.

No caso de haver apenas um elemento na lista, estamos prontos (porque o imprimimos imediatamente), para que o IP continue se movendo para o leste até o final @, novamente encerrando o programa (imprimindo um avanço de linha no caminho).

Caso contrário, também precisamos imprimir os números inteiros do índice ímpar. Nesse caso, os dois caminhos (dos dois pontos de saída do primeiro loop) se fundem no meio ", virando o leste nos dois casos.

_empurra um zero para evitar virar à esquerda no @e ;descarta esse zero. Agora entramos em um novo loop:

     "}
     ""

O IP digita isso na célula inferior esquerda, movendo-se para o norte, contornando o loop no sentido horário. O }deslocamento da parte superior da pilha principal para a pilha auxiliar. Embora ainda exista um elemento na pilha, o IP continua a funcionar. Depois que tudo foi deslocado para a pilha auxiliar (e revertida no processo), o IP continua se movendo para o leste, entrando no último loop:

       \{@
       #!

\imprime um avanço de linha novamente, {move um item da pilha auxiliar de volta para principal. Se esse ainda fosse um item da lista, será positivo e o IP mudará para o sul, onde o item é impresso !. Em seguida, #empurra a profundidade da pilha (e agora é aqui que a inicial _é importante, pois isso #garante uma profundidade positiva da pilha), para que o IP ainda vire à direita, através da \e {novamente.

Depois de imprimir tudo, {extrair um zero da parte inferior da pilha auxiliar, o IP continuará no leste e @encerrará o programa.


8

MATLAB, 24

@(x)x([1:2:end 2:2:end])

semelhante ao python.

Obrigado @LuisMendo por salvar 2 bytes!


1
Ei! Prazer em vê-lo no PPCG!
Luis Mendo

3
Um pouco mais curto:@(x)x([1:2:end 2:2:end])
Luis Mendo

@LuisMendo Haha Estou com um pouco de medo do codegolf, mas esse foi tão fácil para o MATLAB! Obrigado pela dica;)
Brain Guider

6

Haskell , 37 bytes

concat.foldr(\x[l,r]->[x:r,l])[[],[]]

Experimente online!

o foldr recursivamente cria a lista par e a lista ímpar. A adição antecipada de um elemento à lista é atualizada, acrescentando-a à lista ímpar e chamando-a de nova lista par e chamando a lista par anterior da nova lista ímpar. Então, o par [l,r]é concatenado l++r.

Agradecemos a Ørjan Johansen por salvar 5 bytes usando listas de dois elementos no lugar de tuplas.


42 bytes:

f l=[x|p<-[even,odd],(i,x)<-zip[0..]l,p i]

Adiciona índices à lista le filtra os pares ou ímpares.


g(a:_:l)=a:(g l)
g l=l
f l=g l++(g$drop 1 l)

Ainda outro formato, para 44. A função gpega todos os elementos indexados pares. Os índices ímpares são obtidos primeiro pela eliminação de um elemento e pela aplicação g. Se lfosse garantido não vazio, poderíamos fazer com segurança apenas tailpor 41

g(a:_:l)=a:(g l)
g l=l
f l=g l++g(tail l)

1
Ainda noutra variante (39 bytes): l#(a:b:c)=a:(l++[b])#c;l#x=x++l;f=([]#)com fsendo a função principal.
N

@ nimi Essa é uma boa solução, você deve publicá-la.
Xnor

Não, inclua-o na sua postagem. É apenas uma combinação dos seus nºs 2 e 3.
N

1
Você pode salvar 5 bytes em sua segunda versão usando listas e em concatvez de tuplas e uncurry(++).
Ørjan Johansen

5

PowerShell v3 +, 75 67 49 47 bytes

$l=,@()*2
$args|%{$l[($f=!$f)]+=$_}
$l[0]
$l[1]

Experimente online!

Espera a entrada via splatting, como mostrado no link TIO.

Cria uma matriz $lcomo uma matriz de matrizes e canaliza a entrada $argsem um loop |%{}. Cada vez que o loop é adicionado, adicionamos um elemento a uma das duas matrizes $lfilhas, alternando a $fvariável usando a lógica booleana. A primeira vez em que $fé , é $nullo !que é $trueou 1ao indexar em uma matriz. Isso significa que o primeiro elemento é colocado na segunda matriz de $l, e é por isso que $l[1]obtém a saída primeiro.

Suporte para TessellatingHeckler pela assistência no golfe e por essa variação.
-2 bytes graças ao mazzy.


Ressalvas

Indo estritamente à medida que a pergunta é escrita, isso é tecnicamente inválido, pois o PowerShell não tem um conceito de "listas" como objetos pseudo-imutáveis, apenas matrizes ou tabelas de hash (também conhecidas como dicionários). Portanto, estou tratando a linha da pergunta " Use a representação mais natural para listas que seu idioma possui " como perguntando sobre matrizes, pois esse é o PowerShell mais próximo. Além disso, a saída é um elemento por linha, pois é a maneira padrão do PowerShell de gravar uma matriz. Isso significa que uma entrada de (0,1,2,3,4)saída será 0\r\n2\r\n4\r\n1\r\n3\r\n.


47 bytes - $args+ splatting em vez disso $inpute ,@()*2em vez disso@(),@()
mazzy 24/02

4

F #, 79 77 56

fun x->List.foldBack(fun x (l,r)->x::r,l)x ([],[])||>(@)

Baseado em uma das respostas de Haskell

fun x->x|>List.indexed|>List.partition(fst>>(&&&)1>>(=)0)||>(@)|>List.map snd

Primeiro indexamos a lista e depois a particionamos com critérios: primeiro item (o índice) e com 1 igual a 0.
Isso nos dá um par de lista de pares; a primeira lista contém todos os pares indexados e a outra as probabilidades indexadas.
A partir disso, remontamos as duas listas com o operador append e finalmente descartamos o índice.

Edit: perdeu um óbvio, não há necessidade de nomear o arg "xs" (hábitos) para reduzir o nome de uma letra


Eu também tenho um potencial de 76 bytes, que é basicamente o mesmo, mas definido como composição da função. O problema é que ele não é compilado como um valor, mas funcionará efetivamente com qualquer argumento de lista fornecido, para não ter certeza se está ok ou não:

List.indexed>>List.partition(fst>>(&&&)1>>(=)0)>>fun(e,o)->e@o|>List.map snd

Nota: List.indexed está disponível apenas no F # 4.0, apesar de ainda não estar documentado no MSDN


Tecnologia de ponta, legal!
anatolyg

1
@anatolyg É fun, não é?
Conor O'Brien

Eu acho que isso é semelhante ao código Perl 6 que eu tentei pela primeira vez. -> \xs { xs.pairs.classify( *.key%%2, :as( *.value ) ).map( *.value.Slip ) }Supondo que o |>F # seja aproximadamente equivalente ao operador de alimentação à direita ==>no Perl 6. Também estou adivinhando o que fst>>(&&&)1>>(=)0faz
Brad Gilbert b2gills

4

JavaScript (ES6), 52 bytes

Também o faz de uma só vez

x=>x.map((v,i)=>x[(i*=2)>=(z=x.length)?i-z+--z%2:i])


Você pode omitir o F=desde o início; você pode salvar um byte usando este:(i*=2)>=(z=x.length)?i-z+--z%2:i
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Boa ideia obrigado!
George Reith


3

J, 8 bytes

/:0 1$~#

Este é um verbo monádico (um argumento), usado da seguinte maneira:

  (/:0 1$~#) 110 22 3330 4444 55555 6
110 3330 55555 22 4444 6

Explicação

/:        Sort the input array according to
  0 1     the array 0 1
     $~   repeated enough times to be of length
       #  length of input

1
Uma alternativa é /:0:`1:\que também tem 8 bytes.
milhas

3

Gelatina , 4 bytes

s2ZF

Experimente online!

Baseado na resposta CJam de Martin

s2ZF - Main link. Argument: L (a list) e.g.  [110, 22, 3330, 4444, 55555, 6]
s2   - Split into chunks of length 2         [[110, 22], [3330, 4444], [55555, 6]]
  Z  - Columns                               [[110, 3330, 55555], [22, 4444, 6]]
   F - Flatten                               [110, 3330, 55555, 22, 4444, 6]

2

Mathematica, 40 bytes

#[[;;;;2]]~Join~If[#=={},#,#[[2;;;;2]]]&

{}[[2;;;;2]] irá lançar um erro.


2

Burlesco, 12 bytes

J2ENj[-2EN_+

Uso como em:

blsq ) {0 1 2 3 4}J2ENj[-2EN_+
{0 2 4 1 3}
blsq ) {110 22 3330 4444 55555 6}J2ENj[-2EN_+
{110 3330 55555 22 4444 6}

Explicação:

J     -- duplicate
2EN   -- every 2nd element
j     -- swap
[-    -- tail
2EN   -- every 2nd element
_+    -- concatenate parts

Embora uma vez lançada a nova atualização, você possa fazer isso com o novo interno do Unmerge (que faz o oposto do incorporado da mesclagem **):

blsq ) {110 22 3330 4444 55555 6}J2ENj[-2EN**
{110 22 3330 4444 55555 6}

2

Perl, 35 33 bytes

perl -ape 'push@{$|--},$_ for@F;$_="@0 @1"'

31 bytes + 2 bytes para -ap. Lê uma string delimitada por espaço de STDIN:

$ echo 0 1 2 3 4 | perl -ape 'push@{$|--},$_ for@F;$_="@0 @1"'
0 2 4 1 3

$ echo 110 22 3330 4444 55555 6 | perl -ape 'push@{$|--},$_ for@F;$_="@0 @1"'
110 3330 55555 22 4444 6

Quando a entrada está vazia, imprime um único espaço, que eu consideraria equivalente a uma lista vazia. Caso contrário, pode ser corrigido a um custo de 4 bytes com:

perl -anE 'push@{$|--},$_ for@F;$,=$";say@0,@1'

(requer Perl 5.10+, imprime uma nova linha à direita)

ou a um custo de 5 bytes com:

perl -ape 'push@{$|--},$_ for@F;$_=join$",@0,@1'

(sem espaço em branco à direita)

Como funciona

Esta solução usa o -asinalizador, que divide a entrada em espaço em branco e coloca os resultados no campo@F matriz.

A verdadeira magia acontece no push :

push@{$|--},$_

o $| variável é normalmente usada para forçar a descarga da saída, mas tem outra propriedade interessante: quando decrementada repetidamente, seu valor alterna entre 0 e 1.

perl -E 'say $|-- for 0..4'
0
1
0
1
0

Aproveitando o fato de que não há restrições nos identificadores especificados por desreferenciação simbólica , alternamos os elementos da matriz para as matrizes @0e @1, assim @0terminamos com todos os elementos indexados pares e @1com as probabilidades. Em seguida, simplesmente concatenamos os arrays stringificados para obter nossa saída.


2

C, 70

Nada de especial, apenas uma função de mapeamento de índice.

a=0;main(int c,int** v){for(c--;a<c;)puts(v[1+a*2%c+!(a++<c/2|c%2)]);}

Menos golfe

a=0;
main(int c, int** v) {
  for(c--; a<c;)
    puts(v[1 + a*2%c + !(a++ < c/2 | c%2) ]);
}

1

Pitão, 8 bytes

+%2Q%2tQ

Relativamente simples


1

Vitsy, 22 bytes

Vitsy realmente não foi feito para fazer isso ...

r '' Vl2 / \ [N {VO] l \ [NVO]
r Inverta a pilha de entrada numérica implícita.
 '' V Salve o caractere "espaço" como uma variável final global.
     l2 / \ [....] Repita o material entre parênteses ao comprimento da entrada
                        pilha dividida por 2.
          N {VO Exibe o item superior da pilha como um número e depois desloque
                        empilhe uma vez para a esquerda, empurre um espaço e faça a saída.
               l \ [...] para o resto da pilha, repita isso muitas vezes ...
                  NVO Emite o item superior da pilha como um número separado 
                        por um espaço.

1

Perl 6 , 25 bytes

Este é o lambda mais curto que eu poderia inventar.

{|.[0,2...*],|.[1,3...*]} # 25 byte "Texas" version
{|.[0,2…*],|.[1,3…*]}     # 25 byte "French" version
say {|.[0,2…*],|.[1,3…*]}( ^5 ); # (0 2 4 1 3)␤

say ((0..4),('m'..'q'),(5..9)).map: {|.[0,2…*],|.[1,3…*]}
# ((0 2 4 1 3) (m o q n p) (5 7 9 6 8))␤


# bind it as a lexical sub
my &foo = {|.[0,2…*],|.[1,3…*]}

say foo [110, 22, 3330, 4444, 55555, 6]; # (110 3330 55555 22 4444 6)␤

say [~] foo 'a'..'z' # acegikmoqsuwybdfhjlnprtvxz␤

1

Minkolang 0.12 , 15 bytes

$nI2:[i1+g]r$N.

Experimente aqui.

Explicação

$n                 Read in all of input as numbers
  I2:              The length of the stack divided by 2 (n)
     [             Open for loop that repeats n times
      i1+          Loop counter + 1
         g         Gets the (i+1)th item from the stack and puts it on top
          ]        Close for loop
           r       Reverse the stack (for outputting)
            $N.    Output the whole stack as numbers and stop.

1

R, 49 bytes

q<-function(x)c(x[seq(x)%%2==1],x[seq(x)%%2==0])

Chame isso de q (blá). Ou, se x já contém a lista a ser reorganizada, então

c(x[seq(x)%%2==1],x[seq(x)%%2==0])

são apenas 35 bytes.


1

F #, 64

fun x->List.mapi(fun i l->l,i%2)x|>List.sortBy snd|>List.map fst

Inspirado pela resposta de Sehnsucht (mas não o suficiente para comentar).

Mapeia cada valor para uma tupla onde a segunda entrada é o módulo do índice de lista, classifica por módulo e, em seguida, mapeia de volta para o valor original.


1

Prolog, 103 bytes

r([E,O|T],[E|A],[O|B]):-r(T,A,B).
r([],[],[]).
r([E],[E],[]).
p(L):-r(L,A,B),append(A,B,X),write(X).

Exemplo

>p([1,2,3,4,5]).
[1,3,5,2,4]

1

bash e coreutils GNU, 68 bytes

Assumimos que a lista seja separada por nova linha e transmitida na entrada padrão.

(paste - <(seq 0 5 9999)|tee x|grep 0$;grep 5$<x)|cut -f1|grep -v ^$

Infelizmente, isso ignorará qualquer entrada além do índice 1999, portanto não atende exatamente às especificações.

Ele também bloqueia um arquivo temporário codificado ('x'), que pode ser problemático se for executado em paralelo e não o remove posteriormente. Me desculpe por isso!


1

PHP, 78 69 bytes

O PHP pode dividir e fatiar, mas não intercalar matrizes; isso torna isso um pouco volumoso:

function(&$a){while($i++<count($a)>>1)$a[]=array_splice($a,$i,1)[0];}

Ligue por referência ou experimente online .


primeira abordagem (programas para 78 bytes):

for(;++$i<$argc;)echo",",$argv[$i++];for($i=1;++$i<$argc;)echo",",$argv[$i++];

imprime uma vírgula inicial; insira [!$i]antes do primeiro $argvpara removê-lo.

Duas outras soluções de 78 bytes (imprimem uma vírgula inicial e final):

for($n=$argc-2|1;++$i<$argc*2;)$i&1?print",".$argv[$i]:$argv[$n+=2]=$argv[$i];
for($n=$argc-2;++$i<$argc*2;)$i&1?print",".$argv[$i]:$argv[1|$n+=2]=$argv[$i];

Corra com php -nr '<code>' <arguments>ou experimente-os online


1

Japonês , 3 bytes

ñÏu

Tente

ñÏu     :Implicit input of array
ñ       :Sort by
 Ï      :Passing the 0-based index of each through a function
  u     :  Modulo 2 of index

ó c

Tente

ó c     :Implicit input of array
ó       :Split into 2 arrays of every 2nd item
  c     :Flatten
        :Implicit output

0

Clojure / ClojureScript, 52 bytes

(defn f[l](flatten(map #(take-nth 2 %)[l(rest l)])))

Escrito em um REPL do ClojureScript, também deve ser um Clojure válido.



0

Hássio , 191 bytes

Este foi bastante longo :(
Ele lê a matriz de args, então execute isso comhassium file.has 0 1 2 3 4

func main(){a=args;e,o=[]for(c=0;c<a.length;c++)if(c%2==0)e.add(a[c])else o.add(a[c])print("["+(e+o).toString().replace("{", "").replace("}", "").replace("Array", "").replace("  ", "")+"]");}

Execute e veja expandido com o caso de teste aqui

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.