确定数组的深度


31

您星期一晚上(或者世界另一半的星期二早上)的简单挑战。

您将得到一个嵌套的,可能是参差不齐的正整数数组作为输入:

[1, [[2, 3, [[4], 5], 6, [7, 8]], 9, [10, [[[11]]]], 12, 13], 14]

您的任务是确定其深度,该深度是列表中任何整数的最大嵌套深度。在这种情况下,深度11就是6,这是最大的。

您可以假设所有数组都不为空。

您可以编写程序或函数,通过STDIN(或最接近的替代方案),命令行参数或函数自变量获取输入,并通过STDOUT(或最接近的替代方案),函数返回值或函数(out)参数输出结果。

只要不对实际信息进行预处理,就可以采用任何支持非矩形数组(具有不同深度的嵌套数组)的便捷列表或字符串格式进行输入。

您不得使用任何与数组形状有关的内置程序(包括解决此难题的内置程序,这些内置程序可为您提供嵌套数组的尺寸)。唯一的例外是获取数组的长度。

适用标准规则。

测试用例

[1]                                                               -> 1
[1, 2, 3]                                                         -> 1
[[1, 2, 3]]                                                       -> 2
[3, [3, [3], 3], 3]                                               -> 3
[[[[1], 2], [3, [4]]]]                                            -> 4
[1, [[3]], [5, 6], [[[[8]]]], 1]                                  -> 5
[1, [[2, 3, [[4], 5], 6, [7, 8]], 9, [10, [[[11]]]], 12, 13], 14] -> 6
[[[[[[[3]]]]]]]                                                   -> 7

2
在聊天中讨论之后,我决定允许长度内置,因为某些语言要求它们明确地遍历数组。
Martin Ender

2
仅用于普通教育:APL的内置原语正是为此而设计的
2013年

@MartinBüttner我遇到了一个小问题。我在Java中开始执行此操作,毫无疑问,在测试输入时,逗号导致它将输入分成多个命令行参数,而不是一个。我可以\ 在输入中使用转义符吗?编辑:没关系只是尝试那样。那也不起作用。我不能使用CMD参数吗?
Ashwin Gupta

@AshwinGupta不能将命令行参数用引号引起来吗?您还可以从STDIN读取输入,或提交将实际数组对象作为参数的函数。
Martin Ender

@MartinBüttner哦,我不知道那是我会尝试的东西。目前仅使用扫描仪。(System.in)。我相信这是STDIN的一种形式?
Ashwin Gupta'2

Answers:


20

K,4个字节

#,/\

在K中,,/将联接一个列表的所有元素。通用习语,//迭代到固定点,从而完全展平任意嵌套的列表。,/\将以类似的方式迭代到固定点,但收集中间结果列表。通过计算到达固定点(#)之前我们访问了多少中间结果,我们得到了想要的答案:最大嵌套深度。

“通过定点扫描进行连接的计数”。

实际上:

 (#,/\)'(,1
        1 2 3
        ,1 2 3
        (3;(3;,3;3);3)
        ,((,1;2);(3;,4)))
1 1 2 3 4

15

视网膜 10

  • 感谢@ӍѲꝆΛҐӍΛПҒЦꝆ,节省了1个字节
  • @MartinBüttner节省了14个额外的字节
+`\ w |} {

{

这里的输入格式有些人为- _字符用于列表分隔符,因此输入看起来像这样{1_{{2_3_{{4}_5}_6_{7_8}}_9_{10_{{{11}}}}_12_13}_14}

  • 阶段1-重复删除}{和所有其他\w字符。这样的效果是:a)使所有级别的所有列表仅包含一个元素,并且b)删除所有非列表结构的字符。
  • 第二阶段-剩余计数 {。这提供了最深层次的嵌套。

在线尝试。


如果这太麻烦了,那么先前的答案是:

视网膜 13

假定列表包含在花括号中 {}

+`[^} {] |} {

{

在线尝试


1
您的代码可以缩短为13个字节(如果稍微扩展输入格式,则为11个字节)。让我知道是否需要提示。:)(我真的不想自己发布它,因为它实际上是相同的解决方案。)
Martin Ender 2016年

这是两件事。a)您可以通过稍微调整输入格式来保存一个字节左右。b)不管如何,您都可以节省很多字节...如果尝试不一次处理多个测试用例,您能找到一个更短(更简单)的解决方案吗?
马丁·恩德

我什至没有想到这一点。那就是节省的字节数。我对输入格式的更改会更弱。关于b),请记住视网膜最原始和最简单的操作模式是什么?
Martin Ender

1
是的 我的a)是指从输入中删除空格。然后,您可以使用_代替来保存更多的两个字节,,但这可能有点麻烦。
Martin Ender

@MartinBüttner好主意!同意- _分隔符可能太人为了。所以我将两个版本都保留在答案中
Digital Trauma

12

Python 2,33个字节

f=lambda l:l>{}and-~max(map(f,l))

通过说数字的深度为0来递归地定义深度,列表的深度比其元素的最大深度大一。通过与空字典进行比较来检查数字与列表,空字典{}在数字2的内建类型的任意顺序上位于数字的上方但在列表的下方。


现在允许使用长度内置的格式(如果有帮助)。
马丁·恩德

6

Pyth- 11 10 7个字节

@Dennis节省了1个字节

@Thomas Kwa节省了4个字节

eU.usNQ

在这里在线尝试

继续对数组求和,直到它停止更改为止,这意味着它只是一个数字,通过进行与列表相同长度的urange并取最后一个元素,来累加此操作以保存所有中间结果并获得长度。


m!!d可以成为&R1
丹尼斯

@丹尼斯(Dennis)酷,这很聪明
Maltysen

lOP中不允许@ThomasKwa 。
Maltysen'2

@ThomasKwa真的很聪明,谢谢!
Maltysen'2

现在允许使用长度内置的格式(如果有帮助)。
马丁·恩德

6

Haskell,43个字节

'['#x=x-1
']'#x=x+1
_#x=x
maximum.scanr(#)0

用法示例:maximum.scanr(#)0 $ "[1, [[3]], [5, 6], [[[[8]]]], 1]"->5

Haskell没有混合列表(IntegerList of Integer),因此我无法利用某些列表检测功能,因此必须解析字符串。

我从右边开始,0每加1,每]减1,[否则保持该值。scanr保留所有中间结果,因此maximum可以完成工作。


5

JavaScript(ES6),35个字节

f=a=>a[0]?Math.max(...a.map(f))+1:0

说明

递归函数,它返回数组的最大深度,或者0如果传递了数字,则返回最大深度。

var solution =

f=a=>
  a[0]?                   // if a is an array
    Math.max(...a.map(f)) // return the maximum depth of each element in the array
    +1                    // add 1 to increase the depth
  :0                      // if a is a number, return 0

// Test cases
result.textContent =
`[1]                                                              -> 1
[1, 2, 3]                                                         -> 1
[[1, 2, 3]]                                                       -> 2
[3, [3, [3], 3], 3]                                               -> 3
[[[[1], 2], [3, [4]]]]                                            -> 4
[1, [[3]], [5, 6], [[[[8]]]], 1]                                  -> 5
[1, [[2, 3, [[4], 5], 6, [7, 8]], 9, [10, [[[11]]]], 12, 13], 14] -> 6
[[[[[[[3]]]]]]]                                                   -> 7`
.split`\n`.map(t=>(c=t.split`->`.map(p=>p.trim()),c[0]+" == "+c[1]+": "+(solution(eval(c[0]))==c[1]?"Passed":"Failed"))).join`\n`
<input type="text" id="input" value="[1, [[2, 3, [[4], 5], 6, [7, 8]], 9, [10, [[[11]]]], 12, 13], 14]" />
<button onclick="result.textContent=solution(eval(input.value))">Go</button>
<pre id="result"></pre>


现在允许使用长度内置的格式(如果有帮助)。
马丁·恩德

4

MATL,11 14 15字节

'}{'!=dYsX>

在MATL中,花括号用于此类数组。无论如何,输入都是作为字符串处理的,因此可以同样使用方括号来修改代码中的两个字符。

在线尝试!

          % implicitly take input as a string (row array of chars)
'}{'!     % 2x1 (column) char array with the two curly brace symbols
=         % 2-row array. First / second row contains 1 where '}' / '{' is found
d         % second row minus first row
Ys        % cumulative sum of the array
X>        % maximum of the array
          % implicitly display result

现在允许使用长度内置的格式(如果有帮助)。
马丁·恩德

4

八度,29字节

@(a)max(cumsum(92-(a(a>90))))

映射[到1和]-1,然后取累计总和的最大值。

输入是以下形式的字符串

S6 = '[1, [[3]], [5, 6], [[[[8]]]], 1]';

样品在亚乙基酮上运行。


如果您使用的{}?我认为,相当于OP中数组的倍频程是单元格数组
Luis Mendo

@LuisMendo不,因为那是2个额外的字节:)另外,由于我从未真正创建数组,所以只需解析输入字符串,我认为这并不重要。但是您提醒我将期望的输入添加到我的答案中。
烧杯2016年

真正!更长的ASCII码
Luis Mendo

@LuisMendo实际上,长1个字节。第二个比较仅需大于“ 9”。但是您会想到:D
烧杯,

4

朱莉娅,55 26字节

f(a)=0a!=0&&maximum(f,a)+1

这是一个递归函数,它接受具有类型内容的一维数组Any并返回整数。将数组传递给函数时,请在所有括号前面加上Any,即f(Any[1,Any[2,3]])

该方法非常简单。对于输入一个,我们乘一个由0,并检查结果是否是标量0。如果不是,我们知道,一个是一个数组,所以我们应用函数的每个元素,取最大值,并添加1。

感谢Dennis,节省了29个字节!


2
达特高尔夫。<filler>
El'endia Starman '02

3

Ruby,53个字节

i=0;p gets.chars.map{|c|i+=('] ['.index(c)||1)-1}.max

从STDIN输入,输出到STDOUT。

i=0;                 initialize counter variable
p                    output to STDOUT...
gets                 get line of input
.chars               enumerator of each character in the input
.map{|c|             map each character to...
i+=                  increment i (and return the new value) by...
('] ['.index(c)||1)  returns 0 for ], 2 for [, 1 for anything else
-1                   now it's -1 for ], 1 for [, 0 for anything else
                     therefore: increment i on increase in nesting, decrement i
                       on decrease, do nothing otherwise
}.max                find the highest nesting level that we've seen

现在允许使用长度内置的格式(如果有帮助)。
马丁·恩德

3

果冻,10 7个字节

¬;/SпL

在线尝试!验证所有测试用例

怎么运行的

¬;/SпL  Main link. Input: A (list)

¬        Negate all integers in A. This replaces them with zeroes.
    п   Cumulative while loop.
   S       Condition: Compute the sum of all lists in A.
                      If the sum is an integer, it will be zero (hence falsy).
 ;/        Body:      Concatenate all lists in A.
      L  Count the number of iterations.

更新资料

在写这个答案时,我注意到Jelly对于参差不齐的列表表现得很怪异,因为我将列表的深度计算为最小增量

这已在最新版本中得到解决,因此下面的代码(6个字节)现在可以使用。

¬SSпL

这将对数组的行求和而不是将它们连接在一起。


大概ŒḊ是比挑战新的吗?
caird coinheringaahing 17-10-19

您不得使用任何与数组形状有关的内置组件(包括解决此难题的内置组件,它们可以使您获得嵌套数组的尺寸)。
丹尼斯


3

Mathematica,27个 20字节

Max[#0/@#]+1&[0#]-1&

简单的递归函数。


有可能使无效If,从而节省7个字节。(让我知道是否需要提示。)
Martin Ender

@MartinBüttner我放弃... Replace基于解决方案的时间至少与这个时间一样长
LegionMammal978 '16

1
Map对整数执行ping操作是不可操作的:Max[#0/@#]+1&[0#]-1&。该-1也可以去像内部调用中...&[0#-1]&
马丁·恩德

3

PHP,61字节

function d($a){return is_array($a)?1+max(array_map(d,$a)):0;}

递归函数,将其自身用作映射函数以用其深度替换每个元素。


我刚刚注意到:JS中的相同内容只有35个字节。仍然在PHP漂亮。
泰特斯

很好,你打败了我。但是我更新了我的游戏,并打败了你:)
2016年

3

PHP,84 72 64 63 60字节

注意:组合比较运算符需要PHP 7。也使用IBM-850编码

for(;$c=$argv[1][$i++];)$c>A&&$t=max($t,$z+=~ú<=>$c);echo$t;

像这样运行:

php -r 'for(;$c=$argv[1][$i++];)$c>A&&$t=max($t,$z+=~ú<=>$c);echo$t;' "[1, [[3]], [5, 6], [[[[8]]]], 1]"
  • 通过仅计算字符串表示的花括号来节省12个字节
  • 通过简化字符串比较并在[和情况下使用char的序数来节省8个字节]
  • 通过不强制转换$i为int来保存一个字节。字符串偏移量隐式转换为int
  • 通过使用组合比较运算符而不是序号节省了3个字节

好主意,打高尔夫球好!看看我的
泰特斯


2

Python 3中,42 39字节

-3000字节归功于Sp3000

这本质上是xnor的Python 2解决方案的一部分

f=lambda l:"A"<str(l)and-~max(map(f,l))

不幸的是,[] > {}返回一个unorderable types错误,因此无法使用xnor的特殊技巧。取而代之的-0123456789是,ASCII值低于A,ASCII值低于[],因此字符串比较有效。


2

CJam(15字节)

q~{__e_-M*}h],(

在线演示

解剖

q~      e# Read line and parse to array
{       e# Loop...
  _     e#   Leave a copy of the array on the stack to count it later
  _e_-  e#   Remove a flattened version of the array; this removes non-array elements from
        e#   the top-level array.
  M*    e#   Remove one level from each array directly in the top-level array
}h      e# ...until we get to an empty array
],(     e# Collect everything together, count and decrement to account for the extra []

对于相同的长度,但在丑陋的骇客领域,

q'[,-{:~_}h],2-

s/ugly/beautiful/
丹尼斯

@Dennis,我指的'[,-是将字符串剥离为的使用[],这取决于内容的限制。无论数组内容如何,​​平坦化的方法都有效。
彼得·泰勒

第二个更漂亮。第一个具有两种类型不匹配的括号
Cyoce

2

Sed,40个字符

(39个字符的代码+ 1个字符的命令行选项。)

s/[^][]+//g
:;s/]\[//;t
s/]//g
s/\[/1/g

输入:字符串,输出:一元数。

样品运行:

bash-4.3$ sed -r 's/[^][]+//g;:;s/]\[//;t;s/]//g;s/\[/1/g' <<< '[1, [[2, 3, [[4], 5], 6, [7, 8]], 9, [10, [[[11]]]], 12, 13], 14]'
111111

Sed,33个字符

(32个字符的代码+ 1个字符的命令行选项。)

如果输出中允许尾随空格。

s/[^][]+//g
:;s/]\[//;t
y/[]/1 /

输入:字符串,输出:一元数。

样品运行:

bash-4.3$ sed -r 's/[^][]+//g;:;s/]\[//;t;y/[]/1 /' <<< '[1, [[2, 3, [[4], 5], 6, [7, 8]], 9, [10, [[[11]]]], 12, 13], 14]'
111111      

2

六边形,61字节

编辑:感谢@Martin Ender♦从-1技巧中给我节省了1个字节!

|/'Z{>"-\..(.."/'&<'..{>-&,=+<$.{\$._{..><.Z=/...({=Z&"&@!-"

在线尝试验证测试用例!

下面的图像未修改,但流程基本相同。另请注意,-1如果输入不是数组(即不包含[])。

我在Hexagon里面有很多没有操作的东西……我想它肯定可以打更多的高尔夫。

说明

简而言之,它-1在遇到a 时添加,并且在遇到a时[添加。最后,它会打印出它所拥有的最大值。1]

让我们沿测试用例5进行测试,以查看其沿String运行时的行为[1, [[3]], [5, 6], [[[[8]]]], 1]

它从开头开始,并在W角输入:

Brackets

由于仍然有输入(不是空字符\0或EOL),因此它会绕到顶部并开始深红色路径。

这是从那里到可爱的时候发生的事情><

,[入缓冲器,和{Z设定恒定Z到是90 '移动到DIFF和-计算差值。对于[]差异会13分别。对于数字,空格和逗号,它将为负。

M1 M2

然后,我们运行(两次(一次在深红色路径的末尾,一次在绿色路径包装后的开始),以获取-11响应[and ]。在这里,我们将的命名更改DiffValue。将此值添加到深度。(我曾经Z&确保它复制正确的邻居)。然后我们计算lastMin - Depth并在“内存”边缘得到一个数字minLR

然后,我们将其应用于&(在绿色路径的末尾)minLR:如果数字<= 0,它将复制左值(即lastMin - Depth <= 0 => lastMin <= Depth),否则将获取右侧的值。

我们环绕到水平的蓝色路径,然后Z&再次看到复制了minLR。然后,我们"&复制了计算出的最小值。括号被认为是平衡的,因此最小值必须<= 0。包装后,蓝色路径左移并命中(,使副本1小于实际分钟数。重用-,我们再创建一个1-off副本作为Buffer的邻居:

M3

注意: copy重命名为1-off

当蓝色路径命中\,得到了一个很好的"<捕获到主循环中。

当循环命中1,或其他数字输入:

othersM4

差异将变为负数,并且会反射回主循环以进行下一个输入。

当一切都经过主循环后,我们到达EOL,这使Buffer -1最终到达了底部边缘:

M5

'将MP移至1-off copy)递增,然后~取反得到正确的Max Depth值,并用!

故事的结尾@

我想我一定要过度复杂一些。如果我只需要“移回”和“打印”而不增加和取反,那么我不用使用完整的Hexagon就可以节省2个字节。

非常感谢TimwiEsoteric IDEHexagony Colorer


您可以通过将最后一行更改为使用-1from 来节省一个字节,:(@!-".尽管我同意可能可以削掉更多的东西,甚至可以通过一些重组使其适应边长4)。
马丁·恩德

还没想到要使用-1!拿到计算机后将进行编辑。如果温度是左邻,我将有可能挽救了不少Z使用Z&。并且应该有更好的方法使用隐式if启动程序。
阳光双关

2

Brainfuck,48个字节

,[<++[>-<------]>++[+[<]>>[-]]+<,]-[<[>+<-]>>]<.

格式:

,
[
  <++[>-<------]>++
  [
    not close paren
    +
    [
      not open paren
      <
    ]
    >>[-]
  ]
  +<,
]
-[<[>+<-]>>]
<.

接受格式类似的输入,(1, ((3)), (5, 6), ((((8)))), 1)并输出一个字节值

在线尝试。

此存储由存储器位置的深度,移动用于指针右(和左对),而忽略其他字符。访问的单元格带有1标记,因此在主循环的末尾,depth + 1当前单元格的右侧将有标记。然后将其添加以打印最终结果。


以前的69字节解决方案使用不同的方法:

,
[
  >>++[<<->>------]<-<++
  [
    not close paren
    >++<+
    [
      not open paren
      >-<[-]
    ]
  ]
  <
  [
    [>+>]
    <[<-<]
    >
  ]
  >>[<+> >+<-]
  ,
]
<.

在此版本中,深度和最大深度显式存储在单元格中。


1

Pyth,15 13字节

-2字节,@ Maltysen

eSm-F/Ld`Y._z

计数的累积计数之间的差异[],并取最大值。Y是空数组,其字符串表示形式(`)很方便[]

在这里尝试。


现在允许使用长度内置的格式(如果有帮助)。
马丁·恩德

1

CJam,19 22 23字节

0l{_91=\93=-+_}%:e>

与我的MATL答案类似的想法。

感谢Peter Taylor删除了3个字节

在这里尝试

0                            push a 0
l                            read line as string
{            }%              map this block on the string
  _91=\93=-                  1 if it's an opening bracket, -1 if closing
           +_                cumulative sum
               :e>           fold maximum function


1

Ruby,51个字符

起初是对DoorknobRuby答案的改进建议,但结果有所不同。因此,我将其作为单独的答案发布。针对深度计数的想法(?\\<=>$&,从降序'] ['.index(c))的投票应转到原始答案。)

m=i=0
gets.gsub(/\[|\]/){m=[m,i+=?\\<=>$&].max}
p m

输入:字符串,输出:数字。

样品运行:

bash-4.3$ ruby -e 'm=i=0;gets.gsub(/\[|\]/){m=[m,i+=?\\<=>$&].max};p m' <<< '[1, [[2, 3, [[4], 5], 6, [7, 8]], 9, [10, [[[11]]]], 12, 13], 14]'
6

1

Perl 6,53字节

闭包:

{my ($m,$d);/[\[{$d++;$m=max $m,$d}|\]{$d--}|.]*/;$m}

需要一个参数,例如:

{my ($m,$d);/[\[{$d++;$m=max $m,$d}|\]{$d--}|.]*/;$m}("[[[3]][2]]")
3

说明:

{ my ($m,$d);                 # start closure, declare variables    

  /                           # start regex match

   [                          # start (non-capturing) group

     \[ {$d++;$m=max $m,$d} | # match [ and track depth; OR

     \] {$d--}              | # match ] and track depth; OR

     .                        # match one character

   ]*                         # repeat group

  /;                          # end regex

  $m                          # return max depth
}

1

Minkolang 0.1531个 29 24字节

路易斯·门多Luis Mendo)的CJam答案激发了我的算法,并节省了5个字节!

od5&j$ZN.d"["=$r"]"=~++d

在这里尝试!

说明

本质上,这段代码所做的是保持一个总计为+1,每个为[-1 的运行总计],跟踪所达到的最大值,并在最后输出该最大值。循环是由Minkolang的代码框的环形性质处理的。

od           Take character from input and duplicate it (0 if input is empty)
  5&         Pop top of stack and skip the following five spaces if 0
    j$Z      Push the maximum value of the stack
       N.    Output as number and stop.

  d                  Duplicate top of stack for character tests
   "["=              +1 if the character is [
       $r            Swap top two items of stack
         "]"=~       -1 if the character is ]
              ++     Add twice
                d    Duplicate top of stack for the running total

1

Ruby,41个字符

f=->a,d=1{a.map{|e|f[e,d+1]rescue d}.max}

参数:数组,返回:数字。

样品运行:

2.1.5 :001 > f=->a,d=1{a.map{|e|f[e,d+1]rescue d}.max}
 => #<Proc:0x0000000214d258@(irb):1 (lambda)> 

2.1.5 :002 > f[[1, [[2, 3, [[4], 5], 6, [7, 8]], 9, [10, [[[11]]]], 12, 13], 14]]
 => 6 

1

Oracle SQL 11.2,133字节

SELECT MAX(d)FROM(SELECT SUM(DECODE(SUBSTR(:1,LEVEL,1),'[',1,']',-1,0))OVER(ORDER BY LEVEL)d FROM DUAL CONNECT BY LEVEL<=LENGTH(:1));

未打高尔夫球

SELECT MAX(d)
FROM   (
         SELECT SUM(DECODE(SUBSTR(:1,LEVEL,1),'[',1,']',-1,0))OVER(ORDER BY LEVEL) d 
         FROM   DUAL 
         CONNECT BY LEVEL<=LENGTH(:1)
       );

CONNECT BY在输入字符串中为每个字符创建一行。

SUBSTR隔离与行号相对应的字符。

DECODE将每个'['转换为1,每个']'转换为-1,每个其他字符转换为0。

解析SUM将前一行(包括当前行)中的每个1,-1和0相加;

最大和是深度。


1

Java 8、95

这是的lambda表达式ToIntFunction<String>。输入String以OP的示例格式作为。

s->{int d=e=-1;for(String t:s.split("[")){d=++e>d?e:d;e-=t.split("]",-1).length()-1;}return d;}

相当直率。使用[分隔符分割字符串。对于它们中的每一个,增加计数器e,并将其与计数器进行比较d,将其中较大的一个保持在中d。然后这次使用]分隔符分割当前迭代的字符串,并从中减去额外分割的数量e

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.