Evaluasi pohon minimum

16

Alice dan Bob sedang memainkan permainan kecil. Pertama, mereka menggambar pohon dari simpul akar (ditunjukkan oleh titik tebal), tanpa simpul internal, dengan angka di daun. Setiap simpul mungkin memiliki jumlah anak yang banyak.

pohon

Kami mulai di root, dan yang pertama bermain adalah Alice (A). Dia harus memilih salah satu dari anak-anak simpul saat ini. Kemudian giliran Bob, dan ia juga memilih simpul anak. Ini berlanjut sampai simpul daun tercapai.

Saat simpul daun tercapai, permainan berakhir. Adalah tujuan Alice untuk mengakhiri pada simpul dengan nilai sebesar mungkin, dan tujuan Bob mengakhiri pada simpul dengan nilai sekecil mungkin.

Diberikan pohon dalam bentuk array bersarang, kembalikan nilai daun yang akan dicapai jika Alice dan Bob bermain dengan sempurna.


Contoh:

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]

Anda dapat mengasumsikan bahwa simpul akar tidak pernah merupakan simpul daun dan menunjuk setidaknya satu simpul daun. Anda dapat berasumsi bahwa daun adalah angka yang bukan negatif.


Kode terpendek dalam byte menang.

orlp
sumber

Jawaban:

2

Jelly , 7 byte

N߀¬¡ṂN

Cobalah online! atau verifikasi semua kasus uji .

Ini menggunakan algoritma dari jawaban @ xnor . Untuk tujuan perbandingan, pendekatan yang lebih langsung yang menghitung minima dan maxima secara bergantian berbobot 8 byte :

߀¬¡€Ṃ€Ṁ

Bagaimana itu bekerja

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.
Dennis
sumber
8

Python 2, 53 byte

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

Pertanyaan utamanya adalah bagaimana cara mengganti antara maxdan minsetiap lapisan. Menggunakan fakta bahwa max(l) == -min([-x for x in l]), kami malah meniadakan setiap lapisan kedua dan berulang dengan -min. Untuk meniadakan setiap lapisan kedua, kami meneruskan pengganda cyang berganti +1dan -1, dan ketika kami mencapai daun, kami menyesuaikan nilainya dengan pengganda. Kami menyadari bahwa Anda berada di daun melalui kondisi l<[], karena Python 2 memperlakukan angka sebagai kurang dari daftar.

Sulit untuk mempersingkat else/ifterner karena salah satu cabang bisa memberikan nilai Truthy (bukan nol) atau Falsey (nol).

Tidak
sumber
1

JavaScript (ES6), 53 byte

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

Menggunakan pendekatan yang mirip dengan jawaban @ xnor. Jika angkanya bukan nol, maka hanya 49 byte:

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

Pyth, 21 byte

M?sIG*GH_hSmgd_HGLgb1

Jawaban Pyth pertamaku! Terima kasih kepada Dennis untuk bantuannya :).

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)
Yang Mulia
sumber
Ada sintaks yang lebih pendek untuk peta itu: mgd_Hbisa gR_H. Selain itu, alih-alih mendefinisikan fungsi, Anda dapat mengambil input Qdan menggantinya Lgb1dengan gQ1.
lirtosiast
1

Mathematica, 13 byte

-Min[#0/@-#]&

atau setara

Max[-#0/@-#]&

Ini mengevaluasi ke fungsi tanpa nama yang mengambil pohon dan mengembalikan hasilnya.

Ini pada dasarnya juga sama dengan solusi xnor: pada setiap level kita menukar tanda daftar dan hasilnya dan menggunakan Minsemua jalan ke bawah. Ini ternyata sangat menarik di Mathematica, karena:

  • Mindapat mengambil nomor atau daftar individual atau bahkan beberapa daftar. Itu hanya memberi Anda nilai minimum di semua argumennya. Itu berarti ia berfungsi baik pada daftar maupun daun (di mana ia hanya mengembalikan daun).
  • /@yang merupakan kependekan Mapadalah fungsi tingkat tinggi yang sangat umum di Mathematica. Itu tidak hanya memetakan fungsi di atas daftar, itu bisa memetakannya di atas ekspresi apa pun. Angka adalah ungkapan seperti itu, tetapi angka tidak mengandung elemen apa pun untuk dipetakan. Itu berarti kita dapat memetakan fungsi apa pun dengan aman pada angka, yang sama sekali tidak memengaruhi angka.

Kedua hal tersebut bersama-sama berarti kita dapat menulis kode tanpa syarat, karena operasi Mindan Maptidak boleh pada angka, dan kemudian dua negasi membatalkan sehingga fungsi menjadi identitas ketika diberi nomor.

Akhirnya, berkat#0 dimungkinkan untuk menulis fungsi rekursif tanpa nama di Mathematica, yang menghemat beberapa byte lagi.

Martin Ender
sumber
0

Ruby, 46 byte

Trik @xnor digunakan dengan minuntuk berganti-ganti antara maks dan min.

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