Dilemma tù nhân v.2 - Battle Royale


15

Trong câu hỏi này , một trò chơi đã được nghĩ ra trong đó người chơi sẽ đối đầu với nhau theo từng cặp trong Thế lưỡng nan của tù nhân, để xác định chiến lược lặp nào đạt điểm cao nhất so với những người khác.

Trong câu hỏi này , tôi đã nghĩ ra một cách để nhiều người chơi tiến thoái lưỡng nan của tù nhân đối với nhau cùng một lúc. Trong biến thể này, ma trận xuất chi là không cần thiết, với mỗi kết quả giữa mỗi cặp hai người chơi là tổng của hai quyết định độc lập về chức năng.

Nhiệm vụ của bạn là xây dựng một AI để chơi phiên bản tổng quát, đối xứng này của Dilemma nhiều người chơi sẽ đạt được số điểm cao nhất có thể.


Nội quy của trò chơi

Trong mỗi vòng của trò chơi Dilemma nhiều người chơi, nhiều vòng này, một người chơi Acó thể quyết định "lấy 1" từ một số người chơi khác B. Trong trường hợp này, Ađiểm của tăng thêm 1, trong khi Bđiểm của giảm xuống 2. Quyết định này được cho phép xảy ra giữa mỗi cặp người chơi được đặt hàng.

Đây là quyết định duy nhất được đưa ra cho mỗi người chơi - có thể "lấy 1" hoặc không "lấy 1" từ mỗi người chơi khác, tương đồng với sự đào tẩu và hợp tác tương ứng. Ma trận xuất chi hiệu quả giữa hai người chơi P1P2trông như sau:

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

Thủ tục thi đấu

Trò chơi sẽ bao gồm các P * 25vòng, trong đó Psố lượng người chơi tham gia. Tất cả người chơi bắt đầu với một số điểm 0. Mỗi vòng sẽ bao gồm các thủ tục sau đây:

Khi bắt đầu một vòng, mỗi chương trình sẽ được cung cấp lịch sử của các vòng trước từ đầu vào tiêu chuẩn , theo định dạng sau:

  • Một dòng chứa 3 số, P, D, và N.

    • Plà tổng số người chơi trong trò chơi. Mỗi người chơi được chỉ định ngẫu nhiên một số ID từ 1đến Pđầu trò chơi.

    • D là ID của người chơi hiện tại.

    • N là số vòng đã được chơi.

  • Ndòng, mỗi dòng đại diện cho kết quả của một vòng. On line kcủa N, sẽ có một số số n_kcủa cặp có thứ tự (a, b), cách nhau bằng khoảng trắng, trong đó tuyên bố rằng máy nghe nhạc với ID a"mất 1" từ máy nghe nhạc với ID btrong vòng đó.

  • Một số ngẫu nhiên thống nhất Rtừ 0đến 18446744073709551615(2 64 - 1), để hoạt động như một hạt giống giả. Những con số này sẽ được đọc từ một tập tin được tạo trước, sẽ được phát hành vào cuối giải đấu để mọi người có thể tự xác minh kết quả.

  • Một dòng bổ sung đại diện cho một số dạng trạng thái được đọc vào chương trình của bạn, nếu chương trình của bạn tạo ra đầu ra như vậy trong vòng trước. Khi bắt đầu trò chơi, dòng này sẽ luôn trống. Dòng này sẽ không được sửa đổi bởi mã điểm hoặc các chương trình khác.

Mỗi chương trình sau đó sẽ sử dụng chiến lược của mình để tạo ra các mục sau cho đầu ra tiêu chuẩn :

  • Một danh sách các Ksố, là ID của các chương trình mà nó sẽ "lấy 1" từ vòng này. Một đầu ra trống có nghĩa là nó sẽ không làm gì.

  • Tùy chọn, một dòng bổ sung đại diện cho một số dạng trạng thái để chuyển sang các vòng sau. Dòng chính xác này sẽ được đưa trở lại chương trình trong vòng tiếp theo.

Dưới đây là một ví dụ đầu vào cho phần đầu của trò chơi dành cho người chơi ID 3trong trò chơi 4 người:

4 3 0
4696634734863777023

Dưới đây là một ví dụ đầu vào cho cùng một trò chơi với một vài vòng đã chơi:

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

Mỗi chương trình sẽ được cung cấp chính xác cùng một đầu vào cho một vòng ngoại trừ số ID Dduy nhất cho mỗi chương trình.

Dưới đây là một ví dụ đầu ra trong đó người chơi 3lấy 1 từ mọi người khác:

1 2 4

Kết thúc tất cả các vòng yêu cầu, người chơi có số điểm cuối cùng cao nhất sẽ là người chiến thắng.


Mốc thời gian

Việc mã hóa cho giải đấu này sẽ kéo dài tổng cộng 7 ngày. Thời hạn nộp là 2014-05-09 00:00 UTC.

Không đăng các chương trình thực tế trước ngày này - đăng băm SHA256 của mã nguồn chương trình của bạn như một cam kết. Bạn có thể thay đổi hàm băm này bất cứ lúc nào trước thời hạn, nhưng các cam kết được đăng sau thời hạn sẽ không được chấp nhận để phán xét. (Vui lòng sử dụng ký hiệu cơ sở 64 cho băm của bạn, vì chương trình xác minh của tôi đã loại bỏ cơ sở 64 và đó là ký hiệu nhỏ gọn hơn.)

Sau khi thời hạn kết thúc, bạn sẽ có 1 ngày (cho đến khi 2014-05-10 00:00 UTC) để đăng mã nguồn thực tế của chương trình để gửi. Nếu hàm băm SHA256 của mã nguồn được đăng của bạn không khớp với bất kỳ hàm băm nào bạn đã đăng trước thời hạn, mã của bạn sẽ không được chấp nhận vào giải đấu.

Sau này, tôi sẽ tải xuống tất cả các bài nộp vào máy tính của riêng tôi và chạy tất cả các mục tham gia giải đấu trong cuộc chiến này, hy vọng sẽ đăng kết quả trong vòng 2 ngày kể từ đó, bởi 2014-05-12 00:00 UTC .

Tôi sẽ chấp nhận câu trả lời với số điểm cao nhất và trao phần thưởng +100 cho câu trả lời đó nếu điểm cuối cùng của nó lớn hơn 0.

Sau khi giải đấu kết thúc, tôi sẽ đăng tệp hạt giống ngẫu nhiên được sử dụng để điều hành cuộc thi và mọi người có thể bắt đầu đăng các giải pháp khác để cố gắng đứng đầu các giải pháp được sử dụng trong giải đấu. Tuy nhiên, họ sẽ không được tính cho sự chấp nhận hoặc tiền thưởng.

Máy chủ

Tôi sẽ chạy các giải pháp này trên một máy ảo trên máy tính của tôi. Máy ảo này sẽ chạy Ubuntu Linux 14.04, với 2 GB RAM. Máy cơ sở của tôi có bộ xử lý Intel i7-2600K tốc độ 3,40 GHz.

Yêu cầu

Chương trình của bạn phải được viết bằng ngôn ngữ mà trình biên dịch hoặc trình thông dịch sẽ biên dịch chương trình của bạn tồn tại và có sẵn cho phiên bản Ubuntu Linux mới nhất, để tôi có thể chạy tất cả các bài nộp và đánh giá chúng trong một máy ảo.

Chương trình của bạn không được mất nhiều hơn 2.000 secondsđể chạy mỗi vòng. Nếu chương trình của bạn hết thời gian hoặc phát sinh lỗi, đầu ra của nó sẽ được coi là trống cho vòng đó.

Chương trình của bạn phải có tính quyết định; nghĩa là, nó phải luôn trả về cùng một đầu ra cho cùng một đầu vào. Giải pháp giả danh được cho phép; tuy nhiên, tính ngẫu nhiên của chúng phải phụ thuộc vào hạt giống ngẫu nhiên được cung cấp cho nó làm đầu vào và không có gì khác. Tệp hạt giống được tạo bằng Python os.urandom. Nó chứa tổng cộng 500 dòng (sẽ được tạo nhiều hơn nếu cần thiết) và hàm băm SHA256 của nó là K+ics+sFq82lgiLanEnL/PABQKnn7rDAGmO48oiYxZk=. Nó sẽ được tải lên ở đây khi giải đấu kết thúc.


Cây

Để bắt đầu, sẽ có bốn "nhà máy", đại diện cho các chiến lược ngây thơ ban đầu. Chúng sẽ được chơi trong giải đấu cùng với bài dự thi của bạn. Tuy nhiên, trong trường hợp không chắc là một trong số họ thắng, số điểm cao nhất mà người chơi không phải là nhà máy sẽ được coi là người chiến thắng.

Để tính toán hàm băm của mỗi tệp của nhà máy, hãy thay thế mỗi nhóm 4 khoảng trắng bằng một tab, vì trình định dạng ở đây dường như không thích các ký tự tab.

Người lười biếng - không bao giờ làm bất cứ điều gì.

n1bnYdeb/bNDBKASWGywTRa0Ne9hMAkal3AuVZJgovI=

pass

Greedy - luôn lấy 1 từ mọi người khác.

+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

The Wrathful - lấy 1 từ những người khác trong vòng đầu tiên và lấy 1 từ tất cả những người đã lấy 1 từ vòng trước đó sau đó.

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

The Eningly - lấy 1 trong số 50% người chơi có số điểm cao nhất hiện tại không bao gồm chính nó, làm tròn xuống.

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

Trong một giải đấu gồm 100 vòng chỉ trong số bốn vòng này, họ nhận được số điểm:

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

Chương trình đánh giá

Tôi đã đăng chương trình thẩm phán mà tôi sẽ sử dụng tại Github . Tải về và kiểm tra nó. (Và có thể sửa một hoặc hai lỗi nếu bạn tìm thấy .: P)

Hiện tại nó không có tùy chọn biên dịch cho bất cứ thứ gì ngoài Python. Tôi sẽ bao gồm những người sau này - nếu mọi người có thể đóng góp các trình biên dịch hoặc biên dịch cho các ngôn ngữ khác, tôi sẽ có nhiều nghĩa vụ.


Giai đoạn 2: Gửi mã nguồn

Tôi đã đăng một chi nhánh mới tournament lên kho lưu trữ Github cho cuộc thi, chứa tệp pd_rand và các mục nhập khác của nhà máy. Bạn có thể đăng mã nguồn của mình tại đây hoặc gửi nó đến chi nhánh đó dưới dạng yêu cầu kéo.

Thứ tự của các thí sinh sẽ như sau:

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

Điểm cuối cùng

Đầu ra của chương trình thử nghiệm của tôi:

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

Xếp hạng:

 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

Vì vậy, hóa ra người chiến thắng thực sự là một người chơi - đó là Người thường xuyên, với -204 điểm!

Thật không may, điểm số của nó không tích cực, nhưng chúng ta khó có thể mong đợi rằng trong một mô phỏng của Thế lưỡng nan tù nhân lặp đi lặp lại nơi mọi người đang chơi để giành chiến thắng.

Một số kết quả đáng ngạc nhiên (ít nhất là tôi nghĩ là đáng ngạc nhiên):

  • Greedy ghi được nhiều hơn Tit cho Tat, và trên thực tế, nhìn chung cao hơn hầu hết những người ghi bàn.

  • Người phán xử, có nghĩa là một loại nhân vật "thực thi đạo đức" (về cơ bản, nó lấy 1 từ bất kỳ ai lấy 1 từ bất kỳ ai với số lần trên trung bình) đã kết thúc với số điểm khá cao, trong khi thử nghiệm mô phỏng, nó thực sự sẽ đạt điểm khá thấp.

Và những người khác (tôi nghĩ) không ngạc nhiên lắm:

  • The Patient ghi được 484 điểm nhiều hơn The Wrathful. Nó thực sự trả tiền để hợp tác lần đầu tiên.

  • Một phần trăm rất nhanh không có ai đá trong khi họ ngã xuống. Có vẻ như 1% chỉ có thể duy trì như vậy vì họ có nhiều người chơi hơn trong trò chơi.

Dù sao, bây giờ khi giải đấu kết thúc, vui lòng đăng thêm bao nhiêu người chơi tùy thích và thử nghiệm với họ bằng chương trình giám khảo.


3
Việc đăng nguồn lên chương trình kiểm soát và / hoặc các nhà máy có làm tổn thương gì không? Chúng tôi biết những gì họ làm dù sao, và tôi muốn có thể kiểm tra một cái gì đó mà không cần viết năm chương trình bổ sung.
Geobits

2
Tôi không hiểu Có một số loại hình phạt cho tất cả mọi người mất 1 thời gian? Sẽ không phải là lợi thế nhất khi luôn lấy 1?
DankMeme

1
Làm thế nào có thể tham lam không tối đa hóa thiệt hại? Nếu chúng tôi lấy từ người chơi khác, người chơi khác chỉ có thể nhận -1 hoặc -2, trong khi nếu chúng tôi không lấy, người chơi khác có thể nhận 1 hoặc 0. Rõ ràng lấy 1 từ người chơi khác sẽ tối đa hóa thiệt hại. Và như vậy Tham lam sẽ không bao giờ mất. Và nó hầu như sẽ luôn chiến thắng, trừ khi tất cả các đối thủ cũng tham lam, như bạn đã nói.
ngay

1
@Trimsty Khi thử thách lần đầu tiên đi lên, mã cho các nhà máy không được hiển thị. Trong toàn bộ giai đoạn mã hóa, chúng tôi không thể thấy các câu trả lời khác. Dupes có thể đã xảy ra hoàn toàn do tai nạn bằng cách chọn chiến lược tham lam rất rõ ràng .
Geobits

2
@justhalf Nếu bạn thực sự đọc bất kỳ nội dung nào về các chiến lược trong tình thế tiến thoái lưỡng nan của tù nhân, bạn sẽ biết những gì bạn đang nói là sai. Các bài viết trên Wikipedia là một nơi tốt để bắt đầu.
Joe Z.

Câu trả lời:


3

Chính quy

Phiên bản của mục này tôi đã chọn cho giải đấu (SHA-256 ggeo+G2psAnLAevepmUlGIX6uqD0MbD1aQxkcys64oc=:) sử dụng Joey 's " chiến lược " Kẻ hút ngẫu nhiên (mặc dù có một thay đổi nhỏ và có thể không đáng kể), đứng ở vị trí thứ hai trong cuộc thi cuối cùng. Thật không may, một phiên bản mới hơn, hiệu quả hơn được gửi chỉ 3 phút 25 giây trước khi thời hạn có lỗi nghiêm trọng, vì vậy nó không thể được sử dụng. Tuy nhiên, phiên bản này vẫn có giá vé tương đối tốt.

<?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";

Phiên bản lỗi có hàm băm SHA-256 là 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";

Để khắc phục, hãy thực hiện các thay thế sau:

  • Thay thế $hashOutput = rtrim(fgets(STDIN), "\n"); bằng$line .= fgets(STDIN); (không phải là điều đó thực sự quan trọng).
  • Thay thế if ($betterScore >= 3 * $myScore) {bằng if ($betterScore >= 0.5 * $myScore && !psRand(0, $betterPlayer)) {(đây là những gì đã giết nó).

1
3 phút và 25 giây trước thời hạn. Tôi rất ấn tượng.
Joe Z.

Chỉ cần một lời nhắc nhở thân thiện: giai đoạn mã hóa đã kết thúc; bạn đã có một ngày để gửi mã nguồn của bạn. (Thủ tục ở cuối câu hỏi.)
Joe Z.

Bất kể tôi sử dụng phiên bản cũ hay phiên bản mới của bạn, chương trình của bạn vẫn xuất hiện đầu tiên. Xin chúc mừng!
Joe Z.

2

Một phần trăm

b61189399ae9494b333df8a71e36039f64f1d2932b838d354c688593d8f09477

Nhìn xuống những tù nhân mà anh ta xem xét bên dưới anh ta.


Đơn giản chỉ cần lấy từ tất cả mọi người có điểm ít hơn hoặc bằng chính mình. Giả định là những tù nhân đó ít có khả năng nhận lại (hoặc họ sẽ có nhiều hơn). Tôi không biết giả định đó tốt đến mức nào, nhưng đó là những gì anh ấy đang vận hành.

Cũng lấy từ tất cả mọi người trên vòng cuối cùng. Nghĩa đen là không có nhược điểm này, vì không ai có thể trả thù - ăn cắp sau đó.

Nếu bạn gặp vấn đề với việc băm vì tab / khoảng trắng từ mã được dán, đây là một liên kết đến chính tệp.

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

}

Hãy nhớ rằng các bạn có thể tiếp tục cải thiện các giải pháp của bạn cho đến 05-09 00:00thời hạn.
Joe Z.

Vâng. Nếu tôi nghĩ về một cái gì đó khác, tôi sẽ. Mặc dù vậy, tôi có một thời gian khó tin rằng bất cứ ai sẽ yêu cầu tiền thưởng đó. Tích cực trong trò chơi này sẽ ... không bình thường.
Geobits

Vâng, tôi không mong đợi bất cứ ai thực sự đạt được tiền thưởng đó. Nó thực sự sẽ là một thành tựu thách thức lý thuyết trò chơi, có thể đáng giá tiền thật trong khả năng nghiên cứu (Một giải pháp hoạt động tốt hơn hai người luôn hợp tác! Hãy tưởng tượng điều đó!) Thay vì chỉ là một danh tiếng 100 trên Stack Exchange.
Joe Z.

1
@JoeZ. Với kiến ​​thức về những gì người khác sẽ làm, chắc chắn;) Chống lại các mục chưa biết, tôi không thể thấy một chiến lược rất đáng tin cậy . Outliers sẽ là outliers, tôi đoán.
Geobits

1
Tôi nghĩ rằng tôi vẫn sẽ chấp nhận nó trong khoảng thời gian này, vì chiến lược của mã của bạn dường như không có gì độc hại và dù sao cũng có quá ít người tham gia để nó trở thành vấn đề.
Joe Z.

1

Dưới đây là một vài loại cây sẽ tham gia vào trò chơi. Những cái này tiên tiến hơn và mã nguồn của chúng sẽ không được tiết lộ cho đến khi kết thúc giai đoạn mã hóa.

Giống như bốn nhà máy trong câu hỏi, nếu họ đạt được điểm cao hơn tất cả những người chơi khác, chỉ có điểm cao nhất mà một thí sinh thực sự đạt được sẽ được coi là người chiến thắng.


Kẻ bắt nạt

29AGVpvJmDEDI5Efe/afmMJRLaJ+TpjwVcz1GkxgYZs=

Chọn người.


Thẩm phán

yjdCQ3uQ4YKe7xAKxdTFLF4d72fD4ACYpDLwkbzdISI=

Trừng phạt những kẻ sai trái.


Lunatic

m3FsRPocekCcK6GDswgnobV2CYOxX8LquChnKxrx1Wo=

Không có ý kiến những gì nó đang làm.


Bệnh nhân

nd7Pt3bVpFnuvDVeHQ5T9EPTq7KjNraVzp/KGtI73Vo=

Không bao giờ thực hiện bước đầu tiên.


Nếu đây chỉ là thực vật, tôi thấy không có lý do gì để không cho phép chúng. Nếu họ là thí sinh có thể giành chiến thắng , tôi nghĩ thật công bằng khi bạn chỉ nhận được một mục cho mỗi nhận xét ở trên.
Geobits

Tôi đã cân nhắc ngắn gọn về việc có mục riêng của mình, sau đó quyết định rằng đó là một đề xuất không công bằng ngay cả khi tôi chỉ nhập thêm một lần nữa, vì có quá nhiều yếu tố khác của trò chơi nằm trong tầm kiểm soát của tôi. Vì vậy, bất kỳ mục tôi đặt ở đây tất cả sẽ chỉ là thực vật.
Joe Z.

Lý do tôi nghĩ mọi người có thể không muốn chúng ngay cả khi thực vật là vì nó thể hiện một sự thay đổi khá triệt để trong những người chơi cơ bản có sẵn (và do đó là chiến lược cơ bản) không có sẵn ở đầu trò chơi. Nhưng nếu chúng ta đi theo giả định rằng các giải pháp nên được mã hóa là tối ưu bất kể người chơi nào được chèn dưới dạng thực vật, thì tôi cho rằng tôi cũng có thể nhập chúng.
Joe Z.

Chà, các mục nên được mã hóa thành "tối ưu" (nếu điều đó tồn tại ở đây) bất kể người chơi có liên quan đơn giản vì chúng tôi không thể thấy các câu trả lời khác. Sẽ không có gì khác biệt nếu đây là những nhà máy hoặc câu trả lời khác cho chương trình, ngoại trừ việc chúng không thể "chiến thắng". Giả sử rằng người chiến thắng được xác định là cây không có số điểm cao nhất, tôi không thấy nó sẽ quan trọng như thế nào. Tôi nói hãy để họ vào.
Geobits

1

Tit-for-tat

9GkjtTDD2jrnMYg/LSs2osiVWxDDoSOgLCpWvuqVmSM=

Tương tự như Wrathful, với một vài thay đổi (hy vọng) nâng cao hiệu suất.

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

Bạn đã nhận được địa chỉ email của tôi?
Joe Z.

@Joe; Đúng; cảm ơn. (Tôi không chắc chắn tôi sẽ cần nó, nhưng cảm ơn vì đã có sức chứa.)
Ypnypn

Được rồi, tôi chỉ muốn biết để tôi có thể xóa nó.
Joe Z.

1
@luserdroog Mọi người đang đăng băm mã nguồn của chương trình thay vì chính chương trình đó. Sau 7 ngày để viết mã, mọi người sẽ tiết lộ các chương trình thực tế của họ để thử nghiệm.
Joe Z.

1
Vâng, đó là sự thật. Một bài nộp có lẽ nên có một tiêu đề và ít nhất là một khẩu hiệu như Geobits 'trên đó.
Joe Z.

1

Backstab

Con trăn 3

Mặc dù tên, bot này thực sự khá duyên dáng. Nhưng đừng đánh dấu vào nó.

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)

CHỈNH SỬA 2 : Nguồn đăng. Yay.

EDIT : Sau một số thử nghiệm, tôi đã sửa một số lỗi tôi tìm thấy. Chúng không phải là thuật toán, chỉ là một số vấn đề đọc đầu vào.


Chỉ cần một lời nhắc nhở thân thiện: giai đoạn mã hóa đã kết thúc; bạn đã có một ngày để gửi mã nguồn của bạn. (Thủ tục ở cuối câu hỏi.)
Joe Z.

@JoeZ. Đăng. Tôi hy vọng tôi đúng giờ. : P
cjfaure

Âm thanh P, D, N, R giống như các ổ đĩa ô tô có thể chuyển sang.
Joe Z.

1
@JoeZ. xD Họ đến từ bài viết của bạn, vì vậy, 3
cjfaure

Ôi lỗi của tôi. Xin lỗi: S
Joe Z.

1

Người bắt đầu

g1TXBu2EfVz/uM/RS24VeJuYMKLOaRatLxsA+DN1Mto=

Tôi sẽ thừa nhận rằng tôi đã không dành nhiều thời gian cho việc này ...

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)

Chỉ cần một lời nhắc nhở thân thiện: giai đoạn mã hóa đã kết thúc; bạn đã có một ngày để gửi mã nguồn của bạn. (Thủ tục ở cuối câu hỏi.)
Joe Z.

Tôi đã cố chạy cái này và gặp phải lỗi sau: o += a.split(', ')[0]không chừa khoảng trống giữa các con số.
Xin vui lòng và

@PleaseStand Tôi đã sửa nó, nhưng tôi nghĩ rằng phiên bản thử nghiệm sẽ kết thúc với lỗi vì sự cạnh tranh đã kết thúc.
kitcar2000

Vâng, mã của bạn tạo ra một lỗi bất cứ khi nào tôi chạy nó và tôi không thể tìm ra cách khắc phục nó. Nó đã làm tốt hơn một chút so với The Lazy, mặc dù.
Joe Z.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.