リストを偶数インデックス部分と奇数インデックス部分に分けます


26

この質問に触発された:

偶数のインデックス番号が最初に表示され、奇数のインデックス番号が後に続くように、番号のリストを受け取り、並べ替えられたリストを出力する関数(または完全なプログラム)を作成します。数値自体の値は順序に影響を与えません-インデックスのみが影響します。すべてのインデックスはゼロベースです。

例えば:

入力: [0, 1, 2, 3, 4]

出力: [0, 2, 4, 1, 3]

もう一つの例:

入力: [110, 22, 3330, 4444, 55555, 6]

出力: [110, 3330, 55555, 22, 4444, 6]

あなたの言語が持っているリストに最も自然な表現を使用してください。複雑さに関する制限はありません(たとえば、一時リストの割り当ては問題ありません。インプレースで行う必要はありません)。

PS空のリストに対して機能するはずです(空の入力=>空の出力)。



すべてのリスト要素が正または非負などであると仮定できますか?
マーティンエンダー

@MartinBüttner合理的なものを想定します。おそらく、それらが0 ... 255の範囲にあるとさえ仮定します。
アナトリグ


コンマ区切りリストを出力できますか?
オリバー

回答:



21

Python、23バイト

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

オンラインで試す


1
なんでlambda?なぜmunu?:P
Kritixi Lithos

1
@rayryeng私はあなたが私のコメントの最後にある ":P"でわかるように冗談を言っていました:)
Kritixi Lithos

5
ええ、間違いなくバイト数を5減らす必要lambdaλあります!:P
アナトリグ

3
@anatolygはPEP提出のアイデアのようです!
ニックT

2
@ThomasKwaそれは仕事に最適なツールです:P
Mego

16

Pyth、5

o~!ZQ

オンライン試すか、テストスイートを実行する

説明

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

天才!綺麗な。
isaacg

待って、これはどのように機能しますか?
justhalf

@justhalf私はもう少し説明を追加しました、それはそれを明確にしますか?
FryAmTheEggman

11

CJam、7バイト

{2/ze_}

必要に応じて一番上のスタック要素を変換するブロック(名前のない関数に最も近いもの)をプッシュします。

ここでテストしてください。

説明

説明では、スタックの一番上が配列であると想定しています[0 1 2 3 4]。実際の値は計算に影響しません。

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

ラビリンス28 25 24 23 22バイト

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

これは非常に楽しかったです!:)これは、これまでに書いた中で最も密に圧縮されたラビリンスプログラムです。私は20バイトと21バイトで非常に多くのバージョンがあり、ほとんど機能していたので、これが最適であることをまだ疑っています...

これは、入力を正の整数のリスト(任意の区切り文字)として受け取り、結果を改行で区切られた整数としてSTDOUTに出力します。

20/21バイトのハント:フォームのすべてのプログラムをチェックしました

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

どこXブルートフォースによるいかなる合理的なキャラクターですが、任意の有効な解決策を見つけることができませんでした。もちろん、それはより短い解決策が存在しないことを意味しませんが、その構造に関するまともな仮定なしに20バイトのプログラムを強制することはできません。

説明

(説明は少し時代遅れですが、ソリューションが最適であるとはまだ確信していないので、これを更新するのを待ちます。)

そのため、通常、ラビリンスプログラムは迷路のように見えるはずです。命令ポインターは廊下にありますが、その廊下に従います。IPがあらゆる種類のジャンクションに到達すると、方向はラビリンスのメインスタックの最上位値に基づいて決定されます(Labyrinthには2つのスタックがあり、無限にゼロがあります)。それは通常、非自明なループは非常に高価になることを意味します。なぜなら、壁全体に非壁のセルがある場合はすべてがジャンクションであり、ほとんどの場合、スタックの上部にはIPの正しい値がないためですあなたが望む道を辿るために。そこで、ループを拡大して、全体が中央にあり、それぞれ明確に定義された入口と出口がそれぞれ1つだけになるようにします。

でも今回は本当にラッキーだったし、すべてがうまく組み合わさったので、全部まとめて一つにまとめることができた。:)

制御フローは、_南に向かって始まります。_メインスタックにゼロを押します。これは何もしないように見えるかもしれませんが、これにより、1後で必要となる(暗黙ではない)スタックの深さが増加します。

?STDINから整数を読み取ります。読み込む整数がなくなると、ゼロがプッシュされます。その場合、IPは南に移動し続け@、プログラムを直ちに終了します(入力リストが空であるため)。それ以外の場合、IPは東になります。

現在、非常にタイトなループに入り、2つの出口点があります。

 !?;
 \?
  ;

!スタックにゼロのみを残して、STDOUTに整数を出力します。IPは東に移動し続け?、次の整数を読み取ります。それがゼロ以外の場合、権利を取得して南に移動します。?別のもの(次の偶数インデックス)を読み取ります。繰り返しますが、それがゼロでない場合は、権利を取得して西に移動します。

次に\、スタックを変更せずに改行を印刷するため、北に移動して別の権利を取得します。!次の偶数インデックスの整数を出力します。スタックに少なくとも1つの(正の)奇数インデックス整数があるので、右に曲がり続けるとループが繰り返されます。

それらのいずれかが?リストの最後に達すると、ゼロをプッシュし、対応する;にまっすぐ移動して、そのゼロを破棄します。

リストに要素が1つしかない場合は(これをすぐに印刷したため)完了です。そのため、IPは東に移動し続け@、再びプログラムを終了します(末尾を印刷します)途中で改行)。

それ以外の場合は、奇数インデックスの整数も印刷する必要があります。その場合、2つのパス(最初のループの2つの出口点から)は中央"でマージされ、どちらの場合でも東になります。

_に0をプッシュして、に左が入らないようにし、そのゼロ@;破棄します。次に、新しいループに入ります。

     "}
     ""

IPは、左下のセルでこれを入力し、北に移動して、時計回りにループを回ります。}補助スタックの上にメインスタックの最上位にシフトします。スタックにはまだ要素がありますが、IPはその処理を続けます。すべてが補助スタックにシフトされると(およびプロセスで逆になります)、IPは代わりに東に移動し続け、最後のループに入ります。

       \{@
       #!

\再度ラインフィードを印刷し{、アイテムを補助スタックからメインに戻します。それがまだリストのアイテムであった場合、それはポジティブになり、IPは南になり、そこでアイテムがで印刷され!ます。そして、#スタックの深さをプッシュ(初期は今どこにこれは_重要であり、これがあるため、#正のスタックの深さを保証します)IPはまだを通じて、右折だから、\および{再び。

すべてを印刷した後{、補助スタックの一番下からゼロを取得し、IPは東に進み@、プログラムを終了します。


8

MATLAB、24

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

Pythonのものに似ています。

@ LuisMendo、2バイトの節約に感謝します!


1
おい!PPCGでお会いできてうれしいです!
ルイスメンドー

3
もう少し短い:@(x)x([1:2:end 2:2:end])
ルイスメンドー

@LuisMendoハハ私はcodegolfが少し怖いですが、これはMATLABにとってとても簡単でした!ヒントをありがとう;)
ブレインガイダー

6

Haskell、37バイト

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

オンラインでお試しください!

foldr再帰的にもリストと奇数リストを構築します。要素をリストの先頭に追加するには、要素を奇数リストの先頭に追加して新しい偶数リストを呼び出し、前の偶数リストを新しい奇数リストと呼びます。次に、ペア[l,r]はに連結されl++rます。

タプルの代わりに2要素リストを使用して5バイトを保存してくれたØrjanJohansenに感謝します。


42バイト:

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

リストにインデックスを追加しl、偶数または奇数のいずれかをフィルタリングします。


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

44のさらに別の形式。この関数gは、すべての偶数インデックス要素を取ります。奇数のインデックスは、最初に要素を削除してから適用しgます。l空でないことが保証されていればtail、41

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

1
さらに別の変形(39バイト)l#(a:b:c)=a:(l++[b])#c;l#x=x++l;f=([]#)とのf主な機能です。
nimi

@nimiこれは素晴らしい解決策です。投稿してください。
XNOR

いいえ、投稿に含めてください。#2と#3の組み合わせです。
nimi

1
concatタプルとの代わりにリストを使用して、2番目のバージョンで5バイトを保存できますuncurry(++)
Ørjanヨハンセン

5

PowerShell v3 +、75 67 49 47バイト

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

オンラインでお試しください!

TIOリンクに示されているように、スプラッティングを介した入力が必要です。

行列$lを配列の配列として作成し、入力$argsをループにパイプします|%{}。ループを実行するたびに、ブールロジックを使用し$l$f変数をフリップフロップすることにより、2つの子配列のいずれかに要素を追加します。、スルー初めて$fである$null!となっている$true、または1配列に索引付けします。これは、最初の要素がの2番目の配列に配置されることを意味するため、最初に出力が取得さ$lれるのはそのためです$l[1]

ゴルフ支援とこのバリエーションのTessellatingHecklerの小道具。
-2バイトはmazzyのおかげです。


注意事項

質問が書かれているとおりに厳密に言えば、これは技術的に無効です。PowerShellには擬似不変オブジェクトとしての「リスト」という概念はなく、配列またはハッシュテーブル(別名辞書)だけです。そのため、PowerShellで最も近い配列のように、質問の行「言語が持つリストに最も自然な表現を使用する扱っています。さらに、出力は、PowerShellのデフォルトの配列書き込み方法であるため、1行につき1つの要素です。これは、(0,1,2,3,4)will outputの入力を意味します0\r\n2\r\n4\r\n1\r\n3\r\n


47バイト - $args+スプラッティング代わり$input,@()*2代わり@(),@()
mazzy

4

F#、79 77 56

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

Haskellの回答の1つに基づく

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

最初にリストにインデックスを付けてから、最初の項目(インデックス)と1が0に等しいという条件でパーティションを分割します。
これにより、ペアのリストのペアが得られます。最初のリストにはすべてのインデックス付き偶数が含まれ、他のリストにはインデックス付きオッズが含まれます。
それから、append演算子を使用して2つのリストを再構築し、最後にインデックスを破棄します。

編集:引数に「xs」(習慣)という名前を付ける必要がないので、1文字の名前に減らすことができる明白なものを逃しました


また、潜在的に76バイトの1つがあります。これは基本的には同じですが、関数構成として定義されています。問題は、値としてコンパイルさないが、指定されたリスト引数で効果的に機能するため、それが大丈夫かどうか不明です:

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

注:List.indexedは、MSDNにまだ文書化されていませんが、F#4.0からのみ利用可能です


最先端のテクノロジー、クール!
アナトリグ

1
@anatolyg funですよね?
コナーオブライエン

これは、私が最初に試したPerl 6コードに似ていると思います。-> \xs { xs.pairs.classify( *.key%%2, :as( *.value ) ).map( *.value.Slip ) }仮定すると、|>F#には、右方向への供給事業者とほぼ同等である==>私も唯一のものにと推測しているのPerl 6でfst>>(&&&)1>>(=)0ない
ブラッド・ギルバートがb2gills

4

JavaScript(ES6)、52バイト

また、ワンパスでそれを行います

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


F=最初から省略できます。あなたはこれを使用してバイトを保存することができます:(i*=2)>=(z=x.length)?i-z+--z%2:i
コナー・オブライエン

@CᴏɴᴏʀO'Bʀɪᴇɴいいアイデアありがとう!
ジョージリース


3

J、8バイト

/:0 1$~#

これは、次のように使用される単項(1引数)動詞です。

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

説明

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

1
別の方法は/:0:`1:\8バイトです。
マイル



2

バーレスク、12バイト

J2ENj[-2EN_+

使用方法:

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}

説明:

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

新しいアップデートがリリースされたら、新しいUnmergeビルトインでこれを行うことができます (mergeビルトインとは逆です**):

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

2

Perl、35 33バイト

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

31バイト+ 2バイト-ap。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

入力が空の場合、単一のスペースを出力します。これは空のリストと同等と見なされます。そうでない場合は、以下を使用して4バイトのコストで修正できます。

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

(Perl 5.10以降が必要、末尾の改行を出力します)

または5バイトのコストで:

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

(末尾の空白なし)

使い方

このソリューションは-aフラグを使用します。このフラグは、入力を空白に分割し、結果を@F配列にます。

本当の魔法は次の場所で起こりますpush

push@{$|--},$_

この$|変数は通常、出力のフラッシュを強制するために使用されますが、別の興味深いプロパティがあります。繰り返し減少すると、その値は0と1の間で切り替わります。

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

symbolic dereferencing指定された識別子に制限がないという事実を利用して、配列要素を@0and @1配列に交互にプッシュ@0するため、すべての偶数インデックス要素と@1オッズが発生します。次に、文字列化された配列を単純に連結して出力​​を取得します。


2

C、70

特別なものはなく、単なるインデックスマッピング関数です。

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

少ないゴルフ

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バイト

Vitsyは本当にこれを行うように作られていませんでした...

r '' Vl2 / \ [N {VO] l \ [NVO]
r暗黙的な数値入力スタックを逆にします。
 '' V「スペース」文字をグローバル最終変数として保存します。
     l2 / \ [....]括弧内のものを入力の長さだけ繰り返す
                        スタックを2で割ったもの。
          N {VOスタックの一番上の項目を数値として出力し、次にシフトします
                        スタックを1回左に移動し、スペースを押して出力します。
               l \ [...]スタックの残りについて、それを何度も繰り返します...
                  NVOスタックの一番上の項目を数字で区切って出力します 
                        スペースで。

1

Perl 6、25バイト

これは私が思いつくことができる最短のラムダです。

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

R、49バイト

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

q(blah)として呼び出します。または、xに再配置するリストが既に含まれている場合、

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

わずか35バイトです。


1

F#、64

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

Sehnsuchtの回答に触発されました(ただし、コメントするには十分な担当者ではありません)。

2番目のエントリがリストインデックスのモジュロであるタプルに各値をマップし、モジュロでソートしてから、元の値にマップします。


1

プロローグ、103バイト

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

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

1

bashおよびGNU coreutils、68バイト

リストは改行で区切られ、標準入力で渡されると想定しています。

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

残念ながら、これはインデックス1999を超える入力を無視するため、仕様を完全に満たしていません。

また、ハードコーディングされた一時ファイル( 'x')を上書きします。これは、並行して実行すると問題が発生する可能性があり、その後削除されません。ごめんなさい!


1

PHP、78 69バイト

PHPはチャンクとスライスを行うことができますが、配列をインターリーブすることはできません。これは少し大きくなります:

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

参照して呼び出すか、オンラインで試してください


最初のアプローチ(78バイトのプログラム):

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

先頭のコンマを印刷します。[!$i]最初の前に挿入$argvして削除します。

他の2つの78バイトソリューション(先頭と末尾のコンマを印刷):

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

オンラインで実行するphp -nr '<code>' <arguments>、オンラインで試してください



0

Clojure / ClojureScript、52バイト

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

ClojureScript REPLで作成され、有効なClojureである必要があります。



0

Hassium、191バイト

これはかなり長かった:(
argsから配列を読み込むので、これを実行する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("  ", "")+"]");}

実行して、ここでテストケースを展開して表示します

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.