非同期の囚人のジレンマゲームを記録する


15

囚人のジレンマエクササイズラウンドでは、2人のプレイヤーがそれぞれ、そのラウンドに協力するか、または敗走するかを決定します。ラウンドの得点は次のとおりです。

  • プレーヤーAとプレーヤーBの両方が協力:両方に対して1ポイント
  • プレーヤーAとプレーヤーBの両方の欠陥:両方とも2ポイント
  • プレイヤAの協働とプレイヤB不良:3点プレイヤーAの協働および0点プレイヤーBを逃走するための

ただし、戦略について心配する必要はありません。プログラムは単にゲームのスコアを集計するだけです。(あなたがすでに囚人のジレンマに精通している場合、ここでの私の「ポイント」は「刑務所での年」に対応します。)

あなたの課題は、数ラウンドにわたるプレイヤーの選択を表す入力を取得し、それぞれの合計スコアを計算することです。一人のプレイヤーの提出小文字での選択肢、cおよびd(のための協力欠陥)、およびその他の提出の選択肢大文字で、CD。これらの選択肢は文字列としてプログラムに提供されます。

通常、囚人のジレンマに陥っているプレイヤーは、動きを同時に、繰り返し送信します。ただし、このチャレンジでは、プレーヤーは一度に複数のラウンドの選択肢を提出した可能性があります。プレーヤーの動きが順不同の場合、スコアリングプログラムはそれを記憶し、それを相手プレーヤーから次に利用可能な動きと照合します。

入力文字列のサンプルは次のとおりです。

cDCddDDCcCc

この入力に存在する一致を表示するには、小文字と大文字を別々に呼び出して、それらをペアにします。

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

これらはラウンドにペアリングされます:

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)

スコア9(小文字)から6(大文字)を生成するため、出力は9,6(または明確な区切り文字)になります。

さらに別の方法で表現するために、それぞれのペアが独自の行に引き出されています。

cDCddDDCcCc
cD
  Cd
    dD
      D c
       C  c

C大文字のプレーヤーが小文字のプレーヤーよりも多くの動きを送信したため、一致しないものが1つあります。それは許容範囲であり、スコアリングの目的では完全に無視されます。

要件は次のとおりです。

  • /[cdCD]+/何らかの入力メカニズム(STDIN、関数引数、ファイルからの読み取りなど)を介して、正規表現形式の文字列を受け入れるプログラムまたは関数を作成する必要があります。(オプションで、プログラムは末尾の改行で入力を受け入れる場合があります。)

  • プログラムまたは関数は、プレーヤーのスコアを文字列として出力または返す必要があります。出力形式は、小文字のプレーヤーのスコアで始まり、その後に大文字のプレーヤーのスコアが続き、選択した任意の空でない非数値の区切り文字で区切られている必要があります。(末尾の改行はオプションです。)

  • 一方のプレイヤーが他方のプレイヤーよりも多くの動きを持っている場合、余分な動きは無視されます。

  • 入力のすべての動きが1人のプレイヤーのみからのものである場合(つまり、ラウンドがまったくプレイされていない場合)、各プレイヤーのスコアは0です。

  • バイト単位の最小の提出が勝ちです。

テストケース

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

彼らは通常、協力のために2ポイントを得て、両方の欠陥がある場合1ポイントを失いますか?
ユーメル

1
@Eumel Wikipediaの概要から仕様をコピーしましたが、これは元の著者によって提案された定式化を使用しているようです。また、ここでのポイントは、刑務所での年数に対応するため、「悪い」ことに注意してください。勝者は、ポイントが最も少ないプレーヤーです。
-apsillers

である(0,0)か、[0,0]出力のためにOK?
xnor

回答:


3

Pyth、23バイト

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

テストスイート


説明:

@Gz: 小文字

-zG: 大文字

C,:ペア、残りを切り捨てます。

`:ペアのリストの文字列表現を取得します

/L ... "cDDCdd:の各文字について"cDDCdd"、上記の文字列reprに出現する回数をカウントします。

c2:結果のリストを半分に切り取ります。

sM:各半分を合計します。

j:改行に参加して印刷します。


`sの代わりに使用して、一方のパーティが動作しないというケースを作成する必要があります。


5

Haskell、139 134バイト

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

使用例:f "cDCddDDCcCc"-> "9,6"

出力形式を正しくするためだけに15バイト。つまり、数値のペアを(x,y)文字列に変換します"x,y"

使い方:

               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                    

編集:@Zgarbは5バイトの節約に役立ちました。ありがとう!


4

LabVIEW、77バイト

ここに画像の説明を入力してください

コードはトークンからスキャンし、それらのインデックスを使用してポイントの行き先を決定します。

カウントはこのようになります


3

Python 3、110

FryAmTheEggmanのおかげで5バイト節約されました。
apsillerのおかげで7バイト節約されました。
DSMのおかげで26バイト節約されました。

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)

ついにすべてゴルフアウトされたと思います。

入力の各文字をスキャンし、大文字かどうかに基づいてソートします。次に、Pythonのboolsからintへの暗黙的な変換を乱用する派手な計算を行います。


2

JavaScriptの(ES6)、124の 118バイト

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)

ライブデモ

(読みやすくするために少し拡大しました。)

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>

user81655のおかげで6バイト節約されました


もともと配列内包表記がありましたが、別の方法を使用することになりました。ありがとう。
intrepidcoder

1

パー、49バイト

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

1文字につき1バイトが使用されます。こちらをご覧ください

説明

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

フォームでの出力9 6


パーを使用したことのない(または聞いたことがない)誰かとして、私はあなたの説明を読むのが楽しいと感じました。ありがとう!
-apsillers

1

CJam、92 83 81バイト

これは思ったよりも長くなってしまいました...

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

ここで試してみてください。

説明(これを説明しますか?: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")
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.