Terra Mystica: Poder de Ciclismo


28

O jogo de tabuleiro Terra Mystica tem algumas mecânicas muito interessantes para um dos principais recursos, o poder. Em vez de ganhar e gastar unidades de poder de um banco, cada jogador inicia o jogo com exatamente 12 unidades de poder, distribuídas por três "tigelas", rotuladas como I, II e III. Ganhar e gastar poder simplesmente muda o poder entre essas tigelas:

  • Para gastar uma unidade de energia, mova-a da tigela III para a tigela I (desde que você tenha uma unidade na tigela III).
  • Quando você ganhar uma unidade de energia, se houver uma unidade na tigela I, mova-a para a tigela II. Se não houver unidades na tigela I, mas houver uma unidade na tigela II, mova-a para a tigela III. Se todas as unidades já estiverem na tigela III, nada acontece.
  • Quando você ganha ou gasta várias unidades de uma vez, elas são processadas uma unidade de cada vez.

Aqui está um exemplo. Digamos, um jogador começa com a seguinte distribuição de energia (fornecida em ordem I | II | III):

5 | 7 | 0

O poder deles muda da seguinte maneira se eles ganham e gastam poder algumas vezes:

               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)

Sua tarefa é calcular o resultado de um desses eventos de ganho ou gasto.

O desafio

Você recebe quatro números inteiros como entrada. Os três primeiros, I, II, III, representam a quantidade de energia em cada uma das três taças. Eles serão não negativos e somarão 12. O quarto número, Pé a quantidade de energia adquirida ou gasta e estará no intervalo inclusivo [-III, 24](portanto, você pode assumir que o jogador nunca tentará gastar mais poder do que atualmente, mas podem estar ganhando mais poder do que precisam para mover todo o poder para a tigela III).

Você pode levar esses números em qualquer ordem consistente, como argumentos separados, como uma lista de números inteiros ou como uma sequência contendo esses números inteiros. Você também pode tomar Pcomo um argumento, como I, II, IIIcomo um argumento lista separada.

Você deve saída três inteiros I', II', III'que representam a quantidade de energia em cada tigela depois P unidades foram ganho ou gasto, seguindo as regras explicadas acima.

Você pode escrever um programa ou uma função e usar qualquer um dos nossos métodos padrão de recebimento de entrada e saída.

Você pode usar qualquer linguagem de programação , mas observe que essas brechas são proibidas por padrão.

Isso é , então a resposta mais curta e válida - medida em bytes - vence.

Casos de teste

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
Eu recomendo remover pronomes específicos de gênero e substituí-los por neutros de gênero (ou sentenças de reestruturação): os jogadores não precisam ser do sexo masculino.
Greg Martin

1
@GregMartin Claro. Eu peguei todos eles?
Martin Ender

2
Parece com isso; obrigado por pensar nisso! Além disso, o Terra Mystica é tão incrível quanto eu ouvi?
Greg Martin

4
@GregMartin yes. :)
Martin Ender

5
Não há energia queimada na tigela 2? Isso parece tão incompleto.
moreON

Respostas:


6

Mathematica, 52 bytes

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

Esta é uma função sem nome que recebe uma lista {I, II, III, P}como entrada e retorna uma lista {I', II', III'}.

Uma solução de forma fechada. Ainda não parece realmente ótimo ...


Pensei que poderia diminuir, mas {##,12-+##}&[#-#4~Min~#,Max[#2+#-Abs[#4~Max~0-#],0]]&é um byte mais longo. Eu gosto do 12-+##embora.
Greg Martin

1
@GregMartin Eu tentei a mesma coisa :)
Martin Ender

6

C, 97 94 bytes

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

Na forma não-gasta:

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 bytes

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

Experimente 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 bytes

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

O valor intermediário mindica a quantidade de energia que vai (ou se for negativa) à primeira tigela, zindica a quantidade de energia na terceira tigela após a ação. Uma otimização de um byte de última hora mudou a expressão antiga do segundo bowl de 12-a+m-zusar a identidade a+b+c=12.

O tipo de resultado natural é um triplo para as taças; portanto, a entrada também leva as taças como um triplo e o poder muda como um segundo argumento. Isso permite lidar com todos os casos de teste com um aplicativo 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 bytes

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 não tem os operadores ++e --?
Kritixi Lithos

@KritixiLithos Thanks! Sim.
Fergusq


3

GNU sed , 66 bytes

Inclui +1 para -r

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

Usa unário (veja este consenso ).

Experimente 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 bytes

Agradecemos a Martin Ender por várias sugestões úteis!

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

Recebe entrada em unário. A primeira linha contém as quantidades de energia nas três tigelas, separadas por vírgula; a segunda linha, a quantidade de energia a ser percorrida.

Conjunto de teste - Aceita todas as entradas em uma única linha e converte de decimal em unário e vice-versa para facilitar o uso.

Explicação

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

Caso positivo: removemos repetidamente a guia 1da segunda linha e movemos a 1da primeira tigela não vazia para a seguinte, contanto que essa operação seja possível (ou seja, o número de energia para ciclo é diferente de zero e nem todos o poder está na terceira tigela). O smodificador significa single-line, permitindo .combinar também a nova linha.

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

Caso negativo: feito tudo em uma única etapa, movendo a quantidade de energia indicada pela última entrada da terceira para a primeira tigela. Isso também removerá a linha que contém a quantidade negativa de energia a ser movida.

G`,

Mantenha (grep) apenas linhas contendo uma vírgula. Isso vai livrar-se dos eventuais restos da primeira linha.



2

Lote, 87 bytes

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

Use as seguintes fórmulas:

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

Como o Lote não tem um operador menor que, eu calculo i = min(-i, 0)usando i*=i>>5.


2

Perl 6 , 99 bytes

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

Seja a, be cseja o número de fichas iniciais nas tigelas I, II e III, respectivamente. Em seguida, para o caso de adição de poder, é criada uma lista que contém acópias do trigêmeo (-1, 1, 0), seguidas de a + bcópias do trigêmeo (0, -1, 1), seguidas de cópias infinitas de 0. Os primeiros delementos desta lista, dsendo a quantidade de energia a ser adicionada, são adicionados elemento a elemento à distribuição de energia inicial.

Para poder subtraindo (negativo d), uma forma fechada simples é utilizada: (a - d, b, c + d).


2

tinylisp , 134 bytes

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

Define uma função fque recebe quatro argumentos, as três taças ( x y z) e a quantidade de energia transacionada ( p) e retorna uma lista das três taças após a transação. Aqui está uma versão espaçada corretamente com todos os casos de teste: Experimente 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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.