Риск битва: идти вниз


16

Учитывая два списка бросков костей для битвы в Риск, ваша программа или функция должны выводить, сколько войск теряет каждый игрок.

Фон

Вам не нужно читать это, потому что это просто фон. Перейдите к подзаголовку «Задача», чтобы продолжить без изменений.

В игре Risk один игрок может атаковать другого игрока (на самом деле это необходимо для победы). Исход битвы определяется броском костей. Каждое сражение происходит как последовательность под-сражений, в которых каждый игрок может потерять 2свои части армии.

В под-битве каждый защитник и атакующий бросают по несколько кубиков, число которых может меняться в зависимости от обстоятельств, не связанных с этим испытанием. Самый ценный кубик атакующего сравнивается с самым ценным кубиком защитника. Если кубик атакующего выше, чем кубик защитника, он теряет одну фигуру. В противном случае атакующий теряет одну фигуру.

Затем, если у обоих игроков есть по крайней мере два кубика, сравниваются вторые по величине кубики двух игроков. Опять же, если кубик атакующего выше, чем кубик защитника, он теряет одну фигуру. В противном случае атакующий теряет одну фигуру.

(Защитник выигрывает связи. Если и защитник, и атакующий бросают 4, то атакующий теряет фигуру.)

Сравнение игральных костей

В этом под-сражении из статьи в Википедии кости атакующего окрашены в красный цвет, а кости защитника - в белый. Самый высокий из кубиков атакующего есть, 4а самый высокий - у защитника 3. Так как нападающий был выше, защитник теряет фигуру. Второй по величине 3для атакующего и 2для защитника. Поскольку атакующий снова оказался выше, защитник теряет еще одну фигуру. Таким образом, в этом под-сражении атакующий не теряет фигуры, а защитник теряет 2фигуры.

Обратите внимание, что третьи по величине произведения не сравниваются. Это связано с тем, что у защитника не более двух кубиков в одной под-битве, поэтому нет ни одной третьей по величине фигуры для сравнения.

задача

Принимая во внимание несортированные броски костей (целые числа в диапазоне от 1 до 6 включительно) как атакующего, так и защитника в под-битве риска в любой удобной форме, выведите количество армейских фигур, которые проиграл каждый игрок. Вывод может быть в любой удобной форме, если он имеет разные выходы, чтобы указать пять возможностей. Вы должны указать, что эти разные выводы в вашем вопросе.

Выход определяется следующим образом: Начните с def=0и atk=0. Если наибольшее значение в списке бросков костей атакующего больше, чем наибольшее значение в списке бросков костей защитника, то увеличивается def. В противном случае, приращениеatk .

Если оба списка бросков костей имеют длину по крайней мере 2, то: если второе по величине значение списка бросков костей атакующего больше второго по значению списка, то увеличивается defи иначе увеличивается atk.

Наконец, программа или функция должны вывести уникальный идентификатор для каждой из следующих 5 возможностей вывода:

  ╔═══╦═══╗
  ║atk║def║
  ╠═══╬═══╣
  ║ 1 ║ 0 ║
  ║ 0 ║ 1 ║
  ║ 2 ║ 0 ║
  ║ 1 ║ 1 ║
  ║ 0 ║ 2 ║
  ╚═══╩═══╝

пример

Защитник: [3, 2] Атакующий: [2, 4, 1] Макс защитника 3и Макс атакующего 4. 4>3, Поэтому def=1 вторых Защитнику 2и второй атакующего является 2. Not(2>2)так atk=1. Выход может быть [1,1].

Тестовые случаи

Defender
Attacker
Output (as [def,atk])
-----
[1]
[1]
[0,1]
-----
[6,6]
[1,1,1]
[0,2]
-----
[1,2]
[5,2,3]
[2,0]
-----
[5]
[3,4]
[0,1]
-----
[4]
[4,5]
[1,0]
-----
[1,3]
[1,2,3]
[1,1]
-----
[4]
[4,5,6]
[1,0]
-----
[4,5]
[6,2]
[1,1]
-----
[5]
[6,1,3]
[1,0]
-----
[5,5]
[4,4,1]
[0,2]
-----
[2,5]
[2,2]
[0,2]
-----
[6,6]
[4,4,3]
[0,2]
-----
[2,1]
[4,3]
[2,0]
-----
[4]
[1,5]
[1,0]
-----
[1]
[5,2]
[1,0]
-----
[6,2]
[4]
[0,1]
-----
[4,2]
[2,5,5]
[2,0]
-----
[2]
[6,6,2]
[1,0]
-----
[6]
[2,6]
[0,1]
-----
[3,1]
[1]
[0,1]
-----
[6,2]
[3,5,2]
[1,1]
-----
[4,2]
[1,1]
[0,2]
-----
[4,3]
[5,4,1]
[2,0]
-----
[5,6]
[1,2]
[0,2]
-----
[3,2]
[4,4]
[2,0]
-----
[2]
[6,3,4]
[1,0]
-----
[1,4]
[6,2,4]
[2,0]
-----
[4,2]
[2,5,4]
[2,0]
-----
[5]
[6,2,1]
[1,0]
-----
[3]
[2,5,4]
[1,0]
-----
[5,4]
[2]
[0,1]
-----
[6,3]
[2,6,5]
[1,1]
-----
[3,1]
[4]
[1,0]
-----
[4]
[6,6,5]
[1,0]
-----
[6,3]
[4,2]
[0,2]
-----
[1,6]
[5,4]
[1,1]
-----
[3,6]
[4,4]
[1,1]
-----
[5,4]
[5,1,1]
[0,2]
-----
[6,3]
[5,4]
[1,1]
-----
[2,6]
[1,2]
[0,2]
-----
[4,2]
[3,5,5]
[2,0]
-----
[1]
[1,2,1]
[1,0]
-----
[4,5]
[1,6]
[1,1]
-----
[1]
[3,5,1]
[1,0]
-----
[6,2]
[6,2]
[0,2]

Пример реализации

Python 2 или 3

def risk(atk_rolls,def_rolls):
    # set the rolls in descending order, e.g. [5,3,2]
    atk_rolls = sorted(atk_rolls,reverse = True)
    def_rolls = sorted(def_rolls,reverse = True)
    # minimum length.
    minlen = min(len(atk_rolls),len(def_rolls))
    atk_lost = 0
    def_lost = 0
    # compare the highest-valued rolls
    if atk_rolls[0]>def_rolls[0]:
        def_lost += 1
    else:
        atk_lost += 1
    if minlen == 2:
        # compare the second-highest-valued rolls
        if atk_rolls[1] > def_rolls[1]:
            def_lost += 1
        else:
            atk_lost += 1
    return [def_lost, atk_lost]    

Характеристики

  • Входные данные могут быть приняты в любой форме, которая четко кодирует только броски защитника и броски атакующего.
  • Вывод может быть в любой форме, которая обеспечивает уникальный вывод для каждой из пяти возможностей, перечисленных выше.
  • Броски защитника - это список 1или 2целые числа в наборе [1,2,3,4,5,6]. Роллы атакующие представляют собой список 1для 3целых чисел в наборе [1,2,3,4,5,6].
  • Поскольку это , выигрывает самый короткий код на каждом языке ! Вы не дайте ответы на языках гольфа отговорить вас от проводки ответов на других языках.

Увидел это в песочнице, хороший вопрос
Ноа Кристино


Атакующий проигрывает, если его максимальный бросок равен максимальному броску защитника, верно?
Мистер Xcoder

1
Да @ Mr.Xcoder, защитник выигрывает связи.
fireflame241

Поэтому я удалил комментарий :)
Mr. Xcoder

Ответы:


8

NAND Gates, 237

Создано с Logisim

Входы являются 3-битными беззнаковыми двоичными данными, вводится слева. Выходы (2 бита) находятся справа.

Он слишком большой, чтобы поместиться на экране, и Logisim не может увеличить изображение, поэтому изображение черно-белое. Извини :(

Работает для всех тестовых случаев.

Вероятно, есть лучший способ сделать это с использованием некоторой схемы памяти, позволяющей повторно использовать большие разделы.


4

Желе ,  12  11 байт

NṢ€>/Ṡḟ-o-S

Монадическая ссылка, содержащая список Defender, Attackerбросков (каждый в виде списков), возвращающий целое число между -2и 2включительно (потери защитника - потери атакующего):

result : [def, atk]
    -2 : [  0,   2]
    -1 : [  0,   1]
     0 : [  1,   1]
     1 : [  1,   0]
     2 : [  2,   0]

Попробуйте онлайн! или посмотрите набор тестов (который отображает результаты в формат OP).

Как?

NṢ€>/Ṡḟ-o-S - Link: list [list Def, list Atk]
N           - negate all the rolls
 Ṣ€         - sort €ach of the lists of -1*rolls (max rolls are to the left now)
    /       - reduce by:
   >        -   is greater than?  (when len(Atk) > len(Def) leaves trailing negatives)
     Ṡ      - sign (maps all negatives to -1; zeros and ones of comparison unchanged)
       -    - literal -1
      ḟ     - filter discard (remove the -1s)
         -  - literal -1
        o   - logical or, vectorises (replaces the zeros with minus ones)
          S - sum

2

Сетчатка , 82 байта

%O^`.
((.)+).*(¶(?<-2>.)+)(?(2)(?!)).*
$1$3
O$`.
$.%`
\d
$*1D
(1+)D1*\1

1+D
A
O`.

Попробуйте онлайн! Первая строка ввода - игральные кости атакующего, вторая - игральные кости защитника. Возвращает (на отдельных линиях) AA, AD, DD, Aили Dв зависимости от обстоятельств.



2

MATL , 23 байта

oH2$S1&Y)Y&t1M>t~b,Y&sD

Попробуйте онлайн!

Не знаю, почему защитникам разрешено больше кубиков, чем атакующим, но, возможно, я не очень хорошо разбираюсь в риске. Основная программа проста >t~,sD, все остальные байты предназначены для разной длины ввода, с добавлением небольшого количества сортировки. За входом следует атакующий, затем защитник, выходные данные - потери атакующего, за которыми следуют потери защитника.

o    % Convert input to numeric array, padding with zeroes 
H2$S % Sort row-wise (specified to prevent 1v1 sorting)
1&Y) % Split attacker/defender
Y&t  % Logical and to filter out excess dice. Duplicate for 'do twice' later.
1M>  % Get throws again, decide who won
t~   % And the inverse to decide who lost
b,   % Bubble filter to the top. Do twice:
  Y& % Apply filter
  sD % Sum of losses. Display.

2

JavaScript (SpiderMonkey) , 97 83 78 байт

d=>a=>{for(u=v=0;d.sort()>[]&a.sort()>[];)a.pop()>d.pop()?u++:v++
return[u,v]}

Попробуйте онлайн!

-4 байта и исправлено благодаря @ovs и @Craig Ayre
-1 байт благодаря @Shaggy


Не работает для одного атакующего против двух защитников.
Нил

О, хм, я не думал об этом. Я исправлю это
WaffleCohn

2
Это может сработать.
овс

Решение @ ovs проходит все тестовые случаи, вы также можете сэкономить несколько байтов (слишком большая ссылка tio):d=>a=>{for(u=v=0;d.sort()>[]&a.sort()>[];)a.pop()>d.pop()?u++:v++;return[u,v]}
Крейг Эйр,

Первый разрыв строки не нужен и стоит вам байт.
Лохматый

2

Шелуха , 10 байт

M#eI¬¤z>Ö>

Попробуйте онлайн!

Ввод в виде двух отдельных списков рулонов, вывод, как в оп.

объяснение

¤z>Ö> сортирует каждый список по убыванию, а затем архивирует их, сравнивая соответствующие элементы (и обрезая длинный список).

M#eI¬создает 2-элементный список ( e) с #count ( ) истинных значений (через идентичность I) и ложных значений (через логическое отрицание ¬)


1

Perl 5 , 66 + 1 (-a) = 67 байт

@A=sort split/ /,<>;$b+=@A?pop@A>$_?-1:1:0for reverse sort@F;say$b

Попробуйте онлайн!

Входные данные:

Две строчки Первая строка - защитник (игрок 1), вторая - атакующий (игрок 2). Отдельные рулоны разделены пробелами.

Выход:

Указывает на эффективное изменение силы защитника по сравнению с атакующим.

Output Attacker Defender
   2      0        2        Defender wins both
   1      0        1        Defender wins the only roll
   0      1        1        Attacker wins first, defender wins second
  -1      1        0        Attacker wins the only roll
  -2      2        0        Attacker wins both rolls

«Программа или функция должны вывести уникальный идентификатор для каждой из 5 возможностей вывода». У вас есть два выхода для [1,1]. Пожалуйста, отредактируйте свой ответ, чтобы исправить это (просто отсортируйте или
суммируйте

Что не так с шестью? Это более конкретно. :) Я поменял его по стоимости 6 байт.
Xcali


0

R , 46 байт

function(x,y)s(s(y,T)[1:2]>s(x,T)[1:2])
s=sort

Попробуйте онлайн!

Все это делает три вида и одно сравнение ... плюс извлечение первых двух элементов в середине.

Ввод двух векторов бросков костей.

Выход кодируется следующим образом:

╔═══╦═══╗
║atk║def║
╠═══╬═══╣
║ 10TRUE01FALSE20TRUE  TRUE11FALSE TRUE02FALSE FALSE
╚═══╩═══╝

Работает, потому что извлечение в R не перезагружает свой аргумент, но дополняет результат NAдо нужной длины.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.