Terra Mystica: potenza ciclistica


28

Il gioco da tavolo Terra Mystica ha delle meccaniche molto interessanti per una delle risorse primarie, il potere. Invece di guadagnare e spendere unità di potere da una banca, ogni giocatore inizia il gioco con esattamente 12 unità di potere che sono distribuite su tre "ciotole", che sono etichettati I, II e III. Guadagnare e spendere potere sposta semplicemente il potere tra queste ciotole:

  • Per spendere un'unità di potere, spostala dalla ciotola III alla ciotola I (a condizione che tu abbia un'unità nella ciotola III).
  • Quando ottieni un'unità di potere, se c'è un'unità nella ciotola I, spostala nella ciotola II. Se non ci sono unità nella ciotola I, ma c'è un'unità nella ciotola II, spostarla nella ciotola III. Se tutte le unità sono già nella ciotola III, non succede nulla.
  • Quando guadagni o spendi più unità contemporaneamente, vengono elaborate un'unità alla volta.

Ecco un esempio Ad esempio, un giocatore inizia con la seguente distribuzione di energia (indicata in ordine I | II | III):

5 | 7 | 0

Il loro potere cambia come segue se guadagnano e spendono il potere alcune volte:

               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)

Il tuo compito è calcolare il risultato di uno di questi eventi di guadagno o spesa.

La sfida

Ti vengono dati quattro numeri interi come input. I primi tre, I, II, III, rappresentano la quantità di potenza in ciascuna delle tre ciotole. Saranno non negativi e si sommeranno a 12. Il quarto numero Pè la quantità di potere guadagnato o speso e sarà compreso nell'intervallo [-III, 24](quindi puoi presumere che il giocatore non proverà mai a spendere più potere di quello che possono attualmente, ma potrebbero guadagnare più potere di quello di cui hanno bisogno per spostare tutto il potere nella ciotola III).

Puoi prendere questi numeri in qualsiasi ordine coerente, come argomenti separati, come un elenco di numeri interi o come una stringa contenente questi numeri interi. È anche possibile prendere Pcome un argomento, come I, II, IIIcome argomento lista separata.

Si dovrebbe uscita tre numeri interi I', II', III'che rappresentano la quantità di potenza in ogni ciotola dopo P le unità sono state acquisite o spesi, seguendo le regole spiegate sopra.

È possibile scrivere un programma o una funzione e utilizzare uno dei nostri metodi standard per ricevere input e fornire output.

È possibile utilizzare qualsiasi linguaggio di programmazione , ma si noti che queste scappatoie sono vietate per impostazione predefinita.

Questo è , quindi la risposta valida più breve - misurata in byte - vince.

Casi 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
Consiglio di rimuovere i pronomi specifici per genere e di sostituirli con pronomi di genere neutro (o di ristrutturare le frasi): i giocatori non devono essere maschi.
Greg Martin

1
@GregMartin Certo. Li ho presi tutti?
Martin Ender,

2
Assomigliare; grazie per averci pensato! Inoltre, Terra Mystica è fantastica come ho sentito?
Greg Martin

4
@GregMartin sì. :)
Martin Ender

5
Nessuna potenza brucia dalla ciotola 2? Sembra così incompleto.
più il

Risposte:


6

Mathematica, 52 byte

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

Questa è una funzione senza nome che accetta un elenco {I, II, III, P}come input e restituisce un elenco {I', II', III'}.

Una soluzione a forma chiusa. Non sembra ancora ottimale ...


Ho pensato di accorciare, ma {##,12-+##}&[#-#4~Min~#,Max[#2+#-Abs[#4~Max~0-#],0]]&è un byte più lungo. Mi piace 12-+##però.
Greg Martin

1
@GregMartin Ho provato la stessa cosa :)
Martin Ender il

6

C, 97 94 byte

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);}

In forma non golfata:

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 byte

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

Provalo online

Ungolfed:

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 byte

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

Il valore intermedio mindica la quantità di potenza che va (o a, se negativa) dalla prima ciotola, zindica la quantità di potenza nella terza ciotola dopo l'azione. Un'ottimizzazione di un byte dell'ultimo minuto ha cambiato la vecchia espressione per la seconda ciotola 12-a+m-zdall'uso dell'identità a+b+c=12.

Il tipo di risultato naturale è una tripla per le ciotole, quindi l'input prende anche le ciotole come una tripla e la potenza cambia come secondo argomento. Ciò consente di gestire tutti i casi di test con una sola applicazione di 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 byte

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]}

Ungolfed:

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 non ha gli operatori ++e --?
Kritixi Lithos

@KritixiLithos Grazie! Sì lo fa.
Fergusq


3

GNU sed , 66 byte

Include +1 per -r

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

Utilizza unario (vedi questo consenso ).

Provalo online!

/-/!{                  # 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

Retina ,  46  41 39 38 byte

Grazie a Martin Ender per molteplici suggerimenti utili!

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

Riceve input in unario. La prima riga contiene la quantità di potenza nelle tre ciotole, separate da virgola, la seconda riga la quantità di potenza da scorrere.

Suite di test : prende tutti gli input su una sola riga e converte da decimale a unario e viceversa per praticità d'uso.

Spiegazione

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

Caso positivo: rimuoviamo ripetutamente il comando 1dalla seconda riga e spostiamo a 1dalla prima ciotola non vuota a quella successiva, purché questa operazione sia possibile (ovvero il numero di potenza da percorrere è diverso da zero e non tutto il potere è nella terza ciotola). Il smodificatore significa single-line, permettendo .di abbinare anche la nuova riga.

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

Caso negativo: fatto tutto in un solo passaggio, spostando la quantità di potenza indicata dall'ultimo input dalla terza alla prima ciotola. Ciò rimuoverà anche la linea contenente la quantità negativa di potenza da spostare.

G`,

Mantieni (grep) solo le righe che contengono una virgola. Questo eliminerà gli eventuali resti della prima linea.


3

Python 2, 91 byte

Sulla base di questa risposta

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

Provalo online

Ungolfed:

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

Benvenuti nel sito!
DJMcMayhem

2

Lotto, 87 byte

@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%

Usa le seguenti formule:

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

Dato che Batch non ha un operatore minore di, calcolo i = min(-i, 0)usando i*=i>>5.


2

Perl 6 , 99 byte

->\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)}

Sia a, be csia il numero di gettoni iniziali rispettivamente nelle ciotole I, II e III. Quindi, per l'aggiunta di power case, viene creato un elenco che contiene acopie della tripletta (-1, 1, 0), seguite da a + bcopie della tripletta (0, -1, 1), seguite da copie infinite di 0. I primi delementi di questo elenco, dessendo la quantità di energia da aggiungere, vengono aggiunti in modo elementare alla distribuzione di energia iniziale.

Per potere (negativo sottraendo d), una forma chiusa semplice viene utilizzato: (a - d, b, c + d).


2

tinylisp , 134 byte

(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(

Definisce una funzione fche accetta quattro argomenti, le tre ciotole ( x y z) e la quantità di potenza trattata ( p) e restituisce un elenco delle tre ciotole dopo la transazione. Ecco una versione ben spaziata con tutti i casi di test: provalo online!

(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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.