囚徒困境v.2-大逃杀


15

这个问题中,设计了一种游戏,玩家在囚徒困境中将一对一面对面地确定彼此对立,从而确定哪种迭代策略得分最高。

这个问题中,我设计了一种方法,允许多个人同时互相对抗囚徒困境。在这种变化中,回报矩阵是不必要的,每两个参与者之间的每个结果都是两个功能独立决策的总和。

您的任务是构建一个AI来玩多人囚徒困境的对称,通用版本,以实现最高分。


游戏规则

在这种多人,多人囚徒困境的每一轮中,玩家A可以决定从其他玩家中拿1 B。在这种情况下,A的分数会增加1,而B 's的分数减少2。此决定允许在每个有序球员对之间进行。

这是每个玩家做出的唯一决定-彼此“背叛”还是不相互“捉襟见肘”,这与叛逃和合作分别相同。两名球员之间的有效收益矩阵P1P2如下所示:

  P1/P2     P1 Take1   P1 Don't
P2 Take1     -1/-1      -2/+1
P2 Don't     +1/-2       0/ 0

比赛程序

游戏将包括P * 25回合,即P参与比赛的人数。所有玩家的得分都以0。每个回合将包括以下步骤:

在回合开始时,将从标准输入中以以下格式为每个程序提供上回合的历史记录:

  • 含有3个数字一行PDN

    • P是游戏中的玩家总数。每个玩家随机分配从一个ID号1,以P在游戏的开始。

    • D 是当前玩家的ID。

    • N 是已经打过的回合数。

  • N线,每条线代表一轮的结果。在的行kN,将有一定数量n_k的有序对(a, b),用空格分隔,表示该回合中ID为a“ 1” 的玩家与ID为“ 1”的玩家b

  • R018446744073709551615(2 64-1)的均匀随机数,用作伪随机种子。这些数字将从预先生成的文件中读取,该文件将在锦标赛结束时发布,以便人们可以自己验证结果。

  • 如果您的程序在上一轮产生了这样的输出,则多一行代表要读入您的程序的某种状态。在游戏开始时,此行将始终为空。评分代码或其他程序均不会修改此行。

然后,每个程序将使用其策略来产生以下标准输出

  • K数字列表,这是本轮将“取1”的程序的ID。空输出意味着它什么也不做。

  • 可选地,一条代表某种状态形式的额外行可以传递到以后的回合。此确切行将在下一轮反馈给程序。

以下是3在4人游戏中ID 玩家游戏开始时的示例输入:

4 3 0
4696634734863777023

以下是同一游戏的示例输入,已经进行了几轮:

4 3 2
(1, 2) (1, 3) (1, 4) (4, 2)
(1, 3) (2, 1) (2, 4) (3, 1) (4, 1)
4675881156406346380

除了D每个程序唯一的ID号之外,每个程序都将获得完全相同的输入回合。

下面是一个示例输出,其中玩家3从其他所有人那里得到1:

1 2 4

在所有要求的回合结束时,最终得分最高的玩家将成为获胜者。


时间线

该比赛的编码将持续7天。提交截止日期为2014-05-09 00:00 UTC

请勿在此日期之前发布实际程序,而是发布程序源代码的SHA256哈希作为承诺。您可以在截止日期之前的任何时间更改此哈希,但是截止日期之后发布的承诺将不被接受作为判断。(请为您的哈希使用base 64表示法,因为我的验证程序会使用base 64表示法,这是一种更紧凑的表示法。)

截止日期结束后,您将有1天(直到2014-05-10 00:00 UTC)发布程序的实际源代码以进行提交。如果您发布的源代码的SHA256哈希与您在截止日期之前发布的任何哈希都不匹配,则您的代码将不被接受。

之后,我会将所有提交的内容下载到我自己的计算机上,并运行该大逃杀中的所有锦标赛条目,希望在此之后的2天内发布结果 2014-05-12 00:00 UTC

我将接受得分最高的答案,如果最终得分大于,则奖励该答案+100 0

比赛结束后,我将发布用于运行比赛的随机种子文件,人们可能会开始发布其他解决方案,以超越比赛中使用的解决方案。但是,他们将不计入接受或悬赏。

主机

我将在计算机上的虚拟机上运行这些解决方案。该虚拟机将运行带有2 GB RAM的Ubuntu Linux 14.04。我的基本计算机具有运行在3.40 GHz的Intel i7-2600K处理器。

要求

您的程序必须使用一种将用于编译程序的编译器或解释器存在的语言编写,并且该语言应可用于最新版本的Ubuntu Linux,以便我可以运行所有提交并在虚拟机中对其进行判断。

您的程序最多2.000 seconds只能运行一次。如果您的程序用完了时间或产生了错误,则该轮的输出将被视为空。

您的程序必须是确定性的;也就是说,它必须始终为相同的输入返回相同的输出。允许使用伪随机解;但是,它们的随机性必须取决于作为输入提供给它的随机种子,而不是其他任何东西。种子文件是使用Python的生成的os.urandom。它总共包含500行(如有必要,将生成更多行),其SHA256哈希为K+ics+sFq82lgiLanEnL/PABQKnn7rDAGmO48oiYxZk=。比赛结束后,它将被上传到这里。


植物

首先,将有四个“植物”,代表最初的幼稚策略。这些将与您提交的内容一起在锦标赛中播放。但是,如果其中一个获胜的可能性很小,则除植物以外的玩家获得的最高分将被视为获胜者。

要计算每个工厂文件的哈希值,请使用制表符替换每四个空格组,因为此处的格式化程序似乎不喜欢制表符。

懒惰者 -从不做任何事情。

n1bnYdeb/bNDBKASWGywTRa0Ne9hMAkal3AuVZJgovI=

pass

贪婪 –总是从其他人身上夺取 1。

+k0L8NF27b8+Xf50quRaZFFuflZhZuTCQOR5t5b0nMI=

import sys

line1 = sys.stdin.readline()
n = [int(i) for i in line1.split()]
for i in range(n[0]):
    if i+1 != n[1]:
        print i+1,
print

愤怒 –在第一轮中从其他所有人那里拿走1,在随后的上一轮中从所有人那里拿走1的所有人都拿走1。

Ya2dIv8TCh0zWzRfzUIdFKWj1DF9GXWhbq/uN7+CzrY=

import sys
import re

line1 = [int(i) for i in sys.stdin.readline().split()]

players = line1[0]
pid = line1[1]
rounds = line1[2]

lines = []

if rounds == 0:
    for i in range(players):
        if i+1 != pid:
            print i+1,
    print
else:
    for i in range(rounds):
        lines.append(sys.stdin.readline())
    lastline = lines[-1]
    takes = re.findall(r'\([0-9]+, [0-9]+\)', lastline)
    for take in takes:
        sides = [int(i) for i in re.findall(r'[0-9]+', take)]
        if sides[1] == pid:
            print sides[0],
    print

嫉妒者 -从目前得分最高的50%的玩家中减去 1(不包括自身),向下舍入。

YhLgqrz1Cm2pEcFlsiIL4b4MX9QiTxuIOBJF+wvukNk=

import sys
import re

line1 = [int(i) for i in sys.stdin.readline().split()]

players = line1[0]
pid = line1[1]
rounds = line1[2]

lines = []
scores = [0] * players

if rounds == 0:
    for i in range(players):
        if i+1 != pid:
            print i+1,
    print
else:
    for i in range(rounds):
        takes = re.findall(r'\([0-9]+, [0-9]+\)', sys.stdin.readline())
        for take in takes:
            sides = [int(i) for i in re.findall(r'[0-9]+', take)]
            scores[sides[0] - 1] += 1
            scores[sides[1] - 1] -= 2
    score_pairs = [(i+1, scores[i]) for i in range(players)]
    score_pairs.sort(key=lambda x:(x[1], x[0]))
    score_pairs.reverse()
    taken = 0
    j = 0
    while taken < (players) / 2:
        if score_pairs[j][0] != pid:
            print score_pairs[j][0],
            taken += 1
        j += 1

在这四场比赛中的100场比赛中,他们获得以下得分:

Lazy: -204
Greedy: -100
Wrathful: -199
Envious: -199

评审程序

我已经发布了我将在Github使用的判断程序。下载并进行测试。(如果发现一个或两个bug,也许可以修复。:P)

目前,除了Python之外,它没有其他编译选项。稍后我将包括这些内容-如果人们可以提供其他语言的编译或解释脚本,我将非常有义务。


阶段2:提交源代码

我已经tournament为比赛将新分支发布到Github存储库,其中包含pd_rand文件和其他工厂条目。您可以在此处发布源代码,也可以作为拉取请求将其提交到该分支。

参赛者的顺序如下:

'begrudger'
'regular'
'patient'
'lazy'
'backstab'
'bully'
'lunatic'
'envious'
'titfortat'
'greedy'
'wrathful'
'judge'
'onepercent'

最终成绩

我的测试程序的输出:

Final scores:
begrudger -2862
regular -204
patient -994
lazy -2886
backstab -1311
bully -1393
lunatic -1539
envious -2448
titfortat -985
greedy -724
wrathful -1478
judge -365
onepercent -1921

排名:

 1. regular      -204
 2. judge        -365
 3. greedy       -724
 4. titfortat    -985
 5. patient      -994
 6. backstab    -1311
 7. bully       -1393
 8. wrathful    -1478
 9. lunatic     -1539
10. onepercent  -1921
11. envious     -2448
12. begrudger   -2862
13. lazy        -2886

因此,事实证明获胜者的确是玩家-这是-204分的常规!

不幸的是,它的分数不是很高,但是我们很难在模拟“囚徒困境”的模拟中,每个人都在努力取胜。

一些令人惊讶的结果(至少我认为是令人惊讶的):

  • 贪婪者在Tat上的得分高于Tit,实际上,它总体上比大多数得分手都高。

  • 法官本来是一种“道德执法者”角色(基本上是从任何人那里以高于平均水平的次数从任何人那里获得1分的人获得了1分)最终获得了相当高的分数,而在模拟测试中,它实际上是得到相当低的分数。

和其他(我认为)并不奇怪的是:

  • 该患者比“愤怒”得分高484分。第一次合作真的很值得。

  • 百分之一的人倒下时很快就几乎没人踢。似乎只有1%的人会那样做,因为他们在游戏中拥有更多的玩家。

无论如何,既然锦标赛结束了,您可以随意发布任意数量的额外玩家,并使用评判程序与他们一起进行测试。


3
将源发布到控制程序和/或工厂会不会有任何伤害?我们知道他们在做什么,无论如何,并且我也希望能够对测试的东西,而无需编写五个额外的计划。
Geobits,2014年

2
我不明白 所有人每次都服用1是否有某种惩罚?总是取1不是最有利的吗?
2014年

1
贪婪如何不能使损害最大化?如果我们从其他牌手那里拿走,则另一位球员只能得到-1或-2,而如果我们不从另一只牌手那里得到,则另一位球员可以得到1或0。显然,从另一只牌手那里得到1可以最大程度地提高伤害。因此,贪婪永远不会输。除非您所有的对手也都贪婪,否则它几乎总是赢家。
Justhalf 2014年

1
@Trimsty当挑战第一次上升时,没有显示植物的代码。在整个编码阶段,我们看不到其他答案。选择非常明显的贪婪策略,可能完全是偶然造成的。
Geobits 2014年

2
@justhalf如果您实际上已经阅读过囚徒困境中的策略研究,那您就会知道您说的是错误的。在维基百科的文章是一个很好的起点。
JoeZ。14年

Answers:


3

常规

我为锦标赛选择的条目的版本(SHA-256:)ggeo+G2psAnLAevepmUlGIX6uqD0MbD1aQxkcys64oc=使用Joey的“ 随机吸盘 ”策略(尽管更改很小且可能不重要),该策略在上一场比赛中排名第二。不幸的是,在截止日期前3分25秒提交的更新,更有效的版本存在严重的错误,因此无法使用。尽管如此,该版本仍然相对不错。

<?php

$secretKey = '95CFE71F76CF4CD2';
$hashOutput = '';
$hashSeq = 0;
$hashIndex = 64;

function psRand($min = null, $max = null) {
    global $secretKey, $state, $hashOutput, $hashSeq, $hashIndex;
    if ($hashIndex > 56) {
        $hashOutput = hash_hmac('sha256', ++$hashSeq . ' ' . $state['rand'], $secretKey);
        $hashIndex = 0;
    }

    $num = (int)(hexdec(substr($hashOutput, $hashIndex, 8)) / 2);
    $hashIndex += 8;

    return $min === null ? $num : (int)($min + $num * ($max - $min + 1) / 2147483648);
}

$line = fgets(STDIN);
sscanf($line, "%d %d %d", $numPlayers, $myPlayerId, $roundsPlayed);
$roundsCount = 25 * $numPlayers;
$roundsRemaining = $roundsCount - $roundsPlayed - 1;

$betrayalCount = array_fill(1, $numPlayers, 0);
for ($round = 0; $round < $roundsPlayed; ++$round) {
    $line = fgets(STDIN);
    preg_match_all('/\((\d+), (\d+)\)/', $line, $matches, PREG_SET_ORDER);
    foreach ($matches as $m) {
        $defector = (int)$m[1];
        $victim = (int)$m[2];
        if ($victim === $myPlayerId) {
            ++$betrayalCount[$defector];
        }
    }
}

$hashOutput = rtrim(fgets(STDIN), "\n");
$state = unserialize(rtrim(fgets(STDIN), "\n"));
if (!$state) {
    $state = ['rand' => ''];
}

$state['rand'] = hash_hmac('sha256', $state['rand'] . $line, $secretKey);
$victims = [];

if ($roundsPlayed > 1) {
    for ($other = 1; $other <= $numPlayers; ++$other) {
        if ( $other === $myPlayerId) {
            continue;
        }

        if ($betrayalCount[$other] > 7 || psRand() % 1024 < 32 || !$roundsRemaining ) {
            $victims[] = $other;
        }
    }
}

echo implode(' ', $victims), "\n", serialize($state), "\n";

越野车的SHA-256哈希值为2hNVloFt9W7/uA5aQXg+naG9o6WNmrZzRf9VsQNTMwo=

<?php

$secretKey = '95CFE71F76CF4CD2';
$hashOutput = '';
$hashSeq = 0;
$hashIndex = 64;

function psRand($min = null, $max = null) {
    global $secretKey, $state, $hashOutput, $hashSeq, $hashIndex;
    if ($hashIndex > 56) {
        $hashOutput = hash_hmac('sha256', ++$hashSeq . ' ' . $state['rand'], $secretKey);
        $hashIndex = 0;
    }

    $num = (int)(hexdec(substr($hashOutput, $hashIndex, 8)) / 2);
    $hashIndex += 8;

    return $min === null ? $num : (int)($min + $num * ($max - $min + 1) / 2147483648);
}

$line = fgets(STDIN);
sscanf($line, "%d %d %d", $numPlayers, $myPlayerId, $roundsPlayed);
$roundsCount = 25 * $numPlayers;
$roundsRemaining = $roundsCount - $roundsPlayed - 1;

$betrayalCount = array_fill(1, $numPlayers, 0);
$scoreWindow = array_fill(1, $numPlayers, array_fill(1, $numPlayers, 0));
$lastMove = array_fill(1, $numPlayers, array_fill(1, $numPlayers, false));
for ($round = 0; $round < $roundsPlayed; ++$round) {
    $line = fgets(STDIN);
    preg_match_all('/\((\d+), (\d+)\)/', $line, $matches, PREG_SET_ORDER);
    foreach ($matches as $m) {
        $defector = (int)$m[1];
        $victim = (int)$m[2];
        if ($victim === $myPlayerId) {
            ++$betrayalCount[$defector];
        }
TAB>TAB>if ($round >= $roundsPlayed - 10) {
TAB>TAB>TAB>$scoreWindow[$defector][$victim] -= 2;
TAB>TAB>TAB>$scoreWindow[$victim][$defector] += 1;
TAB>TAB>}
TAB>TAB>if ($round === $roundsPlayed - 1) {
TAB>TAB>TAB>$lastMove[$defector][$victim] = true;
TAB>TAB>}
    }
}

$line .= fgets(STDIN);
$state = unserialize(rtrim(fgets(STDIN), "\n"));
if (!$state) {
    $state = ['rand' => '', 'copying' => array_fill(1, $numPlayers, 0)];
}

$state['rand'] = hash_hmac('sha256', $state['rand'] . $line, $secretKey);
$victims = [];

if ($roundsPlayed > 1) {
    for ($other = 1; $other <= $numPlayers; ++$other) {
        if ($other === $myPlayerId) {
            continue;
        }

TAB>TAB>if ($roundsPlayed >= 10) {
TAB>TAB>TAB>$myScore = $scoreWindow[$other][$myPlayerId];
TAB>TAB>TAB>foreach ($scoreWindow[$other] as $betterPlayer => $betterScore) {
TAB>TAB>TAB>TAB>if ($betterScore >= 0.5 * $myScore && !psRand(0, $betterPlayer)) {
TAB>TAB>TAB>TAB>TAB>$state['copying'][$other] = $betterPlayer;
TAB>TAB>TAB>TAB>}
TAB>TAB>TAB>}
TAB>TAB>}

TAB>TAB>if ($state['copying'][$other]) {
TAB>TAB>TAB>if ($lastMove[$state['copying'][$other]][$other]) {
TAB>TAB>TAB>TAB>$victims[] = $other;
TAB>TAB>TAB>}
        } elseif ($betrayalCount[$other] > 7 || psRand() % 1024 < 32 || !$roundsRemaining ) {
            $victims[] = $other;
        }
    }
}

echo implode(' ', $victims), "\n", serialize($state), "\n";

要修复它,请进行以下替换:

  • 替换$hashOutput = rtrim(fgets(STDIN), "\n");$line .= fgets(STDIN);(不是真的很重要)。
  • 替换if ($betterScore >= 3 * $myScore) {if ($betterScore >= 0.5 * $myScore && !psRand(0, $betterPlayer)) {(这是杀死它的原因)。

1
截止日期前3分25秒。我印象深刻
JoeZ。14年

温馨提示:编码阶段已经结束;您有一天要发布源代码。(过程在问题的底部。)
Joe Z.

不管我使用的是旧版本还是新版本,您的程序始终排在第一位。恭喜你!
Joe Z.

2

百分之一

b61189399ae9494b333df8a71e36039f64f1d2932b838d354c688593d8f09477

瞧不起他认为在他身下的那些囚犯。


简单地从所有得分小于或等于他自己的人那里获取。假设是那些囚犯获得回报的可能性较小(或者他们会有更多)。我不知道这样的假设有多,但这就是他所依据的。

在最后一轮比赛中,所有人也都需要参加。从字面上看,这没有缺点,因为在那之后没有人可以报仇。

如果由于粘贴的代码中的制表符/空格而导致获取哈希值时遇到问题,这里是指向文件本身的链接。

import java.io.BufferedReader;
import java.io.InputStreamReader;

class OnePercent {

    static int numPlayers;
    static int me;
    static int turn;
    static int[] values;

    public static void main(String[] args) {
        if(!readInput())
            return;
        String out = "";
        for(int i=1;i<values.length;i++){
            if(i != me && (values[i] <= values[me] || turn > (numPlayers*25-2)))
                out += i + " ";
        }
        out.trim();
        System.out.print(out);
    }

    static boolean readInput(){
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String line = reader.readLine();
            if(line == null)
                return false;
            String[] tokens = line.split(" ");
            if(tokens.length < 3)
                return false;
            numPlayers = Integer.valueOf(tokens[0]);
            me = Integer.valueOf(tokens[1]);
            turn = Integer.valueOf(tokens[2]);
            values = new int[numPlayers+1];
            for(int i=0;i<values.length;i++)
                values[i]=0;

            for(int i=0;i<turn;i++){
                line = reader.readLine();
                line = line.replaceAll("[)]",",");
                line = line.replaceAll("[( ]", "");
                tokens = line.split(",");
                for(int j=0;j<tokens.length-1;j+=2){
                    int thief = Integer.valueOf(tokens[j]);
                    int poor = Integer.valueOf(tokens[j+1]);
                    if(thief<1||poor<1||thief>numPlayers||poor>numPlayers)
                        continue;
                    values[thief]++;
                    values[poor] -= 2;
                }
            }
            reader.close();
        } catch(Exception e) {
            return false;
        }
        return true;
    }

}

请记住,你们可以在05-09 00:00截止日期之前继续改进您的解决方案。
乔Z.

是的 如果我有其他想法,我会的。不过,我很难相信任何人都会声称那笔赏金。在这场比赛中取得积极的成绩将是……不寻常的。
Geobits,2014年

是的,我不期望任何人能真正实现这一目标。确实,这将是一个无与伦比的游戏理论成就,可能值得在研究方面投入真金白银(一种比两个人总是合作更好的解决方案!想象一下!),而不是在Stack Exchange上仅有100个声誉。
乔·Z。2014年

1
@JoeZ。有了其他人会做的事情,可以肯定;)对于未知条目,我看不到非常可靠的策略。我猜,离群值将是离群值。
Geobits,2014年

1
我想这一次我仍然会接受,因为您的代码策略似乎没有什么恶意,而且进入者也很少,因此不管如何。
乔Z。14年

1

这里还有更多将要参加比赛的植物。这些代码更高级,它们的源代码要到编码阶段结束时才会公开。

就像问题中的四个植物一样,如果它们的得分高于所有其他球员,则只有实际参赛者获得的最高分数才被视为获胜者。


恶霸

29AGVpvJmDEDI5Efe/afmMJRLaJ+TpjwVcz1GkxgYZs=

挑人。


法官

yjdCQ3uQ4YKe7xAKxdTFLF4d72fD4ACYpDLwkbzdISI=

惩治不法分子。


疯子

m3FsRPocekCcK6GDswgnobV2CYOxX8LquChnKxrx1Wo=

不知道是什么它做。


患者

nd7Pt3bVpFnuvDVeHQ5T9EPTq7KjNraVzp/KGtI73Vo=

永远不要迈出第一步。


如果这些只是植物,我认为没有理由不允许它们。如果他们是可以赢得比赛的选手,那么我认为,根据以上评论
Geobits,2014年

认为有自己的条目我一下然后决定是完全是一种不公平的命题,甚至如果我只输入了一个多,因为比赛太多其他元素都是我的控制之下。因此,我在此处输入的所有内容都只是植物。
JoeZ。14年

我认为人们可能甚至不希望像植物一样想要它们,这是因为它代表了游戏开始时没有的可用基础玩家(因而是基础策略)中的相当大的变化。但是,如果我们假设解决方案应该编码为最佳,而不考虑插入植物的玩家,那么我想我也可以输入它们。
Joe Z.

好吧,无论涉及哪个参与者,都应将条目编码为“最佳”(如果此处存在),仅仅是因为我们仍然看不到其他答案。这些是植物还是程序的其他答案,没有区别,除了这些不能“赢”。假设获胜者被定义为得分最高的非工厂,我不认为这有多重要。我说让他们进来。
Geobits

1

针锋相对

9GkjtTDD2jrnMYg/LSs2osiVWxDDoSOgLCpWvuqVmSM=

与“愤怒”类似,但有一些(希望如此)提高性能的更改。

import sys
import re

line1 = [int(i) for i in sys.stdin.readline().split()]

players = line1[0]
pid = line1[1]
rounds = line1[2]

lines = []

if rounds == 0:
    print
elif rounds == 25 * players - 1:
    for i in range(players):
        if i+1 != pid:
            print i+1,
    print
else:
    for i in range(rounds):
        lines.append(sys.stdin.readline())
    lastline = lines[-1]
    takes = re.findall(r'\([0-9]+, [0-9]+\)', lastline)
    for take in takes:
        sides = [int(i) for i in re.findall(r'[0-9]+', take)]
        if sides[1] == pid:
            print sides[0],
    print

您收到我的电子邮件地址了吗?
Joe Z. 2014年

@乔; 是; 谢谢。(我不确定我是否需要它,但感谢您的包容。)
Ypnypn 2014年

好吧,我只是想知道,所以我可以删除它。
乔Z.

1
@luserdroog人们正在发布其程序源代码的哈希值,而不是程序本身。一旦可以编写7天的代码,人们就会展示他们的实际程序进行测试。
乔Z.14年

1
对,是真的。提交内容可能应该有标题和至少一个像Geobits这样的标语。
乔Z.14年

1

背刺

Python 3

尽管有这个名字,这个机器人实际上还是很客气的。但是不要打勾。

import sys, math

inp = [int(i) for i in sys.stdin.readline().split()]
inp.append([])
for i in range(inp[2]):
    inp[3].append(
        [eval(i+')') for i in sys.stdin.readline().split(')')[:-1]]
    )
inp += sys.stdin.readline()

# inp is [P, D, N, [M1, M2...], R]

dat = [[], inp[2] % 2] # average runlength take and don't per player, parity of round

lastatk = []

for i in range(inp[0]):
    dat[0].append([])
    lastatk.append(0)

for i,r in enumerate(inp[3]): # each round
    for m in r: # each move
        if m[1] == inp[1]:
            dat[0][m[0]-1].append(i) # round num they attacked
            lastatk[m[0]-1] = i # keep track of last attack

# now that we know who attacked me when, i can do some stats

nav = []
rl = []

for i in range(inp[0]):
    nav.append([[0], False])
    rl.append([[], []]) # attack, don't

for i in range(inp[2]): # each round
    for p in range(1, inp[0]+1): # each player
        if p != inp[1]: # let's not judge ourselves
            if i in dat[0][p-1]: # p attacked me in round i
                if nav[p-1][1]: # attack chain?
                    nav[p-1][0][-1] += 1
                else: # start attack chain!
                    rl[p-1][1] += [nav[p-1][0][-1]] # copy peace chain
                    nav[p-1][0].append(1)
                    nav[p-1][1] = True
            else: # peace!
                if not nav[p-1][1]: # peace chain?
                    nav[p-1][0][-1] += 1
                else: # peace to all!
                    rl[p-1][0] += [nav[p-1][0][-1]] # copy atk chain
                    nav[p-1][0].append(1)
                    nav[p-1][1] = False

print(nav)

print(inp[3])

# now, rl has runlengths for each player.

print(rl)

rl = [[sum(i[0])/len(i[0]+[0]), sum(i[1])/len(i[1]+[0])] for i in rl]

# rl now contains the averages w/ added zero.

# So, now we have average runtime and last attack. Let's quickly make some descisions.

out = []

for p in range(1, inp[0]+1): # each player
    if p != inp[1]: # again, let's not judge ourselves
        if lastatk[p-1] == inp[0]-1: # they attacked us!
            out.append(p)
        else: # whew, we can recover
            if inp[0] - lastatk[p-1] > rl[p-1][0]: # they're due to defend!
                out.append(p)
            elif int(__import__('binascii').b2a_hex(inp[-1].encode()), 16) % 4 == 0: # 1 in 4 chance of doing this
                out.append(p) # backstab!!1!!1one!!!1!!

print(*out)

编辑2:发布源。好极了。

编辑:经过一些测试,我修复了一些发现的缺陷。它们不是算法,只是读取输入时的一些问题。


温馨提示:编码阶段已经结束;您有一天要发布源代码。(过程在问题的底部。)
Joe Z.

@JoeZ。发表。我希望我能及时。:P
cjfaure 2014年

P,D,N,R听起来就像汽车可以行驶的驱动器。
JoeZ。14年

1
@JoeZ。xD他们来自您的帖子,所以; 3
cjfaure

哦,我的坏。对不起:S
乔Z.

1

Begrudger

g1TXBu2EfVz/uM/RS24VeJuYMKLOaRatLxsA+DN1Mto=

我承认我没有花太多时间在这上面...

import sys
p, d, n, o = input().split(' ') + ['']
p, d, n = int(p), int(d), int(n)
for i in range(n):
    r = input()
    r = r[1:len(r)-1].split(') (')
    for a in r:
        if int(a.split(', ')[1]) == d and not a.split(', ')[0] in o:
            o += a.split(', ')[0] + " "

input()
print(o)

温馨提示:编码阶段已经结束;您有一天要发布源代码。(过程在问题的底部。)
Joe Z. 2014年

我试图运行它并遇到以下错误:o += a.split(', ')[0]数字之间不要留空格。
2014年

@PleaseStand我已修复此问题,但我认为经过测试的版本最终会出现bug,因为竞争已经结束。
kitcar2000 2014年

是的,每当我运行它时,您的代码都会产生一个错误,而且我不知道该如何解决。不过,它的表现比The Lazy稍好。
JoeZ。14年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.