Terra Mystica: puissance cycliste


28

Le jeu de société Terra Mystica possède des mécanismes très intéressants pour l'une des principales ressources, le pouvoir. Au lieu de gagner et de dépenser des unités de pouvoir d'une banque, chaque joueur commence le jeu avec exactement 12 unités de pouvoir réparties sur trois "bols", qui sont étiquetés I, II et III. Gagner et dépenser du pouvoir déplace alors simplement le pouvoir entre ces bols:

  • Pour dépenser une unité de puissance, déplacez-la du bol III au bol I (à condition que vous ayez une unité dans le bol III).
  • Lorsque vous gagnez une unité de puissance, s'il y a une unité dans le bol I, déplacez-la dans le bol II. S'il n'y a pas d'unités dans le bol I, mais qu'il y en a une dans le bol II, déplacez-la dans le bol III. Si toutes les unités sont déjà dans le bol III, rien ne se passe.
  • Lorsque vous gagnez ou dépensez plusieurs unités à la fois, elles sont traitées une unité à la fois.

Voici un exemple. Disons qu'un joueur commence avec la distribution de puissance suivante (donnée dans l'ordre I | II | III):

5 | 7 | 0

Leur puissance change comme suit s'ils gagnent et dépensent de la puissance plusieurs fois:

               5 |  7 |  0
Gain  3  ==>   2 | 10 |  0
Gain  6  ==>   0 |  8 |  4   (move 2 power from I to II, 
                              then the remaining 4 from II to III)
Gain  7  ==>   0 |  1 | 11
Spend 4  ==>   4 |  1 |  7
Gain  1  ==>   3 |  2 |  7
Spend 7  ==>  10 |  2 |  0
Gain 12  ==>   0 | 10 |  2   (move 10 power from I to II,
                              then the remaining 2 from II to III)
Gain 12  ==>   0 |  0 | 12   (the two excess units go to waste)

Votre tâche consiste à calculer le résultat d'un tel événement de gain ou de dépenses.

Le défi

Vous disposez de quatre entiers en entrée. Les trois premiers, I, II, III, représentent la quantité de puissance dans chacune des trois bols. Ils seront non négatifs, et ils totaliseront 12. Le quatrième nombre,, Pest la quantité de puissance gagnée ou dépensée, et sera dans la plage incluse [-III, 24](vous pouvez donc supposer que le joueur n'essaiera jamais de dépenser plus de puissance qu'ils ne le peuvent actuellement, mais ils pourraient gagner plus de puissance que nécessaire pour déplacer toute la puissance dans le bol III).

Vous pouvez prendre ces nombres dans n'importe quel ordre cohérent, en tant qu'arguments séparés, en tant que liste d'entiers ou en tant que chaîne contenant ces entiers. Vous pouvez également prendre Pcomme un argument, comme I, II, IIIcomme argument de liste séparée.

Vous devez sortie trois entiers I', II', III'qui représentent la quantité d'énergie dans chaque bol après P unités ont été acquises ou passé, suivant les règles exposées ci - dessus.

Vous pouvez écrire un programme ou une fonction et utiliser l'une de nos méthodes standard de réception d'entrée et de sortie.

Vous pouvez utiliser n'importe quel langage de programmation , mais notez que ces failles sont interdites par défaut.

Il s'agit de , donc la réponse valide la plus courte - mesurée en octets - l'emporte.

Cas de test

I II III P => I' II' III'
5 7 0 3    => 2 10 0
2 10 0 6   => 0 8 4
0 8 4 7    => 0 1 11
0 1 11 -4  => 4 1 7
4 1 7 0    => 4 1 7
4 1 7 1    => 3 2 7
3 2 7 -7   => 10 2 0
10 2 0 12  => 0 10 2
0 10 2 12  => 0 0 12

1
Je recommande de supprimer les pronoms sexospécifiques et de les remplacer par des pronoms non sexistes (ou de restructurer les phrases): les joueurs ne doivent pas nécessairement être des hommes.
Greg Martin

1
@GregMartin Bien sûr. Les ai-je tous attrapés?
Martin Ender

2
Ressemble à ça; merci d'y avoir pensé! De plus, Terra Mystica est-elle aussi géniale que je l'ai entendu?
Greg Martin

4
@GregMartin oui. :)
Martin Ender

5
Aucune puissance ne brûle du bol 2? Cela semble tellement incomplet.
moreON

Réponses:


6

Mathematica, 52 octets

{x=#-#4~Min~#,y=Max[#2+#-Abs[#4~Max~0-#],0],12-x-y}&

Il s'agit d'une fonction sans nom qui prend une liste {I, II, III, P}en entrée et renvoie une liste {I', II', III'}.

Une solution sous forme fermée. Il ne semble pas encore vraiment optimal ...


Je pensais que je pourrais raccourcir, mais {##,12-+##}&[#-#4~Min~#,Max[#2+#-Abs[#4~Max~0-#],0]]&c'est un octet plus long. J'aime 12-+##bien.
Greg Martin

1
@GregMartin J'ai essayé la même chose :)
Martin Ender

6

C, 97 94 octets

f(i,j,k,n){for(;n;n-=n/abs(n))n<0?k?++i+--k:0:i?++j+--i:j?++k+--j:0;printf("%d %d %d",i,j,k);}

Sous forme non golfée:

f(i, j, k, n) {
    while (n) {
        if (n < 0) {
            if (k) {
                ++i; --k;
            }
            ++n;
        } else {
            if (i) {
                ++j; --i;
            }
            else if (j) {
                ++k; --j;
            }
            --n;
        }
    }
    printf("%d %d %d", i, j, k);
}

5

Python 2, 104 octets

def f(i,d,t,g):
 x=min(i,g);i-=x;q=g>0;g-=x
 if q:d+=x;x=min(d,g);g-=x;d-=x;t+=x
 else:t+=x
 print i,d,t

Essayez-le en ligne

Non golfé:

def f(i,d,t,g):
 if g>0:
    x=min(i,g)
    g-=x
    i-=x
    d+=x    
    x=min(d,g)
    g-=x
    d-=x
    t+=x
 else:
    x=min(i,g)
    g-=x
    i-=x
    t+=x
 print(i,d,t)

5

Haskell, 58 octets

f(a,b,c)d|m<-min a d,z<-min(c+d-max 0 m)12=(a-m,b+c+m-z,z)

La valeur intermédiaire mindique la quantité de puissance allant de (ou vers, si elle est négative) le premier bol, zindique la quantité de puissance dans le troisième bol après l'action. Une optimisation d'un octet de dernière minute a changé l'ancienne expression du deuxième bol de l' 12-a+m-zutilisation de l'identité a+b+c=12.

Le type de résultat naturel est un triple pour les bols, donc l'entrée prend également les bols comme un triple et le changement de puissance comme deuxième argument. Cela permet de gérer tous les cas de test avec une seule application de scanl:

*Main> scanl f (5,7,0) [3,6,7,-4,0,1,-7,12,12]
[(5,7,0),(2,10,0),(0,8,4),(0,1,11),(4,1,7),(4,1,7),(3,2,7),(10,2,0),(0,10,2),(0,0,12)]

5

Röda , 100 94 octets

f a,b,c,p{{c+=p;a-=p}if[p<0]else{{a--;b++;p--}while[p*a>0];{b--;c++;p--}while[p*b>0]};[a,b,c]}

Non golfé:

f a,b,c,p {
    if [ p < 0 ] do
        c += p
        a -= p
    else
        { a-=1; b+=1; p-=1 } while [ p > 0 and a > 0 ]
        { b-=1; c+=1; p-=1 } while [ p > 0 and b > 0 ]
    done
    return a, b, c
}

Röda n'a-t-il pas les opérateurs ++et --?
Kritixi Lithos

@KritixiLithos Merci! Oui.
fergusq


3

GNU sed , 66 octets

Comprend +1 pour -r

/-/!{:
s/1,(.* )1/,1\1/
t}
s/(.*)(1+) -\2/\2\1/
s/(,,1{12}).*/\1/

Utilise unaire (voir ce consensus ).

Essayez-le en ligne!

/-/!{                  # If there is not a '-'
  :                    # start loop
  s/1,(.* )1/,1\1/     # move a 1 from before a ',' to after the ',' for every 1 after the space
                       # sed reads left to right, so this takes everything from the first bowl before starting on the second
  t                    # loop if something changed
}                      # end if
s/(.*)(1+) -\2/\2\1/   # take all of the 1s from after a '-' and move them to the begining.
                       # at the same time, remove that many 1s from the 3rd bowl
s/(,,1{12}).*/\1/      # remove everything after 12 1s in the third bowl

3

Rétine ,  46  41 39 38 octets

Merci à Martin Ender pour ses multiples suggestions utiles!

+`1,(.*¶)1
,1$1
(.*)(1+)¶-\2$
$2$1
G`,

Prend entrée en unaire. La première ligne contient les quantités d'énergie dans les trois bols, séparés par des virgules, la deuxième ligne la quantité d'énergie à parcourir.

Suite de tests - Prend toutes les entrées sur une seule ligne et convertit de la décimale en unaire et vice-versa pour plus de commodité d'utilisation.

Explication

+`1,(.*¶)1
,1$1

Cas positif: nous supprimons à plusieurs reprises le début 1de la deuxième ligne et déplaçons un 1du premier bol non vide au suivant, aussi longtemps que cette opération est possible (c'est-à-dire que le nombre de puissance à parcourir est non nul et pas tout la puissance est dans le troisième bol). Le smodificateur signifie single-line, permettant de .faire correspondre également la nouvelle ligne.

(.*)(1+)¶-\2$
$2$1

Cas négatif: fait tout en une seule étape, en déplaçant la quantité de puissance indiquée par la dernière entrée du troisième au premier bol. Cela supprimera également la ligne contenant la quantité négative de puissance à déplacer.

G`,

Conservez (grep) uniquement les lignes contenant une virgule. Cela permettra de se débarrasser des restes éventuels de la première ligne.



2

Lot, 87 octets

@set/a"i=%4-%1,j=%4*(-%4>>5)-%2-2*i*(-i>>5),i*=i>>5,j*=j>>5,k=12-i-j
@echo %i% %j% %k%

Utilisez les formules suivantes:

I' = min(I - P, 0)
II' = min(II + min(P, 0) - 2 * min(P - I, 0), 0)
III' = 12 - I' - II'

Puisque Batch n'a pas d'opérateur inférieur à, je calcule en i = min(-i, 0)utilisant i*=i>>5.


2

Perl 6 , 99 octets

->\a,\b,\c,\d{d>0??[»+»] (a,b,c),|(|((-1,1,0)xx a),|((0,-1,1)xx a+b),|(0 xx*))[^d]!!(a- d,b,c+d)}

Soit a, bet cle nombre de jetons de départ dans les bols I, II et III respectivement. Ensuite, pour le cas de puissance ajoutée, une liste est créée qui contient des acopies du triplet (-1, 1, 0), suivies par des a + bcopies du triplet (0, -1, 1), suivies par des copies infinies de 0. Les premiers déléments de cette liste, détant la quantité de puissance à ajouter, sont ajoutés élément par élément à la distribution de puissance de départ.

Pour soustraire la puissance (négatif d), on utilise une forme fermée simple: (a - d, b, c + d).


2

tinylisp , 134 octets

(d f(q((x y z p)(i p(i(l p 0)(f(s x p)y(a z p)0)(i x(f(s x 1)(a y 1)z(s p 1))(i y(f x(s y 1)(a z 1)(s p 1))(f x y z 0))))(c x(c y(c z(

Définit une fonction fqui prend quatre arguments, les trois bols ( x y z) et la quantité de puissance traitée ( p), et retourne une liste des trois bols après la transaction. Voici une version correctement espacée avec tous les cas de test: Essayez-le en ligne!

(d f                         Define f to be
 (q(                          a quoted two-item list (which acts as a function):
  (x y z p)                    Arglist: the three bowls x y z and power p
  (i p                         If p is nonzero
   (i (l p 0)                   then if p is negative (spending power)
    (f(s x p)y(a z p)0)          then take -p from z, add -p to x, and recurse with p=0
    (i x                         else (gaining power), if x is nonzero
     (f(s x 1)(a y 1)z(s p 1))    then take 1 from x, add to y, decrement p and recurse
     (i y                         else if y is nonzero
      (f x(s y 1)(a z 1)(s p 1))   then take 1 from y, add to z, decrement p and recurse
      (f x y z 0))))               else no moves possible; recurse with p=0
   (c x(c y(c z())))))))        else (p=0), cons x y z into a list and return it
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.