Zdobądź dylemat asynchronicznego więźnia

15

W rundzie ćwiczenia dylematu więźnia , każdy z dwóch graczy decyduje, czy w tej rundzie będzie współpracować, czy też wada . Punktacja dla rundy to:

  • Zarówno gracz A, jak i gracz B współpracują: 1 punkt dla obu
  • Wada zarówno gracza A, jak i gracza B: 2 punkty za oba
  • Gracz A współpracuje, a gracz B ma wady: 3 punkty za współpracującego gracza A i 0 punktów za wadliwego gracza B.

Nie musisz się jednak martwić strategią: twój program będzie jedynie zestawiał wynik gry. (Jeśli znasz już dylemat więźnia, moje „punkty” tutaj odpowiadają „latom w więzieniu”).

Twoim wyzwaniem jest zdobycie wkładu reprezentującego wybory graczy w kilku rundach i obliczenie ich łącznej liczby punktów. Jeden gracz dokonuje wyboru małymi literami, ca d(w przypadku współpracy i wad ), a drugi wybiera wielkie litery, Ca D. Te opcje są dostarczane do programu jako ciąg.

Zwykle gracze dylematu więźnia poddają swoje ruchy jednocześnie i iteracyjnie. Jednak w tym wyzwaniu gracze mogli przedłożyć swoje wybory na kilka rund jednocześnie. Jeśli ruch gracza jest poza sekwencją, program punktacji zapamiętuje go i dopasowuje go do następnego dostępnego ruchu przeciwnika.

Oto przykładowy ciąg wejściowy:

cDCddDDCcCc

Aby wyświetlić dopasowania występujące w tym danych wejściowych, osobno wywołam małe i wielkie litery i sparuję je:

cDCddDDCcCc
c  dd   c c => cddcc
 DC  DDC C  => DCDDCC

Zostaną one sparowane w rundach:

c vs D (3 pts for lowercase-player, 0 pts for uppercase-player)
d vs C (0 pts for lowercase-player, 3 pts for uppercase-player)
d vs D (2 pts for both)
c vs D (3 pts for lowercase-player, 0 pts for uppercase-player)
c vs C (1 pt for both)

Który tworzy wynik 9(małe litery) do 6(wielkie litery), więc wynikiem powinno być 9,6(lub dowolny jednoznaczny separator).

Aby wyrazić to w jeszcze inny sposób, oto każda para wyciągnięta w osobnym rzędzie:

cDCddDDCcCc
cD
  Cd
    dD
      D c
       C  c

Jest jeden nieporównywalny C, ponieważ gracz z dużymi literami zgłosił więcej ruchów niż gracz z małą literą. Jest to do przyjęcia i jest całkowicie ignorowane do celów punktacji.

Oto wymagania:

  • Musisz napisać program lub funkcję, która akceptuje ciąg wyrażenia regularnego /[cdCD]+/, za pośrednictwem jakiegoś mechanizmu wejściowego (STDIN, argument funkcji, odczyt z pliku itp.). (Twój program może opcjonalnie zaakceptować wejście z końcowym znakiem nowej linii).

  • Twój program lub funkcja musi generować lub zwracać wyniki graczy jako ciąg znaków. Format wyjściowy musi zaczynać się od wyniku małego gracza, po którym następuje wynik dużego gracza, oddzielone dowolnym niepustym, nieliczbowym ogranicznikiem według własnego wyboru. (Końcowy znak nowej linii jest opcjonalny).

  • Jeśli jeden gracz ma więcej ruchów niż drugi, nadwyżki ruchów są ignorowane.

  • Jeśli wszystkie ruchy na wejściu pochodzą wyłącznie od jednego gracza (to znaczy w ogóle nie rozegrano rund), wynik każdego gracza jest taki 0.

  • Najmniejsze przesłanie w bajtach wygrywa.

Przypadki testowe

Input:  cDCddDDCcCc
Output: 9,6         -- or any delimiter; I chose commas here

Input:  cccDDD
Output: 9,0         

Input:  DDDDDDccc
Output: 9,0

Input:  cDcDcD
Output: 9,0

Input:  dcDDC
Output: 5,2

Input:  CcdCDDcd
Output: 6,6

Input:  Ddd
Output: 2,2

Input:  ccccccccccc
Output: 0,0
apsillery
źródło
czy zwykle nie otrzymują 2 punktów za współpracę i tracą 1 punkt, jeśli oba są wadliwe?
Eumel,
1
@Eumel Właśnie skopiowałem specyfikacje ze wstępu do Wikipedii, która wydaje się używać sformułowania sugerowanego przez oryginalnych autorów. Zauważ również, że punkty tutaj są „złe”, ponieważ odpowiadają latom spędzonym w więzieniu. Zwycięzcą zostaje gracz z najmniejszą liczbą punktów.
apsillers
Jest (0,0)lub [0,0]OK do wyjścia?
xnor

Odpowiedzi:

3

Pyth, 23 bajty

jsMc2/L`C,@Gz-zG"cDDCdd

Zestaw testowy


Wyjaśnienie:

@Gz: Małe litery

-zG: Wielkie litery

C,: Sparuj, skróć pozostałą część.

`: Weź ciąg reprezentujący listę par

/L ... "cDDCdd: Dla każdej litery w "cDDCdd"policz, ile razy pojawia się w powyższym napisie repr.

c2: Posiekaj wynikową listę na pół.

sM: Dodaj każdą połowę.

j: Dołącz do nowych linii i drukuj.


`musi być użyte zamiast s, aby przypadek, w którym jedna strona nigdy nie gra, działał.

isaacg
źródło
5

Haskell, 139 134 bajtów

g=filter
(n!m)(a,b)=(a+n,b+m)
f s=init$tail$show$foldr id(0,0)$zipWith(#)(g(>'a')s)$g(<'E')s
'c'# 'C'=1!1
'c'#_=3!0
_# 'D'=2!2
_#_=0!3

Przykład użycia: f "cDCddDDCcCc"-> "9,6"

15 bajtów tylko po to, aby uzyskać prawidłowy format wyjściowy, tzn. Zamienić parę liczb (x,y)w ciąg znaków "x,y".

Jak to działa:

               g(>'a')s        -- extract all lowercase letters
                     g(<'E')s  -- extract all uppercase letters
         zipWith(#)            -- combine both lists element wise with function #
                               -- # calls ! depending on the combination of c/d/C/D
                               -- ! takes 2 numbers a and b and returns a function
                               -- that takes a pair (x,y) and returns (x+a,y+b)
                               -- now we have a list of such functions
    foldr id(0,0)              -- apply those functions starting with (0,0)
init$tail$show                 -- format output                    

Edycja: @Zgarb pomógł mi zaoszczędzić 5 bajtów. Dzięki!

nimi
źródło
4

LabVIEW, 77 bajtów

wprowadź opis zdjęcia tutaj

Kod skanuje z tokenów i używa tych wskazówek, aby zdecydować, dokąd idą punkty.

Liczenie przebiega w ten sposób

Eumel
źródło
3

Python 3, 110

Zaoszczędź 5 bajtów dzięki FryAmTheEggman.
Zaoszczędzono 7 bajtów dzięki apsillerom.
Zaoszczędzono 26 bajtów dzięki DSM.

x=[[],[]]
a=b=0
for m in input():x[m<'E']+=m
for w,p in zip(*x):d=p>'C';c=w<'d';b+=d*2+c;a+=3-d-2*c
print(b,a)

Myślę, że w końcu wszystko się skończyło.

Skanuje każdy znak na wejściu i sortuje go na podstawie wielkiej litery lub nie. Następnie wykonuje pewną fantazyjną matematykę, która narusza niejawną konwersję boolonów na ints.

Morgan Thrapp
źródło
2

JavaScript (ES6), 124 118 bajtów

s=>(A=B=i=0,U=(r=x=>s.replace(/c|d/g,x))``,r(l=>U[i]&&(U[i++]<'D'?l<'d'?++A&++B:B+=3:l<'d'?A+=3:(A+=2,B+=2))),A+','+B)

Demo na żywo

(Lekko rozszerzony dla czytelności.)

var f=function (s) {
    A=B=i=0;
    U=(r=function(x){return s.replace(/c|d/g,x)})("");
    r(l=>U[i]&&(U[i++]<'D'?l<'d'?++A&++B:B+=3:l<'d'?A+=3:(A+=2,B+=2)));
    return A+','+B;
}

var input = ["cDCddDDCcCc","cccDDD","DDDDDDccc","cDcDcD","dcDDC","CcdCDDcd","Ddd","ccccccccccc"];
var output = ["9,6","9,0","9,0","9,0","5,2","6,6","2,2","0,0"];
var passed = true;

for (var index=0;index<input.length;index++) {
    if (f(input[index]) !== output[index]) passed = false;
}

document.getElementById("result").textContent = 
  passed ? "All tests passed." : "Some tests failed.";
<div id="result"></div>

Zaoszczędzono 6 bajtów dzięki user81655 .

intrepidcoder
źródło
Początkowo znałem tablice, ale ostatecznie zastosowałem inną metodę. Dzięki.
intrepidcoder,
1

Par , 49 bajtów

(lW▼·L)w▼·U))t˅y])[h7%Z2*↓″4>5*-]z2↔-″0<4*+╞)t.Σ¡

Jeden bajt jest używany na znak. Zobacz tutaj .

Wyjaśnienie

(              ## Construct array
 l             ## Read line
 W             ## Assign to w
 ▼·L)          ## Filter by immutable under lower-case
 w             ## Get w
 ▼·U)          ## Filter by immutable under upper-case
)              ## 
t              ## Transpose and truncate
˅y])           ## If empty, empty 2-D matrix
[              ## Map
 h             ## Decimal to hex
 7%            ## Modulo 7
 Z             ## Assign to z
 2*↓″4>5*-     ## Score of lower case
 ]             ## Put in array
 z2↔-″0<4*+    ## Score of upper case
 ╞             ## Add to array
)              ## 
t              ## Transpose and truncate
.Σ             ## Map - sum
¡              ## Empty array onto stack

Dane wyjściowe w formularzu 9 6.

Ypnypn
źródło
Jako ktoś, kto nigdy nie używał (ani nie słyszał) o Par, uznałem twoje wyjaśnienie za przyjemne do przeczytania. Dzięki!
apsillers
1

CJam, 92 83 81 bajtów

Skończyło się to dłużej, niż myślałem, że ...

0]K*X3tC30tG22tZ11t:L;0'a]q+{'D>}:B$_{B}%1#/z{,1>},{2<[:i:#K%L=]sY0e[{si}%}%:.+S*

Wypróbuj tutaj.

Objaśnienie (czy mogę to wyjaśnić?: O):

0]K*C3tX30tG22tZ11t:L;    e# Creates this array [0,30,0,11,0,0,0,0,0,0,0,0,3,0,0,0,22,0,0,0]
0'a]q+                    e# Creates an array that looks like [0, 'a', input string]
{'D>}:B$                  e# Sorts the array by if the int representation of each element is greater than the int value of the character 'D' (e.g. [0,C,D,a,c,d])
_{B}%1#/                  e# Finds the index of the first value in the array that is > 'D' and splits the array at that index.
z{,1>},{                  e# Zip the two sub arrays and filter for only sub arrays with more than one element. (e.g [[0,a],[C,c],[D,d]])
{2<[:i:#K%L=]s            e# For each sub array, take the first two elements, convert each to an it, calculate n=(x[0]^x[1]) mod 20, and get the nth element in the very first array, and convert it to a string
Y0e[                      e# Pad the string with 0 so it is length 2. (e.g. [["00"],["22"],["11"]])
{si}%}%:.+                e# get the numerical representation of each digit and dot sum all of them (e.g [[0,0],[2,2],[1,1] => [3,3])
S*                        e# Join with a space (e.g "3 3")
geokavel
źródło