评估极小极大树


16

爱丽丝和鲍勃在玩小游戏。首先,他们从根节点(用粗点表示)绘制一棵树,没有内部节点,叶上有数字。任何节点可以具有任意数量的子代。

树

我们从根开始,首先是爱丽丝(A)。她必须选择当前节点的子节点之一。然后轮到鲍勃了,他同样选择了一个子节点。这一直持续到到达叶节点为止。

当到达叶子节点时,游戏结束。艾丽丝(Alice)的目标是在值尽可能大的节点处结束,鲍勃(Bob)的目标是在值尽可能小的节点处结束。

给定一棵嵌套数组形式的树,返回如果爱丽丝和鲍勃都玩的很好的叶子的值。


例子:

18: [[67, [[100, [[67, 47], [86], 21, 16], [[46, [14], 35, 85], [71, [18, 63, 69], 99, 22], 3]]], [[18, 32, 42, 80]], [[36, 70], [86, 53, 46, 59], [[41], 86, 35]]], 3]
60: [[[84, 35], [44, 60]], [[24, 98], [16, 21]]]
58: [[53, 77], [58, [82, 41]], 52]
59: [[93, [100, 53], 58, 79], [63, 94, 59], [9, [55, 48]], [40, 10, 32]]
56: [[20, 10, [[[89, 22, 77, 10], 55], [24, 28, 30, 63]]], [[49, 31]], 17, 56]
0: [0]

您可以假设根节点永远不会是叶节点,并且至少指向一个叶节点。您可以假设叶子是非负数。


以字节为单位的最短代码获胜。


Answers:


2

果冻,7 个字节

N߀¬¡ṂN

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

这使用@xnor的答案中的算法。为了进行比较,一种更直接的方法可交替计算最小值和最大值,其权重为8个字节

߀¬¡€Ṃ€Ṁ

怎么运行的

N߀¬¡ṂN  Main link. Argument: x (array or integer)

N        Negate. For an array, this negates all integers in it.
   ¬     Logical NOT. For an array, this applies to all integers in it.
    ¡    Apply the second link to the left once if ¬ returned an array or 1, or not
         at all if it returned 0.
 ߀      Recursively call the main link on all elements at depth 1 of -x.
         If -x == 0, € will cast 0 to range before mapping ß over it. 
         Since the range of 0 is [], mapping ß over it simply yields [].
     Ṃ   Minimum.
         For an integer, Ṃ simply returns the integer. For [], Ṃ returns 0.
      N  Negate the minimum.

8

Python 2,53个字节

f=lambda l,c=1:c*l if l<[]else-min(f(x,-c)for x in l)

主要的问题是如何之间交替maxmin每一层。利用的事实max(l) == -min([-x for x in l]),我们取而代之的是每隔第二层取反,并用-min。要否定第二层,我们向下传递一个与和c交替的乘数,当我们到达叶子时,我们通过乘数来调整其值。我们认识到通过条件处于一片叶子,因为Python 2将数字视为少于列表。+1-1l<[]

很难缩短else/if三元数,因为任一分支都可以给出Truthy(非零)或Falsey(零)值。


1

JavaScript(ES6),53个字节

f=(a,s=1)=>a.map?s*Math.max(...a.map(b=>s*f(b,-s))):a

对@xnor的答案使用类似的方法。如果数字不为零,则仅49个字节:

f=(a,s=1)=>+a||s*Math.max(...a.map(b=>s*f(b,-s)))

1

Pyth,21个字节

M?sIG*GH_hSmgd_HGLgb1

我的第一个Pyth答案!感谢Dennis的帮助:)。

M                      # define a binary function (G, H)
 ?sIG                  # if G (first argument) is the same with s applied
                       # (check if it's an integer, so, a leaf node)
     *GH               # in such a case, calculate G*H
        _              # negation
         hS            # take the first element of the sorted list (that's the min)
           mgd_HG      # map over G, applying ourself (g) recursively,
                       # with the current lambda's value (d)
                       # and the negation of H
                 Lgb1  # Define a unary function to call our previous
                       # one with the correct base argument (1)

该地图的语法较短:mgd_H可以为gR_H。此外,而不是定义一个函数,你可以采取与输入Q和替换Lgb1gQ1
lirtosiast '16

1

Mathematica,13个字节

-Min[#0/@-#]&

或同等

Max[-#0/@-#]&

这将得出一个未命名的函数,该函数采用该树并返回结果。

这在本质上也与xnor的解决方案相同:在每个级别上,我们交换列表的符号和结果,并Min一直向下使用。在Mathematica中,这证明是令人难以置信的高尔夫运动,因为:

  • Min可以采用单个数字或列表,甚至可以采用多个列表。它只是为您提供所有参数的最小值。这意味着它既可以在列表上也可以在叶子上工作(它只返回叶子)。
  • /@这是MapMathematica中非常通用的高阶函数的缩写。它不仅将函数映射到列表上,还可以将它们映射到任何表达式上。数字就是这样一个表达式,但它们不包含任何要映射的元素。这意味着我们可以安全地将任何函数映射到数字上,而这完全不会影响数字。

这两件事在一起意味着我们可以在没有任何条件的情况下编写代码,因为MinMap操作在数字上是无操作的,随后这两个否定抵消了,因此当给定数字时该函数成为标识。

最后,由于#0可以在Mathematica中编写未命名的递归函数,因此可以节省更多的字节。


0

Ruby,46个字节

使用@xnor的技巧min在最大和最小之间交替。

f=->n,a=1{n==[*n]?-n.map{|c|f[c,-a]}.min: a*n}

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.