简化数组


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

输出灵活吗?就像不同行中的数字一样,其中每一行都是一个级别;或其他数组定界符/分隔符
Luis Mendo


@LuisMendo,是的,它很灵活
Daniel Daniel

8在第线缺少一对括号So, our output is.....。但是,您已在示例代码段中对其进行了修复。
sbisit '16

2
一些答案为没有元素的嵌套级别输出空行。在这种情况下可以返回空数组[1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[]]]], [[[[[8]]]]]]吗,例如您的第一个示例为?
nimi

Answers:


1

果冻,8 字节

fFṄḟ@;/ß

输出是每行一个级别,空行表示没有元素的级别。在线尝试!

怎么运行的

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, 3, 9],但是我们必须注意不要在此处插入空数组。它们保留将数组包装在数组中[4, 7], [[5, 6]], [[[[8]]]]并将其附加到输出,结果为[1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]


可以通过为添加别名来节省一些字节filter。也许从F=(x,y)=>x.filter(y)
Cyoce

@Cyoce最终是30岁!
尼尔

您肯定还需要打高尔夫球。我认为您可以放心地替换[].concat(...v(1))v(1)以节省14个字节。可能还有其他一些事情,但是我很难跟踪脑海中的嵌套括号。
Patrick Roberts

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

主要策略是遍历嵌套数组的每个可能级别,并在一行上打印任何数字,同时将列表中的非数字(列表)保持少一层嵌套。


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

输出的每一行对应于数组的深度级别(因此,在上面的示例中为空行)。

它可以变成一个完整的程序,只需要几个字节:add -n标志和一个eval(内部@{ }将输入转换为数组而不是arrayref)将输入转换为Perl数组:

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个字节,使Patrick Roberts节省了21个字节,仅检查了代码

递归函数在输入和输出中的数组上工作。我不喜欢具有深度为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行在每次递归调用时都会一次又一次求值,但是只有递归结束时的最后一次迭代才有用。
d==02行中的特殊处理负责处理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个字节。
Patrick Roberts

@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
  • fILTER项目TQ上:
    • 检查sum是否I恒等T
    • 如果是(是一个数字),p则为rint 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]]]]]]

注意:这需要一些时间才能运行,因为它会遍历所有正整数(32或64位)以查找深度较深的嵌套层。另外:默认情况下无法打印自定义列表类型,因此,如果要如上例所示查看结果,则需要添加deriving Showdata声明(-> data L=I Int|R[L] deriving Show)。由于不需要从函数返回L-list,因此我不计算字节数。

怎么运行的:

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表示法保存了一个字节。谢谢!


不记法保存一个字节h l=R$do d<-[1..];[i|(e,i)<-0#l,d==e]!d
BlackCap,2016年

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感谢您的关注。这应该是固定的。
Arnauld

我相信现在看起来不错!:)
Kade
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.