Magic: Gathering - гра з торговими картами, де, крім іншого, гравці грають у карти, що представляють істот, які потім можуть атакувати іншого гравця або захищатися від атак іншого гравця, блокуючи їх.
У цьому виклику коду-гольфу ваша програма буде замість гравця Magic, який вирішить, як блокувати в бою.
Кожна істота має два релевантні ознаки: Сила та міцність. Сила істоти - це сума шкоди, яку вона може завдати в бою, а її міцність - це сума шкоди, необхідної для її знищення. Потужність завжди принаймні 0, а в'язкість - не менше 1.
Під час бою в Magic, гравець, у свою чергу якого оголошує, що деякі їхні істоти атакують супротивника. Тоді інший гравець, відомий як гравець, що захищається, може призначити своїх істот блокаторами. Істота може блокувати лише одне створіння за битву, але кілька істот можуть блокувати одне і те ж створіння.
Після того, як блокатори оголошені, гравець, що атакує, вирішує для кожної атакованої істоти, яка була заблокована, як розподілити шкоду (рівну її потужності), що ця істота наносить істотам, які її блокують.
Потім наноситься шкода. Кожна істота завдає шкоди, рівній її потужності. Атакуючі істоти, які були заблоковані, завдають шкоди, як було зазначено вище. Розблоковані атакуючі істоти завдають шкоди гравцеві, що захищається. Блокування істот завдає шкоди істоті, яку вони заблокували. Істоти, що належать гравцеві, що захищається, що не блокували, не завдають шкоди. (Істот не потрібно блокувати.)
Нарешті, будь-яка істота завдала шкоди, рівній або більшої, ніж її в'язкість, знищується та видаляється з поля бою. Будь-яка кількість шкоди, меншої за міцність створіння, не впливає.
Ось приклад цього процесу:
Істота з потужністю P і міцністю T представлена як P/T
Attacking:
2/2, 3/3
Defending player's creatures:
1/4, 1/1, 0/1
Defending player declares blockers:
1/4 and 1/1 block 2/2, 0/1 does not block.
Attacking player distributes damage:
2/2 deals 1 damage to 1/4 and 1 damage to 1/1
Damage is dealt:
2/2 takes 2 damage, destroyed.
3/3 takes 0 damage.
1/1 takes 1 damage, destroyed.
1/4 takes 1 damage.
0/1 takes 0 damage.
Defending player is dealt 3 damage.
У гравця, який захищається, в бою є 3 цілі: знищуйте супротивника, зберігайте власні істоти і завдайте йому якомога менше шкоди. Крім того, істоти з більшою силою та міцністю є більш цінними.
Щоб об'єднати їх в єдиний захід, ми скажемо, що рахунок гравця, який захищається, від бою дорівнює сумі сил і міцності їхніх вижилих істот, мінус суми сил і міцності вижилих істот опонента, мінус один половина суми збитків, завданих гравцеві, що захищається. Гравець, що захищається, хоче максимально збільшити цей рахунок, а атакуючий гравець хоче його мінімізувати.
У бою, показаному вище, рахунок був:
Defending player's surviving creatures:
1/4, 0/1
1 + 4 + 0 + 1 = 6
Attacking player's surviving creature:
3/3
3 + 3 = 6
Damage dealt to defending player:
3
6 - 6 - 3/2 = -1.5
Якби гравець, що захищався, взагалі не заблокував описаний вище бій, рахунок був би
8 - 10 - (5/2) = -4.5
Оптимальним вибором гравця, що захищається, було б блокування 2/2
з і 1/1
та 1/4
, а також блокування 3/3
з 0/1
. Якби вони зробили це, тільки 1/4
і 3/3
вижили б, і жодної шкоди не було б нанесено гравцеві, що захищається, зробивши рахунок
5 - 6 - (0/2) = -1
Ваше завдання полягає в тому, щоб написати програму, яка виведе оптимальний вибір блокування для гравця, що захищається. "Оптимальний" означає вибір, який максимально збільшує рахунок, враховуючи, що опонент розподіляє збиток так, як мінімізує рахунок, враховуючи те, як ви заблокували.
Це максимін: максимальний бал за розподіл шкоди, який мінімізує бал за кожну блокуючу комбінацію.
Введення: Вхід буде складатися з двох списків 2-кортежів, де кожен 2-кортеж має форму (Потужність, Міцність). Перший список містить повноваження та суворість кожної атакуючої істоти (істоти противника). Другий список буде містити сили та міцність кожного вашого створіння.
Кортежі та списки можуть бути представлені у будь-якому зручному форматі, наприклад:
[[2, 2], [3, 3]]
[[1, 4], [1, 1], [0, 1]]
Вихід: Вихід буде складатися з серії 2-кортежів у формі (блокування істоти, заблокована істота) - тобто одне із ваших істот, за яким слідує одне із їхніх створінь. Істот буде посилатися на їх індекс у списках вхідних даних. Індекси можуть бути 0 або 1 індексованими. Знову будь-який зручний формат. Будь-яке замовлення добре. Наприклад, оптимальний сценарій блокування зверху, враховуючи вищевказаний вклад, може бути представлений у вигляді:
[0, 0] # 1/4 blocks 2/2
[1, 0] # 1/1 blocks 2/2
[2, 1] # 0/1 blocks 3/3
Приклади:
Input:
[[2, 2], [3, 3]]
[[1, 4], [1, 1], [0, 1]]
Output:
[0, 0]
[1, 0]
[2, 1]
Input:
[[3, 3], [3, 3]]
[[2, 3], [2, 2], [2, 2]]
Output:
[1, 0]
[2, 0]
or
[1, 1]
[2, 1]
Input:
[[3, 1], [7, 2]]
[[0, 4], [1, 1]]
Output:
[1, 0]
or
[0, 0]
[1, 0]
Input:
[[2, 2]]
[[1, 1]]
Output:
(No output tuples).
Вхід та вихід можуть здійснюватися через STDIN, STDOUT, CLA, функцію введення / повернення тощо. Застосовуються стандартні лазівки . Це код-гольф: найкоротший код у байтах виграє.
Щоб уточнити специфікацію та надати початкові ідеї, ця пастабін надає довідкове рішення в Python. Ця best_block
функція є зразковим рішенням цього завдання, а запуск програми забезпечить більше детального введення та виводу.