죄수의 딜레마 v.2-배틀 로얄


15

에서 이 질문에 , 게임은 플레이어가, 죄수의 딜레마에서 쌍 쌍 떨어져 서로 마주 것이 다른 사람에 대한 가장 높은 점수 반복하는 전략 결정하는 고안되었다.

에서 이 질문에 , 나는 여러 사람이 모두 같은 시간에 서로 죄수의 딜레마를 재생할 수있는 방법을 고안했다. 이 변형에서, 지불 행렬은 불필요하며, 두 플레이어의 각 쌍 사이의 각 결과는 기능적으로 독립적 인 두 가지 결정의 합이다.

당신의 임무는 가능한 한 가장 높은 점수를 얻을 수있는 멀티 플레이어 죄수의 딜레마의 대칭, 일반화 버전을 재생하기 위해 AI를 구축하는 것입니다.


게임의 규칙

이 멀티 플레이어, 멀티 라운드 포로의 딜레마의 각 라운드에서 플레이어 A는 다른 플레이어로부터 "1을 가져 오기"로 결정할 수 있습니다 B. 이 상황에서 A의 점수는 1 씩 증가하고 B점수는 2만큼 감소합니다.이 결정은 각 주문한 플레이어 쌍간에 이루어질 수 있습니다.

이는 각 선수에 대해 유일하게 내려진 결정입니다. 각 선수는 "1 명을 취하거나"1 명을 취하지 않기로 결정합니다. 이는 각각 탈퇴 및 협력과 상동입니다. 두 선수 사이의 효과적인 보수 매트릭스 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 개 숫자를 포함 한 라인, P, D,와 N.

    • P게임의 총 플레이어 수입니다. 각 플레이어는 무작위에서 ID 번호를 할당 1하는 P게임의 시작 부분에.

    • D 현재 플레이어의 ID입니다.

    • N 플레이 한 라운드 수입니다.

  • N각 라인은 라운드의 결과를 나타냅니다. 행에서 kN일부 수있을 것이다 n_k순서쌍의 (a, b)ID와 플레이어가 나타내는 공간으로 구분 aID와 플레이어에서 "1했다" b그 라운드.

  • 균일 한 난수 R018446744073709551615(2 64 - 1의), 의사 랜덤 씨드로서 작용한다. 이 숫자는 미리 생성 된 파일에서 읽히고 토너먼트 종료시 공개되어 사람들이 결과를 확인할 수 있습니다.

  • 프로그램이 이전 라운드에서 이러한 출력을 생성 한 경우 프로그램에 읽을 상태의 형태를 나타내는 하나의 추가 행. 게임이 시작될 때이 줄은 항상 비어 있습니다. 이 줄은 점수 코드 또는 다른 프로그램에 의해 수정되지 않습니다.

각 프로그램은 전략을 사용하여 다음 을 표준 출력 으로 생성합니다 .

  • K이 라운드에서 "1"을받는 프로그램의 ID 인 숫자 목록 . 빈 출력은 아무 것도 수행하지 않음을 의미합니다.

  • 선택적으로, 다음 라운드로 넘어 가기 위해 어떤 형태의 상태를 나타내는 하나의 추가 라인. 이 정확한 라인은 다음 라운드에서 프로그램으로 피드백됩니다.

아래는 34 인용 게임에서 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 해시를 확약으로 게시하십시오. 마감일 전에 언제든지이 해시를 변경할 수 있지만 마감일 이후에 게시 된 약속은 판단을 위해 수락되지 않습니다. (내 검증 프로그램이베이스 64를 뱉어 내고보다 컴팩트 한 표기법이므로 해시에 기본 64 표기법을 사용하십시오.)

마감일이 끝나면, 2014-05-10 00:00 UTC제출할 프로그램의 실제 소스 코드를 게시하는 데 1 일이 걸립니다. 게시 된 소스 코드의 SHA256 해시가 마감일 전에 게시 한 해시와 일치하지 않으면 토너먼트에 코드가 적용되지 않습니다.

그런 다음 모든 제출물을 내 컴퓨터에 다운로드하고이 배틀 로얄에서 모든 토너먼트 참가작을 실행하여 2 일 이내에 결과를 게시 할 예정 2014-05-12 00:00 UTC입니다.

최고 점수를받은 답변을 수락하고 최종 점수가보다 큰 경우 해당 답변에 +100의 현상금을 부여합니다 0.

토너먼트가 끝나면 경쟁을 진행하는 데 사용되는 임의의 시드 파일을 게시하고 사람들은 토너먼트에 사용 된 솔루션보다 상위에있는 다른 솔루션을 게시하기 시작할 수 있습니다. 그러나 그들은 수락 또는 현상금으로 계산되지 않습니다.

호스트 머신

이 솔루션을 내 컴퓨터의 가상 머신에서 실행할 것입니다. 이 가상 머신은 2GB의 RAM으로 Ubuntu Linux 14.04를 실행합니다. 기본 시스템에는 3.40GHz에서 실행되는 Intel i7-2600K 프로세서가 있습니다.

요구 사항

귀하의 프로그램은 귀하의 프로그램을 컴파일 할 컴파일러 또는 인터프리터가 존재하는 언어로 작성되어야하며 최신 버전의 Ubuntu Linux에서 즉시 사용할 수 있으므로 모든 제출물을 실행하고 가상 머신에서 판단 할 수 있습니다.

귀하의 프로그램은 2.000 seconds각 라운드를 실행하는 것 이상 을 가져서는 안됩니다 . 프로그램이 시간이 없거나 오류를 생성하면 해당 라운드에서 출력이 비어있는 것으로 간주됩니다.

프로그램은 결정 론적이어야합니다. 즉, 항상 동일한 입력에 대해 동일한 출력을 반환해야합니다. 의사 랜덤 솔루션이 허용됩니다. 그러나 그 무작위성은 입력으로 주어진 무작위 시드에 의존해야하며 다른 것은 없습니다. 시드 파일은 Python을 사용하여 생성되었습니다 os.urandom. 총 500 줄이 포함되어 있으며 필요한 경우 더 생성됩니다 K+ics+sFq82lgiLanEnL/PABQKnn7rDAGmO48oiYxZk=. SHA256 해시는 입니다. 토너먼트가 끝나면 여기에 업로드됩니다.


식물

일을 시작하기 위해 초기 순진 전략을 나타내는 4 개의 "식물"이있을 것입니다. 이들은 귀하의 제출물과 함께 토너먼트에서 진행됩니다. 그러나, 그들 중 하나가 이길 가능성이없는 경우, 식물 이외의 플레이어가 얻은 최고 점수가 승자로 간주됩니다.

각 플랜트 파일의 해시를 계산하려면 여기에서 포맷터가 탭 문자를 좋아하지 않기 때문에 4 개의 공백 그룹을 모두 탭으로 바꿉니다.

게으른 — 아무것도하지 않습니다.

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

이 4 개의 라운드 중 100 라운드 토너먼트에서 다음과 같은 점수를받습니다.

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

심사 프로그램

Github에 사용할 판사 프로그램을 게시했습니다 . 다운로드하여 테스트하십시오. (그리고 하나를 찾으면 버그를 수정하십시오. : P)

현재 파이썬 이외의 다른 컴파일 옵션이 없습니다. 나는 나중에 그것들을 포함시킬 것이다. 만약 사람들이 다른 언어에 대한 편집이나 해석 스크립트를 제공 할 수 있다면, 나는 많은 의무를지게 될 것이다.


2 단계 : 소스 코드 제출

tournamentpd_rand 파일 및 기타 플랜트 항목이 포함 된 컨테스트의 Github 저장소에 새 브랜치 를 게시했습니다 . 소스 코드를 여기에 게시하거나 풀 요청으로 해당 지점에 제출할 수 있습니다.

참가자의 순서는 다음과 같습니다.

'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 포인트로 The Regular입니다!

불행히도 그 점수는 긍정적이지 않았지만, 모두가 승리하기 위해 반복되는 죄수의 딜레마 시뮬레이션에서 거의 기대할 수 없습니다.

몇 가지 놀라운 결과 (적어도 놀랍다 고 생각했습니다) :

  • Greedy는 Tat의 Tit보다 더 많은 점수를 받았고 실제로 대부분의 득점자보다 일반적으로 더 높습니다.

  • 일종의 "도덕적 집행자"캐릭터로 여겨지는 판사 (기본적으로 평균 이상의 횟수에서 1 명을 얻은 사람 중 1 명을 가져간 사람)는 다소 높은 점수를 얻었습니다. 시뮬레이션 테스트에서는 실제로 다소 낮은 점수를 얻습니다.

그리고 다른 사람들은 (놀랐습니다) 놀라지 않았습니다.

  • 환자는 진노보다 484 점을 더 많이 기록했습니다. 처음으로 협력하는 것은 정말 대가입니다.

  • 한 퍼센트는 그들이 쓰러 졌을 때 거의 아무도 쫓아 낼 수 없었습니다. 1 %는 게임에 더 많은 선수가 있기 때문에 그런 식으로 만 머무를 수 있습니다.

어쨌든 토너먼트가 끝나면 원하는만큼의 추가 플레이어를 자유롭게 게시하고 판사 프로그램을 사용하여 주변을 테스트하십시오.


3
제어 프로그램 및 / 또는 플랜트에 소스를 게시하면 문제가 발생합니까? 우리는 그들이 무엇을하는지 알고 있으며, 5 개의 추가 프로그램을 작성하지 않고도 무언가 에 대해 테스트하는 것을 선호 합니다.
Geobits

2
이해가 안 돼요 항상 1을 복용하는 모든 사람들에게 어떤 형벌이 있습니까? 항상 1을 취하는 것이 가장 유리하지 않습니까?
DankMemes 3

1
욕심은 어떻게 피해를 극대화하지 못할 수 있습니까? 우리가 다른 플레이어로부터 가져 가면 다른 플레이어는 -1 또는 -2 만 얻을 수 있지만, 그렇지 않으면 다른 플레이어는 1 또는 0을 얻을 수 있습니다. 분명히 다른 플레이어에서 1을 가져 가면 피해가 극대화됩니다. 그래서 탐욕은 결코 잃지 않을 것입니다. 그리고 당신이 말한 것처럼 모든 상대가 욕심이 없다면 거의 항상 이길 것입니다.
justhalf

1
@Trimsty 도전이 처음 시작되었을 때 식물의 코드는 표시되지 않았습니다. 전체 코딩 단계를 통해 다른 답변을 볼 수 없었습니다. 속는는 선택하여 사고로 순수하게 일어날 수있는 매우 분명 욕심 전략을.
Geobits

2
@justhalf 반복 된 죄수의 딜레마에있는 전략에 대한 재구성을 실제로 읽었다면, 당신이 말하는 것이 틀렸다는 것을 알게 될 것입니다. 위키 백과 문서는 시작하기에 좋은 장소입니다.
Joe Z.

답변:


3

레귤러

나는 대회 (SHA-256 :에 대해 선택한이 항목의 버전 ggeo+G2psAnLAevepmUlGIX6uqD0MbD1aQxkcys64oc=)를 사용 조이 의 " 임의 빠는 마지막 대회에서 2 위를했다 (작은 가능성 사소한 변화이기는하지만)"전략을. 불행히도, 더 새롭고 더 효과적인 버전은 마감 시간이 심각한 버그를 갖기 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 초 전에 나는 감동.
Joe Z.

친숙한 알림 : 코딩 단계가 끝났습니다. 소스 코드를 게시 할 하루가 있습니다. (절차는 문제의 맨 아래에 있습니다.)
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마감일 까지 솔루션을 계속 개선 할 수 있습니다 .
Joe Z.

네. 다른 것을 생각하면 나는 할 것이다. 그래도 누군가가 그 현상금을 주장 할 것이라고 믿기 힘들다. 이 게임에서 긍정적 인 반응은 ... 이례적인 일입니다.
Geobits

그래, 나는 누군가가 실제로 그 현상금에 도달하기를 기대하지 않습니다. 스택 익스체인지에 대한 100의 명성 대신 연구 가능성 (두 사람보다 항상 잘 작동하는 솔루션!
Joe Z.

1
@JoeZ. 다른 사람이 있는지, 어떻게 할 것인지의 지식을) 알 수없는 항목에 대하여, 나는 아주 볼 수 신뢰할 수있는 전략을. 이상 값은 이상 값일 것입니다.
Geobits

1
귀하의 코드 전략은 악의적 인 것으로 보이지 않으며 어쨌든 문제가 될 참가자가 너무 적기 때문에 이번에는 여전히 받아 들일 것이라고 생각합니다.
Joe Z.

1

게임에 참여할 식물이 몇 가지 더 있습니다. 이것들은 더 발전되어 있으며 코딩 단계가 끝날 때까지 소스 코드가 공개되지 않습니다.

문제의 네 가지 식물과 마찬가지로 다른 모든 플레이어보다 높은 점수를 얻는 경우 실제 참가자가 달성 한 최고 점수 만 승자로 간주됩니다.


깡패

29AGVpvJmDEDI5Efe/afmMJRLaJ+TpjwVcz1GkxgYZs=

사람들을 선택합니다.


판사

yjdCQ3uQ4YKe7xAKxdTFLF4d72fD4ACYpDLwkbzdISI=

잘못을 저지른다.


루나틱

m3FsRPocekCcK6GDswgnobV2CYOxX8LquChnKxrx1Wo=

그것이 무엇을 하고 있는지 전혀 모른다 .


환자

nd7Pt3bVpFnuvDVeHQ5T9EPTq7KjNraVzp/KGtI73Vo=

처음으로 움직이지 마십시오.


이것들이 단지 식물 이라면 , 나는 그들을 허용하지 않을 이유가 없다. 그들이 이길 수있는 참가자라면 ,
Geobits

내 자신의 항목을 가지고 생각 나는 짧게, 그조차 모두 불공정 한 제안을 있다고 결정 하면 게임의 너무 많은 다른 요소가 내 통제하에 있기 때문에 나는 단지 더 많은 일을 입력했습니다. 제가 여기에 넣은 모든 항목은 식물 일뿐입니다.
Joe Z.

내가 사람들이 식물로도 원치 않았을 것이라고 생각한 이유는 게임 초반에는 사용할 수 없었던 기본 플레이어 (그리고 기본 전략)에서 근본적인 변화를 나타 내기 때문입니다. 그러나 플랜트로 삽입 된 플레이어에 관계없이 솔루션을 최적으로 코딩해야한다는 가정하에 솔루션을 입력 할 수 있다고 가정합니다.
Joe Z.

글쎄, 참가자는 단순히 다른 답변을 볼 수 없기 때문에 관련 플레이어와 상관없이 "최적"(여기에 존재하는 경우)으로 코딩해야합니다. 이것들이 "승리"할 수 없다는 것을 제외하고는 이것들이 프로그램에 대한 식물이나 다른 대답이라면 아무런 차이가 없습니다. 우승자가 가장 높은 점수를 가진 비 식물로 정의되었다고 가정하면, 그것이 얼마나 중요한지 알 수 없습니다. 내가 그들을 들여 말한다.
Geobits

1

가슴을위한 가슴

9GkjtTDD2jrnMYg/LSs2osiVWxDDoSOgLCpWvuqVmSM=

Wrathful과 유사하며 성능을 향상시키는 몇 가지 변경 사항이 있습니다.

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.

@ 조; 예; 감사. (필요하지는 않지만 수용 해 주셔서 감사합니다.)
Ypnypn

알았어요. 삭제하고 싶었습니다.
Joe Z.

1
@luserdroog 사람들은 프로그램 자체 대신 프로그램 소스 코드의 해시를 게시하고 있습니다. 코드 작성 7 일이 지나면 사람들은 테스트 할 실제 프로그램을 공개합니다.
Joe Z.

1
그래, 그건 사실이야. 제출물에는 아마도 제목과 최소한 Geobits와 같은 태그 라인이 있어야합니다.
Joe Z.

1

백스탭

파이썬 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

P, D, N, R은 자동차가 이동할 수있는 드라이브처럼 들립니다.
Joe Z.

1
@JoeZ. xD 게시물에서
왔으므로

오, 나빠 죄송합니다 : S
Joe 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.

나는 이것을 실행하려고 시도하고 다음 버그에 부딪쳤다 : o += a.split(', ')[0]숫자 사이에 공백을 두지 마십시오.
Please Standand

@PleaseStand 나는 그것을 고쳤지만 경쟁이 끝나기 때문에 테스트 된 버전이 버그로 끝날 것이라고 생각합니다.
kitcar2000

예, 코드를 실행할 때마다 버그가 발생하여 문제를 해결하는 방법을 알 수 없었습니다. 그래도 The Lazy보다 약간 나았습니다.
Joe Z.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.