Terra Mystica: Bisiklet Gücü


28

Tahta oyunu Terra Mystica , en önemli kaynaklardan biri olan iktidar için çok ilginç bir mekanizmaya sahiptir. Her oyuncu bir bankadan güç kazanmak ve harcamak yerine, her oyuna I, II ve III etiketli üç "kasenin" üzerine dağıtılan tam 12 birim güçle oyuna başlar. Gücü kazanmak ve harcamak daha sonra bu kaseler arasında gücü değiştirir:

  • Bir birim güç harcamak için, kase III'den kase I'e (kase III'te bir üniteniz olması koşuluyla) taşıyın.
  • Bir güç kazandığınızda, kase I'de bir ünite varsa, kase II'ye getirin. Kase I'de birimler yoksa, ancak Kase II'de bir birim varsa, kase III'e getirin. Tüm birimler zaten kasede III ise, hiçbir şey olmuyor.
  • Aynı anda birden fazla birim kazandığınızda veya harcadığınızda, bir seferde bir ünite işlenir.

İşte bir örnek. Diyelim ki, bir oyuncu aşağıdaki güç dağıtımıyla başlar (sırayla verilir I | II | III):

5 | 7 | 0

Birkaç kez güç kazanıp harcarlarsa güçleri şu şekilde değişir:

               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)

Göreviniz böyle bir kazanma ya da harcama olayı sonucu hesaplamaktır.

Meydan okuma

Giriş olarak dört tamsayı verilir. İlk üç, I, II, III, üç kase her güç miktarını temsil eder. Negatif olmayacaklar ve 12'ye toplayacaklar. Dördüncü sayı, Pkazanılan veya harcanan güç miktarı ve kapsayıcı aralıkta olacak [-III, 24](oyuncunun asla daha fazla güç harcamayı deneyemeyeceğini düşünebilirsiniz. şu anda yapabildiklerinden daha fazla, ancak tüm gücü kabın içine taşımaları gerekenden daha fazla güç kazanıyor olabilirler III).

Bu sayıları herhangi bir tutarlı sırayla, ayrı argümanlar, tam sayılar listesi veya bu tam sayıları içeren bir dize olarak alabilirsiniz. Ayrıca alabilir Pgibi bir argüman olarak I, II, IIIayrı bir liste argüman olarak.

Sen çıkış üç tamsayılar gerektiğini I', II', III'her kapta güç miktarını temsil hangi sonra P birimler kazanmış veya kurallar yukarıda açıklandığı ardından harcandı.

Bir program veya fonksiyon yazabilir ve standart girdi alma ve çıktı alma yöntemlerimizden herhangi birini kullanabilirsiniz .

Herhangi bir programlama dilini kullanabilirsiniz , ancak bu boşlukların varsayılan olarak yasak olduğunu unutmayın .

Bu , yani en kısa geçerli cevap - bayt cinsinden - kazanır.

Test Kılıfları

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
Cinsiyete özgü zamirlerin kaldırılmasını ve cinsiyetten bağımsız olanların (veya yeniden yapılanma cümlelerinin) değiştirilmesini öneririm: oyuncuların erkek olmaları gerekmez.
Greg Martin

1
Elbette @GregMartin. Hepsini yakaladım mı?
Martin Ender

2
Öyle görün; düşündüğün için teşekkür ederim! Ayrıca, Terra Mystica duyduğum kadar harika mı?
Greg Martin,

4
@GregMartin evet. :)
Martin Ender

5
Kaseden 2 elektrik gelmiyor mu? Bu sadece çok eksik hissettiriyor.
fazlaMON

Yanıtlar:


6

Mathematica, 52 bayt

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

Bu, bir listeyi {I, II, III, P}girdi olarak alan ve bir liste döndüren adlandırılmamış bir işlevdir {I', II', III'}.

Kapalı formlu bir çözüm. Henüz gerçekten optimal hissetmiyor ...


Kısaltabileceğimi düşündüm, ama {##,12-+##}&[#-#4~Min~#,Max[#2+#-Abs[#4~Max~0-#],0]]&daha uzun bir bayt. 12-+##Yine de hoşuma gitti .
Greg Martin

1
@GregMartin Aynı şeyi denedim :)
Martin Ender

6

C, 97 94 bayt

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

Ungolfed formunda:

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 bayt

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

Çevrimiçi deneyin

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 bayt

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

Ara değer m, ilk kaseden gelen (veya negatifse) geçen zgüç miktarını, işlemden sonra üçüncü kasedeki güç miktarını belirtir. Son dakikadaki bir bayt optimizasyonu, ikinci kase için eski ifadeyi 12-a+m-zkimliği kullanmaktan değiştirdi a+b+c=12.

Doğal sonuç tipi kaseler için üçlüdür, bu nedenle giriş kaseleri üçlü olarak alır ve güç ikinci bir argüman olarak değişir. Bu, tüm test durumlarının tek bir uygulama ile ele alınmasına izin verir 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 bayt

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 ++ve --operatörlere sahip değil mi?
Kritixi Lithos

@KritixiLithos Teşekkürler! Evet öyle.
fergusq


3

GNU sed , 66 bayt

İçin +1 içerir -r

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

Tek taraflı kullanır ( bu fikir birliğine bakınız ).

Çevrimiçi deneyin!

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

Yardımcı öneriler için Martin Ender'e teşekkürler !

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

Tekli girişi alır. İlk satır üç kasedeki güç miktarını içerir, virgülle ayrılmış, ikinci satır ise çevrilecek güç miktarını içerir.

Test paketi - Tüm girişleri tek bir satırda alır ve kullanım rahatlığı için ondalık sayılardan düzensiz ve tam tersine dönüştürür.

açıklama

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

Olumlu durum: ana 1çizgiyi ikinci çizgiden tekrar tekrar çıkarırız ve a 1boş olmayan ilk hazneden diğerine ilerleriz, bu işlem mümkün olduğu sürece (yani, çevrilecek güç sayısı sıfır değil ve hepsi değil) güç üçüncü kaptadır). sModifiye edici aracı single-line, izin .da yeni satır eşleşecek.

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

Olumsuz durum: hepsi bir adımda yapılır, son girdi tarafından belirtilen güç miktarı üçüncüten birinci kaseye taşınır. Bu, taşınacak negatif güç miktarını içeren çizgiyi de kaldıracaktır.

G`,

Yalnızca virgül içeren satırları tutun (grep). Bu, ilk satırdaki nihai kalıntılardan kurtulacak.


3

Python 2, 91 bayt

Dayanarak bu cevap

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

Çevrimiçi deneyin

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)

Siteye Hoşgeldiniz!
DJMcMayhem

2

Toplu iş, 87 bayt

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

Aşağıdaki formülleri kullanın:

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

Batch'in operatörden daha az olmadığından, onu i = min(-i, 0)kullanarak hesaplarım i*=i>>5.


2

Perl 6 , 99 bayt

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

Let a, bve cI, II, ve III 'sırasıyla kase belirteçleri başlangıç sayısı olabilir. Ardından, ekleme güç durum için, bir liste içeren oluşturulur aüçlü kopyalarını (-1, 1, 0), ardından a + büçlü kopyalarının(0, -1, 1) sonsuz kopya ardından 0. dBu listenin ilk elemanları,d , eklenecek güç miktarıdır, başlangıçtaki güç dağılımına eleman olarak eklenir.

Güç (negatif çıkarılarak için d), basit bir kapalı form kullanılır: (a - d, b, c + d).


2

tinylisp , 134 bayt

(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Üç argüman (üç kasedi ( x y z) ve işlem yapılan güç miktarını ( ) alan ve işlemden psonra üç çanağın bir listesini döndüren bir işlev tanımlar . İşte tüm test senaryoları ile uygun şekilde yerleştirilmiş bir versiyon: Çevrimiçi deneyin!

(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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.