Terra Mystica: Moc rowerowa

28

Gra planszowa Terra Mystica ma kilka bardzo interesujących mechanizmów dla jednego z podstawowych zasobów, mocy. Zamiast zdobywać i wydawać jednostki mocy z banku, każdy gracz rozpoczyna grę z dokładnie 12 jednostkami mocy, które są rozmieszczone na trzech „misach”, oznaczonych jako I, II i III. Pozyskiwanie i wydawanie mocy następnie przesuwa moc między tymi miskami:

  • Aby wydać jednostkę mocy, przenieś ją z misy III do misy I (pod warunkiem, że masz jednostkę w misce III).
  • Kiedy zyskasz jednostkę mocy, jeśli w misce I znajduje się jednostka, przenieś ją do misy II. Jeśli w misce I nie ma żadnych jednostek, ale w misce II jest jednostka, przenieś ją do misy III. Jeśli wszystkie jednostki są już w misce III, nic się nie dzieje.
  • Gdy zyskujesz lub wydajesz wiele jednostek naraz, są one przetwarzane pojedynczo.

Oto przykład. Powiedzmy, że gracz zaczyna od następującej dystrybucji mocy (podanej w kolejności I | II | III):

5 | 7 | 0

Ich moc zmienia się w następujący sposób, jeśli zdobędzie i wyda moc kilka razy:

               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)

Twoim zadaniem jest obliczenie wyniku jednego takiego zdarzenia pozyskiwania lub wydawania.

Wyzwanie

Jako dane wejściowe podano cztery liczby całkowite. Pierwsze trzy, I, II, III, oznaczają ilość energii w każdej z trzech misek. Będą nieujemne i sumują się do 12. Czwarta liczba, Poznacza ilość uzyskanej lub wydanej mocy i będzie w zakresie obejmującym [-III, 24](więc możesz założyć, że gracz nigdy nie będzie próbował wydać większej mocy niż mogą obecnie, ale mogą zyskać więcej mocy niż potrzebują przenieść całą moc do misy III).

Możesz wziąć te liczby w dowolnej spójnej kolejności, jako osobne argumenty, jako listę liczb całkowitych lub jako ciąg zawierający te liczby całkowite. Można również przyjąć Pjako jeden argument za I, II, IIIjako osobna lista jej argumentów.

Należy wyjść trzy liczby całkowite I', II', III'co stanowi ilość energii w każdej misce po P jednostki zostały zdobyte lub wydane, zgodnie z zasadami wyjaśniono powyżej.

Możesz napisać program lub funkcję i użyć dowolnej z naszych standardowych metod otrzymywania danych wejściowych i dostarczania danych wyjściowych.

Możesz używać dowolnego języka programowania , ale pamiętaj, że te luki są domyślnie zabronione.

To jest , więc wygrywa najkrótsza ważna odpowiedź - mierzona w bajtach .

Przypadki testowe

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
Martin Ender
źródło
1
Polecam usunięcie zaimków specyficznych dla płci i zastąpienie ich neutralnymi dla płci (lub restrukturyzacyjnymi zdaniami): gracze nie muszą być mężczyznami.
Greg Martin
1
@GregMartin Oczywiście. Czy złapałem je wszystkie?
Martin Ender,
2
Tak to wygląda; dziękuję za myślenie o tym! Czy Terra Mystica jest tak niesamowita, jak słyszałem?
Greg Martin
4
@GregMartin tak. :)
Martin Ender,
5
Brak mocy w misce 2? To po prostu wydaje się tak niekompletne.
moreON

Odpowiedzi:

6

Mathematica, 52 bajty

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

Jest to nienazwana funkcja, która pobiera listę {I, II, III, P}jako dane wejściowe i zwraca listę {I', II', III'}.

Rozwiązanie w formie zamkniętej. To naprawdę nie wydaje się optymalne ...

Martin Ender
źródło
Myślałem, że mogę skrócić, ale {##,12-+##}&[#-#4~Min~#,Max[#2+#-Abs[#4~Max~0-#],0]]&jest bajt dłużej. 12-+##Mimo to lubię .
Greg Martin
1
@GregMartin Próbowałem tego samego :)
Martin Ender
6

C, 97 94 bajtów

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

W formie bez golfa:

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);
}
Steadybox
źródło
5

Python 2, 104 bajty

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

Wypróbuj online

Nie golfowany:

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)
mbomb007
źródło
5

Haskell, 58 bajtów

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

Wartość pośrednia moznacza ilość mocy przechodzącej od (lub do, jeśli ujemna) pierwszej misy, zoznacza ilość mocy w trzeciej misce po akcji. W ostatniej chwili optymalizacja jednego bajtu zmieniła stare wyrażenie dla drugiej miski od 12-a+m-zużywania tożsamości a+b+c=12.

Naturalny typ wyniku jest potrójny dla misek, więc wkład bierze potrawy również jako potrójne, a zmiana mocy jako drugi argument. Umożliwia to obsługę wszystkich przypadków testowych za pomocą jednej aplikacji 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)]
Christian Sievers
źródło
5

Röda , 100 94 bajtów

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

Nie golfowany:

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
}
fergusq
źródło
Czy Röda nie ma operatorów ++i --?
Kritixi Lithos
@KritixiLithos Thanks! Tak.
fergusq
4

JavaScript, 61 59 bajtów

(a,b,c,d)=>[r=a-d>0?a-d:0,s=r?b:b-d+2*a>0?b-d+2*a:0,12-r-s]

Wypróbuj online!

Fəˈnɛtɪk
źródło
3

GNU sed , 66 bajtów

Obejmuje +1 dla -r

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

Wykorzystuje unary (patrz ten konsensus ).

Wypróbuj 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
Riley
źródło
3

Siatkówka ,  46  41 39 38 bajtów

Dziękujemy Martinowi Enderowi za wiele pomocnych sugestii!

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

Pobiera dane wejściowe jednoargumentowe. Pierwszy wiersz zawiera ilości mocy w trzech miseczkach, oddzielonych przecinkami, drugi wiersz zawiera ilość mocy do cyklowania.

Zestaw testowy - pobiera wszystkie dane wejściowe w jednym wierszu i konwertuje z dziesiętnego na jednoargumentowy i odwrotnie dla wygody użytkowania.

Wyjaśnienie

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

Przypadek pozytywny: kilkakrotnie usuwamy prowadzenie 1z drugiej linii i przenosimy a 1z pierwszej niepustej misy do następnej, o ile ta operacja jest możliwa (tzn. Liczba cykli zasilania jest niezerowa i nie wszystkie moc znajduje się w trzeciej misce). W smodyfikator środki single-line, umożliwiając .w celu dopasowania również do nowej linii.

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

Przypadek ujemny: wykonane wszystko w jednym kroku, przenosząc ilość mocy wskazaną przez ostatni wkład z trzeciej do pierwszej misy. Spowoduje to również usunięcie linii zawierającej ujemną ilość mocy do ruchu.

G`,

Zachowaj (grep) tylko wiersze zawierające przecinek. Pozbędzie się to ewentualnych pozostałości pierwszej linii.

Lew
źródło
3

Python 2, 91 bajtów

Na podstawie tej odpowiedzi

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

Wypróbuj online

Nie golfowany:

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)
Alejandro Castillo
źródło
Witamy na stronie!
DJMcMayhem
2

Partia, 87 bajtów

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

Użyj następujących formuł:

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

Ponieważ Batch nie ma mniej niż operatora, obliczam i = min(-i, 0)za pomocą i*=i>>5.

Neil
źródło
2

Perl 6 , 99 bajtów

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

Niech a, bi cbędzie liczbą początkowych żetonów odpowiednio w misach I, II i III. Następnie dla przypadku dodawania mocy tworzona jest lista zawierająca akopie tripletu (-1, 1, 0), następnie a + bkopie tripletu (0, -1, 1), a następnie nieskończone kopie 0. Pierwsze delementy tej listy, dczyli ilość mocy do dodania, są dodawane elementarnie do początkowego rozkładu mocy.

Odjęcie energii (ujemne d), prosta forma zamknięta stosuje się: (a - d, b, c + d).

Sean
źródło
2

tinylisp , 134 bajty

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

Definiuje funkcję, fktóra pobiera cztery argumenty, trzy miski ( x y z) i ilość mocy przetwarzanej ( p), i zwraca listę trzech misek po transakcji. Oto odpowiednio rozmieszczona wersja ze wszystkimi przypadkami testowymi: Wypróbuj 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
DLosc
źródło