Terra Mystica: Велосипедна сила


28

Настільна гра Terra Mystica має дуже цікаву механіку для одного з основних ресурсів, потужності. Замість того, щоб отримувати та витрачати одиниці потужності у банку, кожен гравець починає гру з рівно 12 одиницями сили, які розподіляються на три «чаші», що мають позначення I, II та III. Набираючи та витрачаючи силу, тоді просто перекладаєте владу між цими чашами:

  • Щоб витратити одиницю потужності, перемістіть її з чаші III в чашу I (за умови, що у вас є одиниця в чаші III).
  • Коли ви наберете одиницю потужності, якщо в чаші I є одиниця, перемістіть її в чашу II. Якщо в чаші I немає одиниць, але в чаші II є одиниця, перемістіть її в чашу III. Якщо всі одиниці вже в чаші III, нічого не відбувається.
  • Коли ви отримуєте або витрачаєте кілька одиниць одночасно, вони обробляються по одній одиниці.

Ось приклад. Скажімо, гравець починає такий розподіл потужності (наводиться в порядку I | II | III):

5 | 7 | 0

Їх потужність змінюється так, якщо вони кілька разів набирають і витрачають владу:

               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)

Ваше завдання - обчислити результат однієї такої події на виграш або витрачання.

Змагання

Вам вводять чотири цілі числа як вхідні дані. Перші три, I, II, III, являють собою кількість енергії в кожному з трьох чаш. Вони будуть негативними, і вони підсумують 12. Четверте число, P- це кількість отриманої або витраченої енергії, і буде в діапазоні включень [-III, 24](тому ви можете припустити, що гравець ніколи не намагатиметься витратити більше сили ніж вони в даний час можуть, але вони можуть набирати більше енергії, ніж потрібно для переміщення всієї сили в чашу III).

Ви можете приймати ці числа в будь-якому послідовному порядку, як окремі аргументи, як список цілих чисел, або як рядок, що містить ці цілі числа. Ви також можете взяти в Pякості одного аргументу, а I, II, IIIяк окремий список аргументів.

Виведіть три цілих числа I', II', III'які представляють собою кількість енергії в кожній чаші після P одиниці були отримані або витрачені, дотримуючись правил пояснено вище.

Ви можете написати програму чи функцію та скористатися будь-яким із наших стандартних методів отримання вводу та надання виводу.

Ви можете використовувати будь-яку мову програмування , але зауважте, що ці лазівки за замовчуванням заборонені.

Це , тому найкоротший вірний відповідь - вимірюється в байтах - виграє.

Випробування

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
Рекомендую видалити гендерні займенники та замінити їх гендерно нейтральними (або реструктуризувати речення): геймери не повинні бути чоловіками.
Грег Мартін

1
@GregMartin Звичайно. Чи я їх усіх спіймав?
Мартін Ендер

2
Погляньте так; дякую, що подумали про це! Крім того, чи є Terra Mystica таким приголомшливим, як я чув?
Грег Мартін

4
@GregMartin так. :)
Мартін Ендер

5
Жодна сила не горить з чаші 2? Це просто так неповно.
більшеON

Відповіді:


6

Математика, 52 байти

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

Це неназвана функція, яка приймає список {I, II, III, P}як вхідний і повертає список {I', II', III'}.

Розчин закритої форми. Це все ще не відчуває себе оптимальним ...


Думав, що я можу скоротити, але {##,12-+##}&[#-#4~Min~#,Max[#2+#-Abs[#4~Max~0-#],0]]&на байт довше. Мені подобається 12-+##хоч.
Грег Мартін

1
@GregMartin Я спробував те ж саме :)
Мартін Ендер

6

C, 97 94 байт

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

У неозореному вигляді:

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 байти

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

Спробуйте в Інтернеті

Безголівки:

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

Хаскелл, 58 байт

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

Проміжне значення mпозначає величину потужності, що йде від (або до негативної) першої чаші, zпозначає кількість потужності в третій чаші після дії. Остання оптимізація в один байт змінила старий вираз для другої чаші з 12-a+m-zвикористання ідентичності a+b+c=12.

Природний тип результату - це потрійний для мисок, тому введення також приймає миски як потрійне, а зміна потужності - як другий аргумент. Це дозволяє обробляти всі тестові випадки одним застосуванням 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

Roda , 100 94 байт

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

Безголівки:

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 не мають ++і --операторів?
Kritixi Lithos

@KritixiLithos Дякую! Так.
fergusq


3

GNU sed , 66 байт

Включає +1 для -r

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

Використовується одинаково (див. Цей консенсус ).

Спробуйте в Інтернеті!

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

Сітківка ,  46  41 39 38 байт

Дякуємо Мартіну Ендеру за багато корисних пропозицій!

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

Здійснює введення в одинаковому режимі. Перший рядок містить величину потужності в трьох чашах, розділених комами, другий рядок - кількість потужності для циклу.

Тестовий набір - приймає всі входи в одному рядку і перетворює з десяткових в одинарні та навпаки для зручності використання.

Пояснення

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

Позитивний випадок: ми неодноразово видаляємо ведучі 1з другого рядка і переміщуємо a 1з першої не порожньої чаші на наступну, доки ця операція можлива (тобто кількість потужності для циклу не дорівнює нулю, і не все потужність в третій мисці). У sмодифікують засоби single-line, що дозволяє , .щоб відповідати також символ нового рядка.

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

Негативний випадок: робиться все за один крок, переміщуючи кількість потужності, вказану останнім входом, від третьої до першої чаші. Це також видалить лінію, що містить негативну кількість сили для переміщення.

G`,

Зберігайте (grep) лише рядки, що містять кому. Це дозволить позбутися від можливих залишків першого рядка.



2

Пакет, 87 байт

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

Використовуйте такі формули:

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

Оскільки Batch не має менше оператора, я обчислюю, i = min(-i, 0)використовуючи i*=i>>5.


2

Perl 6 , 99 байт

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

Нехай a, bі cбуде число стартових жетонів у чашах I, II та III відповідно. Потім для випадку додавання потужності створюється список, який містить aкопії триплету (-1, 1, 0), а потім a + bкопії триплету (0, -1, 1), а потім нескінченні копії 0. Перші dелементи цього списку, dяк кількість потужності, яку потрібно додати, додаються поетапно до початкового розподілу потужності.

Для вирахування потужності (негативний d), використовується проста замкнута форма: (a - d, b, c + d).


2

тинілісп , 134 байти

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

Визначає функцію, fяка бере чотири аргументи, три чаші ( x y z) та кількість потужності, що передавалася ( p), і повертає список трьох чаш після транзакції. Ось правильно розміщена версія з усіма тестовими кейсами: Спробуйте її в Інтернеті!

(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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.