配列を単純化する


22

入力

配列または正の連続した昇順整数を含むことができる配列。配列には、その中に任意の数の配列を含めることができます。空の配列はありません。

出力

簡素化されたこの配列

配列を単純化する方法

[1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]例として配列を使用します。

最初に、値のネストの深さを確認します。深度とそれらの深度での数値は次のとおりです。

0  1
1  2 3 9
2  4 7
3  5 6
5  8

出力配列は、元の配列の数値を取得し、ネストの深さでグループ化してから、要素の元の深さの深さでグループをネストすることで構築します。数字を昇順と深さで並べます。

したがって、出力は [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]

[1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]] -> [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]
[[[1]], [2, [3]], 4, [5, [6, [7, [8], [9, [[10]]]]]]] -> [4, [2, 5], [[1, 3, 6]], [[[7]]], [[[[8, 9]]]], [[[[[[10]]]]]]]
[1] -> [1]
[1, [2], [[3]], [[[4]]], [[[[5]]]]] -> [1, [2], [[3]], [[[4]]], [[[[5]]]]]
[1, [[[[2], 3]]] [[4]]] -> [1, [[4]], [[[3]]], [[[[2]]]]]

出力は柔軟ですか?異なる行の数字のように、各行は1レベルです。または他の配列区切り記号/区切り記号
ルイスメンドー


@LuisMendo、ええ、それは柔軟です
ダニエル

8行に1つのブラケットペアがありませんSo, our output is.....。ただし、サンプルスニペットで修正しました。
sbisit

2
一部の回答では、要素を含まないネストレベルの空行が出力されます。そのような場合に空の配列を返すことは問題あり[1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[]]]], [[[[[8]]]]]]ませんか?
-nimi

回答:


1

ゼリー、8 バイト

fFṄḟ@;/ß

出力は行ごとに1レベルで、要素のないレベルには空の行があります。オンラインでお試しください!

使い方

fFṄḟ@;/ß  Main link. Argument: A (array)

 F        Flat; yield all integers (at any level) in A.
f         Filter; intersect A with the integers, yielding those at level 0.
  Ṅ       Print the filtered array and a linefeed. Yields the filtered array.
     ;/   Reduce by concatenation.
          This decreases the levels of all integers at positive levels by 1.
   ḟ@     Swapped filter-false; remove the integers at level 0 in A from the array
          with decreased levels.
       ß  Recursively call the main link on the result.
          The program stops once A is empty, since ;/ will result in an error.

3

JavaScript(ES6)、139 109バイト

f=(a,v=b=>a.filter(a=>b^!a[0]))=>a[0]?v().concat((a=f([].concat(...v(1))),b=v())[0]?[b]:[],v(1).map(a=>[a])):[]

入力例を使用した説明:vは、配列(パラメーター付き1)または値(パラメーターなし)を返すヘルパーメソッドです。a = [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]空ではないから始めます。配列をフィルタリングして、を与え[1]ます。次に、連結された配列を再帰的に呼び出します。[2, 3, [4], [[5, 6], 7, [[[8]]]], 9]つまり、結果はになり[2, 3, 9, [4, 7], [[5, 6]], [[[[8]]]]]ます。配列を再度フィルター処理して、出力の2番目の項を取得しますが、[2, 3, 9]ここに空の配列を挿入しないように注意する必要があります。配列[4, 7], [[5, 6]], [[[[8]]]]内に配列をラップして出力に追加するために残っているため、結果がになり[1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]ます。


にエイリアスを作成することで、数バイトを節約できる場合がありますfilter。多分始まるF=(x,y)=>x.filter(y)
チョイス

@Cyoceは最終的に30になりました!
ニール

あなたは間違いなくこれでやるべきゴルフが残っています。私はあなたが安全に置き換えることができると思う[].concat(...v(1))v(1)14のバイトを保存します。おそらく他にもいくつかありますが、私は頭の中で入れ子になった括弧を追跡するのに苦労しています。
パトリックロバーツ

1
@PatrickRobertsはと[].concat(...v(1))は非常に異なる獣v(1)です。簡単な例については、検討しa = [2, [3], [[4]]]、次にv(1) = [[3], [[4]]]けど[].concat(...v(1)) = [3, [4]]
ニール

@Neilああ、うわー、口を開ける前に提案をテストすべきだった。..かかわらず、これを行うための簡単な方法があるはずような気がします
パトリック・ロバーツ

2

05AB1E27 26 25 21バイト

D˜gFvyydi„ÿ ?}}¶?.gG«

オンラインでお試しください!.gまだTIOにないため、少し変更されています)

説明

D˜gF                    # flattened input length times do
    vy                  # for each y current level of list
      ydi„ÿ ?}          # if y is a digit, print with space
              }         # end v-loop
               ¶?       # print newline
                 .g     # calculate length of stack (this should be .g but I can't test)
                   G«   # length stack times, concatenate items on stack

主な戦略は、ネストされた配列の各レベルをループし、リスト内の非数字(リスト)を1レベル下に入れたまま、1行に数字を出力することです。


2

Perl、52バイト

再帰的なサブルーチンです。(Perlの回答としては珍しい、私は知っている..)

sub f{say"@{[grep!ref,@_]}";@_&&f(map/A/?@$_:(),@_)}

そのように呼び出します:

$ perl -E 'sub f{say"@{[grep!ref,@_]}";@_&&f(map/A/?@$_:(),@_)}f(1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9])'
1
2 3 9
4 7
5 6

8

出力の各行は、配列の深さレベルに対応します(上の例の空の行)。

あと数バイトで完全なプログラムに変換できます。入力をPerl配列に変換するために-n、フラグとeval@{ }入力をarrayrefではなく配列に変換するための)を追加します。

perl -nE 'sub f{say"@{[grep!ref,@_]}";@_&&f(map/A/?@$_:(),@_)}f(@{+eval})' <<< "[1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]"

私の以前のアプローチはわずかに長かった(65バイト)が、それでも面白いので、ここでそれをさせよう:

perl -nE '/\d/?push@{$;[$d-1]},$_:/]/?$d--:$d++for/\[|]|\d+/g;say"@$_"for@' <<< "[1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]"

2

JavaScript(ES6)121 144 152

編集多くを修正し、1バイトがthx Patrick Robertsを保存し、さらに21個がコードをレビューしました。

入力および出力の配列で機能する再帰関数。深さ1の要素を出力配列の単一の要素として持つ要求は好きではありません(より大きなレベルは1つの要素としてグループ化されます)[l1,l1, [l2...], [[l3...]] ]。これはより直接的です:[ [l1...], [[l2...]], [[[l3...]]] ]

f=(l,d=0,r=[])=>l.map(v=>v[0]?f(v,d+1,r):r[d]=[...r[d]||[],v])
r.reduce((r,v,d)=>d?[...r,(n=d=>d-->1?[n(d)]:v)(d)]:v,[])

読みやすくするために改行が追加されました。

いくつかの注意:行2は各再帰呼び出しで何度も何度も評価されますが、再帰の最後の最後の反復のみが有用です。2行目
の特別な処理d==0は、レベル1の要素の異常を処理します。アレイ出力にネスト再帰関数ハンドル
n

テスト

f=(l,d=0,r=[])=>l.map(v=>v[0]?f(v,d+1,r):r[d]=[...r[d]||[],v])
&&r.reduce((r,v,d)=>d?[...r,(n=d=>d-->1?[n(d)]:v)(d)]:v,[])

console.log=x=>O.textContent+=x+'\n'

test=[
 [ 
   [1, [2,3], 4], /* -> */ [1, 4, [2,3]]
 ]
,[
   [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]], 
   // ->
   [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]
 ]
,[
  [[[1]], [2, [3]], 4, [5, [6, [7, [8], [9, [[10]]]]]]],
  // ->
  [4, [2, 5], [[1, 3, 6]], [[[7]]], [[[[8, 9]]]], [[[[[[10]]]]]]] 
 ]
,[  
  [1], /* -> */ [1]
 ]
,[  
  [1, [2], [[3]], [[[4]]], [[[[5]]]]],
  // ->
  [1, [2], [[3]], [[[4]]], [[[[5]]]]]
 ]
,[  
  [1, [[[[2], 3]]], [[4]]],
  [1, [[4]], [[[3]]], [[[[2]]]]]
]]

test.forEach(t=>{
  var i=t[0], k=t[1], r=f(i),
      si=JSON.stringify(i),
      sr=JSON.stringify(r),
      sk=JSON.stringify(k)
  
  console.log((sr==sk?'OK ':'KO ')+si + " => " + sr)
})
<pre id=O></pre>


1
ネストされた配列と正の整数のみがあり、入力の配列が空でないことを指定している場合、三項演算子のより簡単なテストはのv[0]代わりになりv.mapます。1バイト節約します。
パトリックロバーツ

@PatrickRobertsクールな感謝
edc65

1

JavaScript(ES6)168バイト

f=a=>(s=[],b=-1,k=0,a.replace(/\d+|\[|\]/g,a=>a=='['?b++:a==']'?b--:(s[b]=s[b]||[]).push(a)),'['+s.map((a,b)=>k=a&&(k?',':'')+'['.repeat(b)+a+']'.repeat(b)).join``+']')

デモ


1

PHP、145バイト

<?function c($r){$n=[];foreach($r as$k=>$v)if(is_array($v)){$n=array_merge($n,$v);unset($r[$k]);}if($n)$r[]=c($n);return$r;}print_r(c($_GET[a]));

壊す

function c($r){
  #usort($r,function($x,$y){return is_array($x)<=>is_array($y)?:$x<=>$y;}); 
#no need to sort and a simple sort($r); do it sort array after scalar
  $n=[];
  foreach($r as$k=>$v)if(is_array($v)){$n=array_merge($n,$v);unset($r[$k]);} # put arrays on the same depth together
  if($n)$r[]=c($n); # recursive if an array exists
  return$r; #return changes
}
print_r(c($_GET[a])); #Output and Input

1

Pyth、 19 16バイト

W=Qsf!&sITp+TdQk

オンラインでお試しください。 テストスイート。

先頭のスペースに注意してください。Perlの回答のような行のレベルを出力します。

説明

  • 暗黙的な入力 Q
  • fイルターアイテム TQ
    • かどうかをチェックしs、UMでありますI dentity onしTます。
    • それが(数字だった)場合、pリントTとスペース+ ... d
    • そうでない場合(配列である場合)、そのままにしてください。
  • sアイテム。これにより、各アイテムから配列のレイヤーが削除されます。何も残っていない場合は、0ます。
  • =結果を割り当てるQます。
  • W結果が空でない間は、空の文字列kと改行を出力します。

1

Haskell、124 123バイト

data L=I Int|R[L]
d#R l=((d+1)#)=<<l
d#i=[(d::Int,i)]
[]!_=[]
l!1=l
l!d=[R$l!(d-1)]
h l=R$do d<-[1..];[i|(e,i)<-0#l,d==e]!d

Haskellはデフォルトでは混合リスト(整数と整数のリスト)をサポートしていないため、カスタムリストタイプを定義しますL。使用例:

*Main> h (R[I 1, R[I 2, I 3], R[ R[I 4]], R[ R[ R[I 5, I 6], I 7, R[R[R[I 8]]]], I 9]])
R [I 1,R [I 2,I 3,I 9],R [R [I 4,I 7]],R [R [R [I 5,I 6]]],R [R [R [R [R [I 8]]]]]]

注:すべての正のInt(32ビットまたは64ビット)をループして、それより深いネストレベルを検索するため、実行には時間がかかります。また、カスタムリストタイプはデフォルトでは印刷できないため、上記の例のように結果を表示する場合はderiving Showdata宣言(-> data L=I Int|R[L] deriving Show)。関数からLリストを返すために必要ではないため、バイトをカウントしません。

使い方:

data L=I Int|R[L]               -- custom list type L, which is either an Int
                                -- (-> I Int) or a list of some L (-> R [L]) 

d#R l=((d+1)#)=<<l              -- # makes a list of (depth, I-number) pairs from
d#i=[(d::Int,i)]                -- a given L-list, e.g.
                                -- 0 # (R[I 1,R[I 2,I 3],I 4]) -> [(1,I 4),(2,I 2),(2,I 3),(1,I 4)]
                                -- the type annotation ::Int makes sure that all
                                -- depths are bounded. Without it, Haskell
                                -- would use arbitrary large numbers of type
                                -- ::Integer and the program won't finish

[]!_=[]                         -- ! wraps a list of Is with (d-1) additional
l!1=l                           --  R constructors
l!d=[R$l!(d-1)]

h l=                            -- main function, takes a L-list
      do d<-[1..]               -- for each nest level d make
        [i|(e,i)<-0#l,d==e]     -- a list of all I where the depth is d
                           !!d  -- and wrap it again with d-1 Rs         
     R$                         -- wrap with a final R

@BlackCapを編集して>>=do表記法に切り替えることで1バイトを保存しました。ありがとう!


表記法はバイトを節約しますh l=R$do d<-[1..];[i|(e,i)<-0#l,d==e]!d
BlackCap

0

JavaScript(ES6)、127 137 134バイト

入力として配列を受け取り、文字列を返します。

f=(a,l=[],d=0,o='')=>`[${a.map(x=>x[0]?f(x,l,d+1,o+'['):l[d]=(l[d]?l[d]+',':o)+x),l.map((s,d)=>x+s+']'.repeat(d,x=','),x='').join``}]`

テストケース


@Shebang気づいてくれてありがとう。これは修正する必要があります。
アーナルド

私はそれが今よさそうだと信じています!:)
Kade
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.