Bataille des risques: descendre

16

Étant donné deux listes de lancers de dés pour une bataille à risque, votre programme ou fonction doit générer le nombre de troupes perdues par chaque joueur.

Contexte

Vous n'êtes pas obligé de lire ceci, car ce n'est qu'un arrière-plan. Passez à la sous-rubrique "Tâche" pour continuer sans relâche.

Dans le jeu de Risque , un joueur peut attaquer un autre joueur (en fait, c'est nécessaire pour gagner). Le résultat d'une bataille est déterminé par le lancer de dés. Chaque bataille se déroule comme une succession de sous-batailles dans lesquelles chaque joueur peut perdre jusqu'à 2ses pièces d'armée.

Dans une sous-bataille, le défenseur et l'attaquant lancent chacun plusieurs dés dont le nombre peut varier en fonction de circonstances non pertinentes pour ce défi. Le dé le plus précieux de l'attaquant est comparé au dé le plus précieux du défenseur. Si le dé de l'attaquant est supérieur au dé du défenseur, le défenseur perd une pièce. Sinon, l'attaquant perd une pièce.

Ensuite, si les deux joueurs ont au moins deux dés, les deuxièmes dés les plus élevés des deux joueurs sont comparés. Encore une fois, si le dé de l'attaquant est supérieur au dé du défenseur, le défenseur perd une pièce. Sinon, l'attaquant perd une pièce.

(Le défenseur gagne des égalités. Si le défenseur et l'attaquant réussissent tous les deux 4, l'attaquant perd un morceau.)

Comparaison des dés

Dans cette sous-bataille de l'article de Wikipédia, les dés de l'attaquant sont rouges et les dés du défenseur sont blancs. Le plus haut des dés de l'attaquant est 4le plus élevé des dés du défenseur 3. Comme l'attaquant était plus haut, le défenseur perd un morceau. Les deuxièmes plus élevés sont 3pour l'attaquant et 2pour le défenseur. Comme l'attaquant était à nouveau plus haut, le défenseur perd un autre morceau. Ainsi, dans cette sous-bataille, l'attaquant ne perd aucune pièce et le défenseur perd des 2pièces.

Notez que les troisièmes pièces les plus élevées ne sont pas comparées. En effet, le défenseur n'a pas plus de deux dés sur une seule sous-bataille, il n'y a donc pas de troisième pièce la plus élevée à comparer.

Tâche

Compte tenu des lancers de dés non triés (nombres entiers compris entre 1 et 6 inclus) de l'attaquant et du défenseur d'une sous-bataille de Risk sous n'importe quelle forme pratique, affichez le nombre de pièces d'armée que chaque joueur perd. La sortie peut être sous n'importe quelle forme pratique, tant qu'elle a des sorties différentes pour indiquer les cinq possibilités. Vous devez indiquer quelles sont ces différentes sorties dans votre question.

La sortie est déterminée comme suit: Commencez par def=0et atk=0. Si la plus grande valeur de la liste des dés de l'attaquant est supérieure à la plus grande valeur de la liste des dés du défenseur, alors incrémentez def. Sinon, incrémentez atk.

Si les deux listes de lancers de dés ont au moins une longueur 2, alors: si la deuxième plus grande valeur de la liste des lancers de dés de l'attaquant est supérieure à la deuxième plus grande valeur de la liste, alors incrémentez defet augmentez autrement atk.

Enfin, le programme ou la fonction doit sortir un identifiant unique pour chacune des 5 possibilités de sortie suivantes:

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

Exemple

Défenseur: [3, 2] Attaquant: [2, 4, 1] Max du défenseur est 3et max de l'attaquant 4. 4>3, donc le def=1 deuxième du défenseur est 2et le deuxième de l'attaquant 2. Not(2>2), donc atk=1. La sortie pourrait alors être [1,1].

Cas de test

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]

Exemple d'implémentation

Python 2 ou 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]    

Caractéristiques

  • L'entrée peut être prise sous n'importe quelle forme qui code clairement uniquement les rôles du défenseur et les rôles de l'attaquant.
  • La sortie peut être sous n'importe quelle forme qui fournit une sortie unique pour chacune des cinq possibilités énumérées ci-dessus.
  • Les jets du défenseur sont une liste 1ou des 2entiers dans l'ensemble [1,2,3,4,5,6]. Les rouleaux de l'attaquant sont une liste 1d' 3entiers dans l'ensemble [1,2,3,4,5,6].
  • Puisqu'il s'agit de , le code le plus court dans chaque langue gagne! Ne laissez pas les réponses dans les langues de golf vous décourager de publier des réponses dans d'autres langues.
fireflame241
la source
J'ai vu ça sur le bac à sable, belle question
Noah Cristino
L'attaquant perd si son jet maximum est égal au jet le plus élevé du défenseur, non?
M. Xcoder
1
Oui @ Mr.Xcoder, le défenseur gagne des égalités.
fireflame241
Par conséquent, j'ai supprimé le commentaire :)
M. Xcoder

Réponses:

8

Portes NAND, 237

Créé avec Logisim

Les entrées sont des binaires non signés de 3 bits, saisis à gauche. Les sorties (2 bits) sont à droite.

Il est trop grand pour tenir sur l'écran et Logisim ne peut pas zoomer, donc l'image est en noir et blanc. Pardon :(

Fonctionne pour tous les cas de test.

Il existe probablement un meilleur moyen de le faire en utilisant un circuit de mémoire, permettant de réutiliser de grandes sections.

Khuldraeseth na'Barya
la source
4

Gelée ,  12  11 octets

NṢ€>/Ṡḟ-o-S

Un lien monadique prenant une liste de Defender, Attackerrôles (chacun sous forme de listes), renvoyant un entier entre -2et 2inclus (pertes défenseur - pertes attaquant):

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

Essayez-le en ligne! ou consultez une suite de tests (qui mappe les résultats au format OP).

Comment?

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
Jonathan Allan
la source
2

Rétine , 82 octets

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

1+D
A
O`.

Essayez-le en ligne! La première ligne d'entrée est les dés de l'attaquant, la seconde est les dés du défenseur. Retours (sur des lignes séparées) AA, AD, DD, Aou , Dselon le cas.

Neil
la source
2

Python 2 , 83 75 octets

x=0
k=map(sorted,input())
while all(k):x+=cmp(*map(list.pop,k))or 1
print-x

Essayez-le en ligne!

La sortie est les pertes du défenseur - les pertes de l'attaquant

ovs
la source
2

MATL , 23 octets

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

Essayez-le en ligne!

Je ne sais pas pourquoi les défenseurs ont plus de dés que les attaquants, mais peut-être que je ne connais pas très bien le risque. Le programme de base est juste >t~,sD, tous les autres octets sont là pour permettre différentes longueurs d'entrée, avec un peu de tri. L'entrée est l'attaquant suivi du défenseur, la sortie est les pertes de l'attaquant suivies des pertes du défenseur.

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.
Sanchises
la source
2

JavaScript (SpiderMonkey) , 97 83 78 octets

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

Essayez-le en ligne!

-4 octets et fixe grâce à @ovs et @Craig Ayre
-1 octet grâce à @Shaggy

WaffleCohn
la source
Ne fonctionne pas pour un attaquant contre deux défenseurs.
Neil
Oh hmm je n'y ai pas pensé. Je vais le réparer
WaffleCohn
2
Cela pourrait fonctionner.
2017 à 10h14
La solution de @ ovs passe tous les cas de test, vous pouvez également économiser quelques octets (le lien tio était trop volumineux):d=>a=>{for(u=v=0;d.sort()>[]&a.sort()>[];)a.pop()>d.pop()?u++:v++;return[u,v]}
Craig Ayre
Le premier saut de ligne est inutile et vous coûte un octet.
Shaggy
2

Husk , 10 octets

M#eI¬¤z>Ö>

Essayez-le en ligne!

Entrez comme deux listes distinctes de rouleaux, sortez comme dans l'op.

Explication

¤z>Ö> trie chaque liste par ordre décroissant puis les zippe en comparant les éléments correspondants (et en tronquant la liste la plus longue).

M#eI¬ crée une liste à 2 éléments (e ) avec les décomptes ( #) des valeurs véridiques (grâce à l'identité I) et des valeurs fausses (via la négation logique ¬)

Leo
la source
1

Perl 5 , 66 + 1 (-a) = 67 octets

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

Essayez-le en ligne!

Contribution:

Deux lignes. La première ligne est le défenseur (joueur 1), la deuxième est l'attaquant (joueur 2). Rouleaux individuels séparés par des espaces.

Production:

Indique un changement efficace de la force du défenseur par rapport à l'attaquant.

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
Xcali
la source
"Le programme ou la fonction doit sortir un identifiant unique pour chacune des 5 possibilités de sortie." Le vôtre a deux sorties pour [1,1]. Veuillez modifier votre réponse pour résoudre ce problème (il suffit de trier ou de additionner)
fireflame241
Quel est le problème avec six? C'est plus précis. :) Je l'ai changé au prix de 6 octets.
Xcali
0

Gelée , 30 octets

0,0‘⁸Ṁ€</¤¦‘⁸ḟ"Ṁ€⁺</¤¦⁸L€Ṃ>1¤¡

Essayez-le en ligne!

Veeeeeeeery non golfé! > _ <

Affiche les valeurs exactement comme dans les cas de test.

Erik le Outgolfer
la source
Wow, cela me semble bien trop long: P
M. Xcoder
0

R , 46 octets

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

Essayez-le en ligne!

Tout cela ne fait que trois sortes et une comparaison ... plus l'extraction des deux premiers éléments au milieu.

L'entrée est deux vecteurs de lancers de dés.

Sortie codée comme suit:

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

Fonctionne car l'extraction dans R ne recycle pas son argument, mais remplit le résultat avec NApour obtenir la longueur demandée.

JayCe
la source