Séparez une liste en parties indexées paires et impaires


26

Inspiré par cette question:

Créez une fonction (ou un programme complet) qui reçoit une liste de nombres et sort la liste réorganisée, de sorte que les nombres indexés pairs apparaissent en premier, et les nombres indexés impairs suivent. Les valeurs des nombres eux-mêmes n'affectent pas l'ordre - seuls leurs indices le font. Tous les indices sont basés sur zéro.

Par exemple:

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

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

Un autre exemple:

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

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

Utilisez la représentation la plus naturelle pour les listes de votre langue. Il n'y a pas de limites à la complexité (par exemple, allouer une liste temporaire est OK - pas besoin de le faire sur place).

PS Cela devrait fonctionner pour la liste vide (entrée vide => sortie vide).



Pouvons-nous supposer que tous les éléments de la liste sont positifs ou non négatifs ou quelque chose?
Martin Ender

@ MartinBüttner Supposons tout ce qui est raisonnable, peut-être même qu'ils sont compris entre 0 et 255.
anatolyg


Pouvons-nous produire une liste séparée par des virgules?
Oliver

Réponses:



21

Python, 23 octets

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

Essayez-le en ligne


1
Pourquoi lambda? Pourquoi pas muou nu? : P
Kritixi Lithos

1
@rayryeng Je plaisantais seulement comme vous pouvez le voir par le ": P" à la fin de mon commentaire :)
Kritixi Lithos

5
Oui, vous devriez certainement remplacer lambdapar λet réduire le nombre d' octets par 5! : P
anatolyg

3
@anatolyg sonne comme une idée de soumission PEP !
Nick T

2
@ThomasKwa C'est le bon outil pour le travail: P
Mego

16

Pyth, 5

o~!ZQ

Essayez-le en ligne ou exécutez une suite de tests

Explication

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énie! Beau.
isaacg

Attendez, comment ça marche?
moitié du

@justhalf J'ai ajouté quelques explications supplémentaires, est-ce que cela clarifie les choses?
FryAmTheEggman

11

CJam, 7 octets

{2/ze_}

Pousse un bloc (l'élément le plus proche d'une fonction sans nom) qui transforme l'élément de pile supérieur selon les besoins.

Testez-le ici.

Explication

L'explication suppose que le haut de la pile est le tableau [0 1 2 3 4]. Les valeurs réelles n'affectent pas le calcul.

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

Labyrinthe , 28 25 24 23 22 octets

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

C'était amusant fou! :) C'est de loin le programme Labyrinthe le plus densément compressé que j'ai écrit jusqu'à présent. J'avais tellement de versions à 20 et 21 octets qui fonctionnaient presque que je doute toujours que ce soit optimal ...

Cela prend l'entrée comme une liste d' entiers positifs (avec un délimiteur arbitraire) et imprime le résultat dans STDOUT sous forme d'entiers délimités par des sauts de ligne.

La chasse aux 20/21 octets: j'ai vérifié tous les programmes du formulaire

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

X est tout caractère raisonnable par force brute, mais n'a trouvé aucune solution valide. Bien sûr, cela ne signifie pas qu'il n'existe pas de solution plus courte, mais il n'est pas possible de forcer des programmes de 20 octets sans une quantité décente d'hypothèses sur sa structure.

Explication

(L'explication est légèrement dépassée, mais je ne suis toujours pas convaincu que la solution soit optimale, donc j'attendrai avec la mise à jour.)

Donc, normalement, les programmes Labyrinth sont censés ressembler à des labyrinthes. Pendant que le pointeur d'instructions se trouve dans un couloir, il suivra ce couloir. Lorsque l'IP atteint n'importe quel type de jonction, la direction est déterminée en fonction de la valeur maximale de la pile principale de Labyrinth (Labyrinth a deux piles, avec une quantité infinie de zéros en bas). Cela signifie normalement que toute boucle non triviale sera assez coûteuse, car si vous avez des cellules non murales partout, tout est une jonction, et dans la plupart des cas, le haut de la pile n'aura pas la bonne valeur pour l'IP pour prendre le chemin que vous aimeriez qu'il prenne. Donc, ce que vous faites, c'est agrandir les boucles de sorte qu'elles aient un tout au centre avec un seul point d'entrée et de sortie bien défini chacun.

Mais cette fois, j'ai vraiment eu de la chance et tout allait si bien ensemble que je pouvais tout écraser en une seule grosse touffe. :)

Le flux de contrôle commence au _sud. Le _pousse un zéro sur la pile principale. Cela peut sembler être un no-op, mais cela augmente la profondeur de pile (non implicite) 1dont nous aurons besoin plus tard.

?lit un entier dans STDIN. S'il n'y a plus d'entiers à lire, cela pousse zéro. Dans ce cas, l'IP continue de se déplacer vers le sud et @termine immédiatement le programme (car la liste d'entrée est vide). Sinon, l'IP tourne vers l'Est.

Nous entrons maintenant dans une boucle très serrée avec deux points de sortie:

 !?;
 \?
  ;

!imprime l'entier dans STDOUT, ne laissant qu'un zéro sur la pile. L'IP continue de se déplacer vers l'est et ?lit l'entier suivant. Si ce n'est pas zéro, nous prenons à droite et nous nous déplaçons vers le sud. ?lit un autre (le prochain index pair). Encore une fois, si ce n'est pas zéro, nous prenons à droite et nous nous déplaçons vers l'ouest.

\Imprime ensuite un saut de ligne sans changer la pile, nous prenons donc une autre à droite en se déplaçant vers le nord. !imprime le prochain entier d'index pair. Comme il y a maintenant au moins un entier impair (positif) sur la pile, nous continuons à tourner à droite et la boucle se répète.

Une fois que l'un d'eux ?atteint la fin de la liste, il pousse un zéro et se déplace directement sur le correspondant ;, ce qui rejette ce zéro.

Dans le cas où il n'y avait qu'un seul élément dans la liste, nous avons terminé (parce que nous l'avons imprimé tout de suite), donc l'IP continuerait de se déplacer vers l'est jusqu'à la @fin du programme (en imprimant une fin saut de ligne en chemin).

Sinon, nous devons également imprimer les entiers à indice impair. Dans ce cas, les deux chemins (à partir des deux points de sortie de la première boucle) fusionnent au milieu ", tournant vers l'Est dans les deux cas.

_pousse un zéro pour éviter de prendre une gauche dans le @, et ;rejette ce zéro. Maintenant, nous entrons dans une nouvelle boucle:

     "}
     ""

L'IP entre dans la cellule en bas à gauche, se déplaçant vers le nord, faisant le tour de la boucle dans le sens des aiguilles d'une montre. Le }déplace le haut de la pile principale vers la pile auxiliaire. Bien qu'il y ait encore un élément sur la pile, l'IP continue de faire son travail. Une fois que tout a été déplacé vers la pile auxiliaire (et inversé dans le processus), l'IP continue de se déplacer vers l'est à la place, entrant dans la dernière boucle:

       \{@
       #!

\imprime à nouveau un saut de ligne, {déplace un élément de la pile auxiliaire vers le principal. Si c'était encore un élément de la liste, il sera positif et l'adresse IP se dirigera vers le sud, là où l'élément est imprimé !. #Pousse ensuite la profondeur de pile (et maintenant c'est là que l'initiale _est importante, car cela #garantit une profondeur de pile positive), de sorte que l'IP tourne toujours à droite, à travers le \et à {nouveau.

Une fois que nous avons tout imprimé, tiré {un zéro du bas de la pile auxiliaire, l'IP continue vers l'Est et @termine le programme.


8

MATLAB, 24

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

similaire à celui en python.

Merci @LuisMendo d'avoir économisé 2 octets!


1
Hey! Ravi de vous voir à PPCG!
Luis Mendo

3
Un peu plus court:@(x)x([1:2:end 2:2:end])
Luis Mendo

@LuisMendo Haha J'ai un peu peur du codegolf, mais celui-ci était si facile pour MATLAB! Merci pour l'astuce;)
Brain Guider

6

Haskell , 37 octets

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

Essayez-le en ligne!

Le foldrconstruit de manière récursive la liste paire et la liste impaire. L'ajout d'un élément à la liste est mis à jour en l'ajoutant à la liste impaire et en l'appelant la nouvelle liste paire et en appelant la liste paire précédente la nouvelle liste impaire. Ensuite, la paire [l,r]est concaténée à l++r.

Merci à Ørjan Johansen pour avoir économisé 5 octets en utilisant des listes à deux éléments à la place des tuples.


42 octets:

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

Ajoute des indices à la liste let filtre les pairs ou les impairs.


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

Encore un autre format, pour 44. La fonction gprend chaque élément pair-indexé. Les indices impairs sont obtenus en supprimant d'abord un élément, puis en appliquant g. Si létait garanti non vide, nous pourrions le faire en toute sécurité tailpour 41

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

1
encore une autre variante (39 octets): l#(a:b:c)=a:(l++[b])#c;l#x=x++l;f=([]#)avec fcomme fonction principale.
nimi

@nimi C'est une bonne solution, vous devriez la poster.
xnor

Non, veuillez l'inclure dans votre message. C'est juste une combinaison de votre # 2 et # 3.
nimi

1
Vous pouvez enregistrer 5 octets sur votre deuxième version en utilisant des listes et concatau lieu de tuples et uncurry(++).
Ørjan Johansen

5

PowerShell v3 +, 75 67 49 47 octets

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

Essayez-le en ligne!

Attend l'entrée via l'éclaboussure, comme indiqué sur le lien TIO.

Crée une matrice en $ltant que tableau de tableaux, puis dirige l'entrée $argsdans une boucle |%{}. Chaque fois dans la boucle, nous ajoutons un élément à l'un des deux tableaux enfants de $len inversant la $fvariable à l'aide de la logique booléenne. La première fois, $fest $null, !dont est $true, ou 1lors de l'indexation dans un tableau. Cela signifie que le premier élément est placé dans le deuxième tableau de $l, c'est pourquoi la $l[1]sortie est la première.

Props à TessellatingHeckler pour l'aide au golf et cette variation.
-2 octets grâce à mazzy.


Avertissements

Aller strictement comme la question est écrite, c'est techniquement invalide, car PowerShell n'a pas un concept de "listes" en tant qu'objets pseudo-immuables, seulement des tableaux ou des tables de hachage (aka dictionnaires). Donc, je traite la ligne de la question « Utilisez la représentation la plus naturelle pour les listes de votre langue » comme une question sur les tableaux, car c'est le PowerShell le plus proche. De plus, la sortie est un élément par ligne, car c'est la façon par défaut PowerShell d'écrire un tableau. Cela signifie une entrée de (0,1,2,3,4)volonté de sortie 0\r\n2\r\n4\r\n1\r\n3\r\n.


47 octets - $args+ éclaboussures à la place $inputet à la ,@()*2place@(),@()
mazzy

4

F #, 79 77 56

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

Basé sur l'une des réponses de Haskell

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

Nous indexons d'abord la liste, puis la partitionnons avec des critères: premier élément (l'index) et 1 égal à 0.
Cela nous donne une paire de liste de paires; la première liste contiendra tous les événements indexés et l'autre les cotes indexées.
À partir de là, nous remontons la liste des deux avec l'opérateur d'ajout et nous éliminons finalement l'index.

Edit: manqué une évidence, il n'est pas nécessaire de nommer l'arg "xs" (habitudes), donc peut se réduire à un nom à 1 lettre


J'ai également un potentiel de 76 octets qui est fondamentalement le même mais défini comme composition de fonction. Le problème est qu'il ne se compile pas en tant que valeur mais fonctionnera efficacement avec n'importe quel argument de liste donné, donc vous ne savez pas si c'est correct ou non:

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

Remarque: List.indexed est uniquement disponible à partir de F # 4.0 bien qu'il ne soit pas encore documenté dans MSDN


Une technologie de pointe, cool!
anatolyg

1
@anatolyg C'est fun, n'est-ce pas?
Conor O'Brien

Je pense que cela est similaire au code Perl 6 que j'ai essayé pour la première fois. -> \xs { xs.pairs.classify( *.key%%2, :as( *.value ) ).map( *.value.Slip ) }Supposer |>en F # équivaut à peu près à l'opérateur d'alimentation vers la droite ==>dans Perl 6. Je ne fais que deviner ce qui se fst>>(&&&)1>>(=)0passe
Brad Gilbert b2gills

4

JavaScript (ES6), 52 octets

Il le fait également en un seul passage

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


Vous pouvez omettre le F=depuis le début; vous pouvez enregistrer un octet en utilisant ceci:(i*=2)>=(z=x.length)?i-z+--z%2:i
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Belle idée merci!
George Reith


3

J, 8 octets

/:0 1$~#

Il s'agit d'un verbe monadique (à un argument), utilisé comme suit:

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

Explication

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

1
Une alternative est /:0:`1:\également de 8 octets.
miles

3

Gelée , 4 octets

s2ZF

Essayez-le en ligne!

Basé sur la réponse 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 octets

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

{}[[2;;;;2]] va lancer une erreur.


2

Burlesque, 12 octets

J2ENj[-2EN_+

Utilisation comme dans:

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}

Explication:

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

Bien qu'une fois la nouvelle mise à jour publiée, vous pouvez le faire avec le nouveau intégré Unmerge (qui fait le contraire de la fusion **intégrée):

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

2

Perl, 35 33 octets

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

31 octets + 2 octets pour -ap. Lit une chaîne délimitée par des espaces depuis 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

Lorsque l'entrée est vide, imprime un seul espace, que je considérerais comme équivalent à une liste vide. Sinon, peut être fixé au coût de 4 octets avec:

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

(nécessite Perl 5.10+, imprime une nouvelle ligne de fin)

ou au coût de 5 octets avec:

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

(aucun espace de fin)

Comment ça marche

Cette solution utilise l' -aindicateur, qui divise l'entrée sur les espaces blancs et place les résultats dans le @Ftableau.

La vraie magie opère dans push:

push@{$|--},$_

La $|variable est normalement utilisée pour forcer le vidage de sortie, mais elle a une autre propriété intéressante: lorsqu'elle est décrémentée à plusieurs reprises, sa valeur bascule entre 0 et 1.

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

Profitant du fait qu'il n'y a aucune restriction sur les identifiants spécifiés via le déréférencement symbolique , nous poussons alternativement les éléments du tableau sur les tableaux @0et @1, donc nous nous retrouvons @0avec tous les éléments pairs et @1avec les cotes. Ensuite, nous concaténons simplement les tableaux stringifiés pour obtenir notre sortie.


2

C, 70

Rien de spécial, juste une fonction de mappage d'index.

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

Moins golfé

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

1

Pyth, 8 octets

+%2Q%2tQ

Relativement simple


1

Vitsy, 22 octets

Vitsy n'était vraiment pas fait pour faire ça ...

r '' Vl2 / \ [N {VO] l \ [NVO]
r Inverse la pile d'entrée numérique implicite.
 '' V Enregistrez le caractère "espace" en tant que variable finale globale.
     l2 / \ [....] Répéter les trucs entre parenthèses la longueur de l'entrée
                        pile divisée par 2.
          N {VO Affiche l'élément supérieur de la pile sous forme de nombre, puis décale
                        empiler une fois vers la gauche, pousser un espace, le sortir.
               l \ [...] Pour le reste de la pile, répétez cela plusieurs fois ...
                  NVO Afficher l'élément supérieur de la pile sous la forme d'un nombre séparé 
                        par un espace.

1

Perl 6 , 25 octets

C'est le lambda le plus court que j'ai pu trouver.

{|.[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 octets

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

Essayez-le ici.

Explication

$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 octets

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

Appelez-le comme q (bla). Ou, si x contient déjà la liste à réorganiser, alors

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

n'est que de 35 octets.


1

F #, 64

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

Inspiré par la réponse de Sehnsucht (mais pas assez de représentant pour commenter).

Mappe chaque valeur à un tuple où la deuxième entrée est le modulo de l'index de liste, trie par modulo, puis mappe à la valeur d'origine.


1

Prolog, 103 octets

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).

Exemple

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

1

bash et GNU coreutils, 68 octets

Nous supposons que la liste est séparée par des sauts de ligne et transmise sur une entrée standard.

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

Malheureusement, cela ignorera toutes les entrées au-delà de l'indice 1999, donc il ne répond pas tout à fait à la spécification.

Il détruit également un fichier temporaire codé en dur ('x'), ce qui pourrait être problématique s'il est exécuté en parallèle, et il ne le supprime pas par la suite. Désolé pour ça!


1

PHP, 78 69 octets

PHP peut fragmenter et découper, mais pas entrelacer les tableaux; ce qui en fait un peu volumineux:

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

Appelez par référence ou essayez-le en ligne .


première approche (programmes pour 78 octets):

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

imprime une virgule de début; insérer [!$i]avant le premier $argvpour le retirer.

Deux autres solutions de 78 octets (imprimer une virgule de début et une virgule de fin):

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

Courez avec php -nr '<code>' <arguments>ou essayez-les en ligne


1

Japt , 3 octets

ñÏu

Essayez-le

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

ó c

Essayez-le

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

0

Clojure / ClojureScript, 52 octets

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

Écrit dans un ClojureScript REPL, doit également être un Clojure valide.



0

Hassium , 191 octets

Celui-ci était assez long :(
Il lit le tableau à partir des arguments, alors exécutez-le avechassium 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("  ", "")+"]");}

Exécutez et voyez développé avec le cas de test ici

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.