minimax 트리 평가


16

Alice와 Bob은 작은 게임을하고 있습니다. 먼저, 그들은 잎에 숫자가있는 내부 노드가없는 루트 노드 (굵은 점으로 표시)에서 나무를 그립니다. 모든 노드에는 여러 개의 자식이있을 수 있습니다.

나무

우리는 처음부터 시작하여 Alice (A)입니다. 그녀는 현재 노드의 자식 중 하나를 선택해야합니다. 그런 다음 Bob의 차례이며, 마찬가지로 자식 노드를 선택합니다. 리프 노드에 도달 할 때까지 계속됩니다.

리프 노드에 도달하면 게임이 종료됩니다. 가능한 한 큰 값을 가진 노드에서 끝나는 것이 Alice의 목표이고 가능한 한 작은 값을 가진 노드에서 끝나는 Bob의 목표입니다.

중첩 된 배열 형태의 트리가 주어지면 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]

루트 노드는 절대 리프 노드가 아니며 적어도 하나의 리프 노드를 가리키는 것으로 가정 할 수 있습니다. 잎이 음수가 아닌 것으로 가정 할 수 있습니다.


바이트 단위의 짧은 코드가 이깁니다.


답변:


2

젤리 , 7 바이트

N߀¬¡ṂN

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인하십시오 .

이것은 @ xnor 's answer 의 알고리즘을 사용합니다 . 비교를 위해 최소값과 최대 값을 교대로 계산하는보다 간단한 방법은 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

파이썬 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는 번갈아 가는 승수 를 전달 +1하고 -1, 잎에 도달하면 승수에 의해 그 값을 조정합니다. l<[]Python 2는 숫자를 목록보다 작게 취급하기 때문에 condition을 통해 리프에있는 것으로 인식 합니다.

else/if분기가 Truthy (0이 아님) 또는 Falsey (0) 값을 줄 수 있기 때문에 3 항 을 단축하기가 어렵습니다 .


1

자바 스크립트 (ES6), 53 바이트

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

@xnor의 답변과 비슷한 접근 방식을 사용합니다. 숫자가 0이 아닌 경우 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및 교체 Lgb1와 함께 gQ1.
lirtosiast

1

Mathematica, 13 바이트

-Min[#0/@-#]&

또는 동등하게

Max[-#0/@-#]&

이것은 트리를 가져와 결과를 반환하는 명명되지 않은 함수로 평가됩니다.

이것은 또한 xnor의 솔루션과 본질적으로 동일합니다. 각 수준에서 우리는 목록의 부호와 결과를 바꾸고 완전히 사용 Min합니다. 이것은 Mathematica에서 엄청나게 골프로 나타났습니다.

  • Min개별 번호 또는 목록 또는 여러 목록을 사용할 수 있습니다. 모든 인수에서 최소값을 제공합니다. 즉, 목록뿐만 아니라 잎 (잎만 반환)에서 모두 작동합니다.
  • /@이것은 MapMathematica에서 매우 일반적인 고차 함수입니다. 단순히 함수를리스트에 매핑하는 것이 아니라 어떤 식 으로든 함수를 매핑 할 수 있습니다. 숫자는 그러한 표현이지만 매핑 할 요소를 포함하지 않습니다. 즉, 숫자에 함수를 안전하게 매핑 할 수 있으며 숫자에 전혀 영향을 미치지 않습니다.

두 가지 모두 함께 조건부없이 코드를 작성할 수 있음을 의미합니다. MinMap연산은 숫자에 대한 오류가 없기 때문에 두 개의 부정은 취소되므로 함수는 숫자가 주어지면 ID가됩니다.

마지막으로, 덕분에#0 그것은 몇 바이트를 저장 티카에 이름이 재귀 함수를 작성하는 것이 가능하다.


0

루비, 46 바이트

@xnor의 트릭을 사용 min하여 최대와 최소를 번갈아 사용 했습니다.

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.