Оцініть мінімакс дерево


16

Аліса і Боб грають у маленьку гру. Спочатку вони малюють дерево з кореневого вузла (позначеного товстою крапкою), без внутрішніх вузлів, з цифрами на листках. Будь-який вузол може мати будь-яку кількість дітей.

дерево

Ми починаємо в корені, і спочатку граємо - Аліса (А). Вона повинна вибрати одного з поточних дітей вузла. Тоді настає черга Боба, і він аналогічно вибирає дочірній вузол. Це триває, поки не буде досягнутий листовий вузол.

Коли досягається вузол листя, гра закінчена. Мета Аліси - закінчитися на вузлі з максимально великим значенням, а мета Боба - закінчити у вузлі з якомога меншим значенням.

Давши дерево у вкладеній формі масиву, поверніть значення аркуша, який буде досягнуто, якщо і Аліса, і Боб гратимуть ідеально.


Приклади:

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 . Для порівняння, більш простий підхід, який по черзі обчислює мінімуми і максимуми, важить 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)

Основне питання полягає в тому , щоб вибрати між maxі minкожен шар. Використовуючи той факт max(l) == -min([-x for x in l]), ми замість цього заперечуємо кожен другий шар і повторюємо -min. Для того, щоб звести на ні кожного другого шару, ми переходимо вниз множник , cякий чергується +1і -1, і , коли ми досягаємо лист, ми регулюємо його значення умножителя. Ми визнаємо, що перебуваємо в аркуші через умову l<[], оскільки Python 2 розглядає числа як менші за списки.

Важко скоротити 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! Дякую Деннісу за допомогу :).

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

Математика, 13 байт

-Min[#0/@-#]&

або рівнозначно

Max[-#0/@-#]&

Це оцінює неназвану функцію, яка бере дерево і повертає результат.

Це по суті те саме, що і рішення xnor: на кожному рівні ми поміняємо знак списку та результату і використовуємо Minвесь шлях вниз. Це виявилося неймовірно похмурим у Mathematica, оскільки:

  • Minможе приймати або окремі номери, або списки, або навіть декілька списків. Він просто дає мінімальне значення для всіх його аргументів. Це означає, що він працює як у списках, так і на листках (де він просто повертає лист).
  • /@що коротше Map- це дуже загальна функція вищого порядку в Mathematica. Він не просто відображає функцію над списками, але може відображати їх над будь-яким виразом. Числа - це такий вираз, але вони не містять елементів, які підлягають відображенню. Це означає, що ми можемо безпечно відображати будь-яку функцію над номерами, що взагалі не впливає на число.

Обидва ці речі разом означають, що ми можемо писати код без будь-яких умовних умов, оскільки операції Minі Mapоперації не мають пропусків чисел, а згодом два заперечення скасовуються, так що функція стає ідентичною при наданні числа.

Нарешті, завдяки#0 цьому можна записати неназвані рекурсивні функції в Mathematica, що економить ще кілька байтів.


0

Рубін, 46 байт

Використовується трюк @ xnor з minдля чергування максимуму та мінуса.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.