Podziel listę na części o indeksach parzystych i nieparzystych


26

Zainspirowany tym pytaniem:

Utwórz funkcję (lub pełny program), która odbiera listę liczb i wysyła listę na nowo, tak aby liczby o indeksach parzystych pojawiały się jako pierwsze, a następnie liczby o indeksach nieparzystych. Wartości samych liczb nie wpływają na kolejność - wpływają tylko ich indeksy. Wszystkie indeksy są zerowe.

Na przykład:

Wkład: [0, 1, 2, 3, 4]

Wydajność: [0, 2, 4, 1, 3]

Inny przykład:

Wkład: [110, 22, 3330, 4444, 55555, 6]

Wydajność: [110, 3330, 55555, 22, 4444, 6]

Użyj najbardziej naturalnej reprezentacji dla list, które ma Twój język. Nie ma ograniczeń dotyczących złożoności (np. Przydzielenie tymczasowej listy jest w porządku - nie trzeba tego robić w miejscu).

PS Powinno działać dla pustej listy (puste wejście => puste wyjście).


Jest to faktycznie odwrotność obecnych odpowiedzi na to pytanie
Peter Taylor,

Czy możemy założyć, że wszystkie elementy listy są pozytywne, nieujemne czy coś w tym rodzaju?
Martin Ender,

@ MartinBüttner Załóżmy, że wszystko jest rozsądne, może nawet, że są w zakresie 0 ... 255.
anatolyg


Czy możemy wyświetlić listę rozdzielaną przecinkami?
Oliver,

Odpowiedzi:




16

Pyth, 5

o~!ZQ

Wypróbuj online lub uruchom pakiet testowy

Wyjaśnienie

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

Geniusz! Piękny.
isaacg,

Zaraz, jak to działa?
justhalf

@ justhalf Dodałem więcej wyjaśnień, czy to wyjaśnia?
FryAmTheEggman

11

CJam, 7 bajtów

{2/ze_}

Przesuwa blok (najbliższy funkcji bez nazwy), który przekształca element stosu górnego zgodnie z wymaganiami.

Sprawdź to tutaj.

Wyjaśnienie

Wyjaśnienie zakłada, że ​​górną częścią stosu jest tablica [0 1 2 3 4]. Rzeczywiste wartości nie wpływają na obliczenia.

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

Labirynt , 28 25 24 23 22 bajtów

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

To była szalona zabawa! :) To zdecydowanie najgęściej skompresowany program Labiryntu, jaki do tej pory napisałem. Miałem tak wiele wersji o wielkości 20 i 21 bajtów, które prawie działały, że wciąż wątpię, czy jest to optymalne ...

Pobiera to dane wejściowe jako listę liczb całkowitych dodatnich (z dowolnym ogranicznikiem) i wypisuje wynik do STDOUT jako liczby całkowite rozdzielane przez linię.

Polowanie na 20/21 bajtów: sprawdziłem wszystkie programy formularza

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

gdzie Xjest jakikolwiek rozsądny charakter brutalnej siły, ale nie znalazł żadnych ważnych rozwiązań. Oczywiście nie oznacza to, że krótsze rozwiązanie nie istnieje, ale nie można narzucać 20-bajtowych programów bez sporej liczby założeń dotyczących jego struktury.

Wyjaśnienie

(Wyjaśnienie jest nieco nieaktualne, ale nadal nie jestem przekonany, że rozwiązanie jest optymalne, więc poczekam z aktualizacją).

Zatem normalnie programy Labiryntu powinny wyglądać jak labirynty. Gdy wskaźnik instrukcji znajduje się w korytarzu, podąży za nim. Kiedy IP trafia na jakiekolwiek połączenie, kierunek jest określany na podstawie najwyższej wartości głównego stosu Labiryntu (Labirynt ma dwa stosy, z nieskończoną liczbą zer na dole). Zwykle oznacza to, że każda nietrywialna pętla będzie dość droga, ponieważ jeśli masz komórki nieścienne w całym miejscu, wszystko jest skrzyżowaniem, aw większości przypadków górna część stosu nie będzie miała właściwej wartości dla adresu IP podążać ścieżką, którą chcesz. Więc powiększasz pętle, tak aby miały całość w środku z tylko jednym dobrze zdefiniowanym punktem wejścia i wyjścia.

Ale tym razem miałem naprawdę szczęście i wszystko tak dobrze do siebie pasowało, że mogłem wszystko to zmiażdżyć. :)

Przepływ kontrolny zaczyna się w _kierunku południowym. _Popycha zero na głównym stosie. Może to wydawać się brakiem operacji, ale zwiększa to (niejawną) głębokość stosu, do 1której będziemy potrzebować później.

?odczytuje liczbę całkowitą ze STDIN. Jeśli nie ma więcej liczb całkowitych do odczytania, przesuwa to zero. W takim przypadku adres IP przesuwa się na południe i @natychmiast kończy program (ponieważ lista wejść jest pusta). W przeciwnym razie IP zmienia się na Wschód.

Wchodzimy teraz w bardzo ciasną pętlę z dwoma punktami wyjścia:

 !?;
 \?
  ;

!wypisuje liczbę całkowitą z powrotem do STDOUT, pozostawiając tylko zero na stosie. Adres IP przesuwa się na wschód i ?odczytuje następną liczbę całkowitą. Jeśli to nie jest zero, skręcamy w prawo i ruszamy na południe. ?odczytuje inny (następny parzysty indeks). Ponownie, jeśli nie jest to zero, skręcamy w prawo i ruszamy na zachód.

Następnie \drukuje wysuw linii bez zmiany stosu, więc skręcamy w prawo, przesuwając się na północ. !wypisuje następną liczbę całkowitą z indeksem parzystym. Ponieważ teraz na stosie znajduje się co najmniej jedna (dodatnia) liczba całkowita o nieparzystym indeksie, skręcamy w prawo i pętla się powtarza.

Gdy któryś z nich ?trafi na koniec listy, naciska zero i przesuwa się prosto na odpowiedni ;, który odrzuca to zero.

W przypadku, gdy na liście znajdował się tylko jeden element, skończyliśmy (ponieważ wydrukowaliśmy to od razu), więc adres IP przesuwałby się na wschód aż do @, ponownie kończąc program (drukując końcowy po drodze).

W przeciwnym razie musimy również wydrukować liczby całkowite o nieparzystym indeksie. W takim przypadku dwie ścieżki (z dwóch punktów wyjścia pierwszej pętli) łączą się na środku ", w obu przypadkach kierując się na wschód.

_naciska zero, aby uniknąć skrętu w lewo @, i ;odrzuca to zero. Teraz wchodzimy w nową pętlę:

     "}
     ""

IP wchodzi do tego w lewej dolnej komórce, poruszając się na północ, omijając pętlę zgodnie z ruchem wskazówek zegara. }Przenosi góry głównego stosu nad do stosu pomocniczego. Podczas gdy na stosie nadal znajduje się element, adres IP nadal działa. Po przeniesieniu wszystkiego do stosu pomocniczego (i odwróceniu w tym procesie) IP przesuwa się na wschód, wchodząc w ostatnią pętlę:

       \{@
       #!

\wypisuje ponownie linię, {przenosi element ze stosu pomocniczego z powrotem na główny. Jeśli nadal był to element na liście, będzie dodatni, a adres IP skręca na południe, gdzie element jest drukowany !. Następnie #przesuwa głębokość stosu (a teraz jest to miejsce, w którym _ważna jest wartość początkowa , ponieważ #zapewnia to dodatnią głębokość stosu), dzięki czemu adres IP nadal skręca w prawo, przez \i {ponownie.

Po wydrukowaniu wszystkiego, {wyciąga zero z dolnej części stosu pomocniczego, IP kontynuuje Wschód i @kończy program.


8

MATLAB, 24

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

podobny do pythonowego.

Dzięki @LuisMendo za uratowanie 2 bajtów!


1
Hej! Miło cię widzieć w PPCG!
Luis Mendo,

3
Nieco krótszy:@(x)x([1:2:end 2:2:end])
Luis Mendo,

@LuisMendo Haha Trochę boję się codegolfa, ale ten był tak łatwy dla MATLAB! Dzięki za podpowiedź;)
Brain Guider

6

Haskell , 37 bajtów

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

Wypróbuj online!

foldrRekurencyjnie buduje listę parzystych i nieparzystych listę. Przygotowywanie elementu do listy jest aktualizowane przez dodanie go do listy nieparzystych i nazwanie jej nową listą parzystą, a wywołanie poprzedniej listy parzystej nowej listy nieparzystej. Następnie para [l,r]konkaternuje l++r.

Dzięki Ørjan Johansen za uratowanie 5 bajtów przy użyciu list dwuelementowych zamiast krotek.


42 bajty:

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

Dodaje indeksy do listy li filtruje parzyste lub nieparzyste.


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

Jeszcze inny format, dla 44. Funkcja gprzyjmuje każdy element z indeksem parzystym. Wskaźniki nieparzyste są pobierane najpierw przez upuszczenie elementu, a następnie zastosowanie g. Gdyby lzagwarantowano, że nie będzie pusta, moglibyśmy bezpiecznie zrobić tailza 41

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

1
Jeszcze inny wariant (39 bajtów): l#(a:b:c)=a:(l++[b])#c;l#x=x++l;f=([]#)przy fczym główną funkcją.
nimi

@nimi To miłe rozwiązanie, powinieneś je opublikować.
xnor

Nie, umieść to w swoim poście. To tylko połączenie twojego # 2 i # 3.
nimi

1
Możesz zapisać 5 bajtów w drugiej wersji, używając list i concatzamiast krotek i uncurry(++).
Ørjan Johansen

5

PowerShell v3 +, 75 67 49 47 bajtów

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

Wypróbuj online!

Oczekuje wprowadzania przez rozpryskiwanie, jak pokazano na łączu TIO.

Tworzy macierz $ljako tablicę tablic, a następnie przesyła dane wejściowe $argsdo pętli |%{}. Za każdym razem przez pętlę dodajemy element do jednej z dwóch podrzędnych tablic $lpoprzez przerzucanie $fzmiennej za pomocą logiki boolowskiej. Za pierwszym razem $fjest to $null, !które jest $truelub 1podczas indeksowania do tablicy. Oznacza to, że pierwszy element jest umieszczany w drugiej tablicy $l, dlatego właśnie jako $l[1]pierwszy pobiera dane wyjściowe.

Rekwizyty dla TessellatingHeckler za pomoc w grze w golfa i tę odmianę.
-2 bajty dzięki mazzy.


Ostrzeżenia

Mówiąc ściśle, pytanie jest technicznie nieważne, ponieważ PowerShell nie ma pojęcia „list” jako pseudo-niezmiennych obiektów, tylko tablice lub tabele skrótów (inaczej słowniki). Tak więc traktuję wiersz pytania „ Używaj najbardziej naturalnej reprezentacji dla list, które ma twój język ”, jako pytanie o tablice, ponieważ jest to najbliższy PowerShell. Ponadto dane wyjściowe to jeden element w wierszu, ponieważ jest to domyślny sposób zapisywania tablicy w programie PowerShell. Oznacza to wejście wartości (0,1,2,3,4)wyjściowej 0\r\n2\r\n4\r\n1\r\n3\r\n.


47 bajtów - $args+ splatting zamiast $inputi ,@()*2zamiast@(),@()
Mazzy

4

F #, 79 77 56

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

Na podstawie jednej z odpowiedzi Haskell

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

Najpierw indeksujemy listę, a następnie dzielimy ją według kryteriów: pierwsza pozycja (indeks) i 1 równa 0.
Daje nam to parę par; pierwsza lista będzie zawierała wszystkie indeksowane evens, a druga indeksowane kursy.
Następnie składamy dwie listy za pomocą operatora dołączania i ostatecznie odrzucamy indeks.

Edycja: pominięto oczywistą, że nie ma potrzeby nazywania arg „xs” (nawyki), więc można zredukować do 1-literowej nazwy


Mam również potencjał 76 bajtów, który jest w zasadzie taki sam, ale zdefiniowany jako skład funkcji. Problem polega na tym, że nie kompiluje się jako wartość, ale skutecznie działa z dowolnym argumentem listy podanym tak niepewnie, czy jest w porządku, czy nie:

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

Uwaga: List.indexed jest dostępny tylko w wersji F # 4.0, mimo że nie został jeszcze udokumentowany w MSDN


Najnowocześniejsza technologia, super!
anatolyg

1
@anatolyg To funprawda?
Conor O'Brien

Myślę, że jest to podobne do kodu Perla 6, który najpierw wypróbowałem. -> \xs { xs.pairs.classify( *.key%%2, :as( *.value ) ).map( *.value.Slip ) }Zakładając, że |>F # odpowiada mniej więcej prawemu operatorowi feeda ==>w Perlu 6. Zgaduję również, co fst>>(&&&)1>>(=)0robi
Brad Gilbert b2gills

4

JavaScript (ES6), 52 bajty

Robi to również w jednym przejściu

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


Możesz pominąć F=od początku; możesz zapisać bajt, używając:(i*=2)>=(z=x.length)?i-z+--z%2:i
Conor O'Brien,

@ CᴏɴᴏʀO'Bʀɪᴇɴ Dobry pomysł dzięki!
George Reith,


3

J, 8 bajtów

/:0 1$~#

Jest to czasownik monadyczny (jednoargumentowy), używany w następujący sposób:

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

Wyjaśnienie

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

1
Alternatywą jest /:0:`1:\także 8 bajtów.
mile


2

Mathematica, 40 bajtów

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

{}[[2;;;;2]] wyrzuci błąd.


2

Burleska, 12 bajtów

J2ENj[-2EN_+

Zastosowanie jak w:

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}

Wyjaśnienie:

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

Chociaż po wydaniu nowej aktualizacji możesz to zrobić za pomocą nowej wbudowanej funkcji Unmerge (która działa odwrotnie niż **wbudowana funkcja scalania ):

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

2

Perl, 35 33 bajtów

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

31 bajtów + 2 bajty dla -ap. Odczytuje ciąg STDIN rozdzielany spacjami:

$ 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

Gdy dane wejściowe są puste, wypisuje pojedynczą spację, którą uważam za równoważną pustej liście. Jeśli nie, można to naprawić kosztem 4 bajtów za pomocą:

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

(wymaga Perla 5.10+, drukuje końcowy znak nowej linii)

lub w cenie 5 bajtów z:

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

(brak spacji końcowych)

Jak to działa

To rozwiązanie wykorzystuje -aflagę, która dzieli dane wejściowe na białe znaki i umieszcza wyniki w @Ftablicy.

Prawdziwa magia dzieje się w push:

push@{$|--},$_

$|Zmienna jest zwykle używany do siły wyjściowej zaczerwienienie, ale ma inną ciekawą właściwość: gdy zmniejszany wielokrotnie, jego przełączanie wartości między 0 i 1.

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

Korzystając z faktu, że nie ma żadnych ograniczeń dotyczących identyfikatorów określonych przez dereferencję symboliczną , naprzemiennie wypychamy elementy tablicy na tablice @0i @1, dzięki czemu uzyskujemy @0wszystkie elementy o indeksie parzystym i @1szanse. Następnie po prostu konkatenujemy zestawione tablice, aby uzyskać wynik.


2

C 70

Nic specjalnego, tylko funkcja mapowania indeksu.

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

Mniej golfa

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


1

Vitsy, 22 bajtów

Vitsy naprawdę nie został stworzony do tego ...

r '' Vl2 / \ [N {VO] l \ [NVO]
r Odwróć niejawny stos danych numerycznych.
 '' V Zapisz znak „spacji” jako globalną zmienną końcową.
     l2 / \ [....] Powtórz rzeczy w nawiasach na długość wejścia
                        stos podzielony przez 2.
          N {Głosowanie Wypisuje górny element stosu jako liczbę, a następnie przesuwa się
                        stos raz na lewo, popchnij spację, wyrzuć ją.
               l \ [...] Dla reszty stosu powtórz to wiele razy ...
                  NVO Wyprowadza górny element stosu jako liczbę oddzieloną 
                        przez spację.

1

Perl 6 , 25 bajtów

To najkrótsza lambda, jaką mogłem wymyślić.

{|.[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 bajtów

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

Wypróbuj tutaj.

Wyjaśnienie

$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 bajtów

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

Nazwij to q (bla). Lub, jeśli x zawiera już listę do zmiany, to

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

ma tylko 35 bajtów.


1

F #, 64

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

Zainspirowany odpowiedzią Sehnsuchta (ale za mało przedstawicieli, by móc komentować).

Odwzorowuje każdą wartość na krotkę, w której drugim wpisem jest modulo indeksu listy, sortuje według modulo, a następnie odwzorowuje z powrotem na pierwotną wartość.


1

Prolog, 103 bajty

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

Przykład

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

1

coreutils bash i GNU, 68 bajtów

Zakładamy, że lista jest oddzielona znakiem nowej linii i przekazana na standardowe wejście.

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

Niestety zignoruje to wszelkie dane wejściowe poza indeksem 1999, więc nie do końca spełnia specyfikację.

Blokuje również plik tymczasowy na stałe („x”), co może być problematyczne, jeśli jest uruchamiany równolegle, i nie usuwa go później. Przepraszam za to!


1

PHP, 78 69 bajtów

PHP może fragmentować i kroić, ale nie przeplatać tablic; co sprawia, że ​​jest to trochę nieporęczne:

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

Zadzwoń przez referencję lub wypróbuj online .


pierwsze podejście (programy na 78 bajtów):

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

drukuje wiodący przecinek; włóż [!$i]przed pierwszym, $argvaby go usunąć.

Dwa inne 78-bajtowe rozwiązania (wydrukuj przecinek początkowy i końcowy):

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

Uruchom je php -nr '<code>' <arguments>lub wypróbuj online


1

Japt , 3 bajty

ñÏu

Spróbuj

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

ó c

Spróbuj

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

0

Clojure / ClojureScript, 52 bajty

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

Napisany w ClojureScript REPL, powinien być również prawidłowym Clojure.



0

Wapń , 191 bajtów

Ten był dość długi :(
Czyta tablicę z argumentów, więc uruchom to za pomocąhassium 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("  ", "")+"]");}

Uruchom i zobacz rozwinięty z przypadkiem testowym tutaj

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.