Dilema Tahanan v.2 - Battle Royale

15

Dalam pertanyaan ini , sebuah permainan dirancang di mana para pemain akan saling berhadapan satu sama lain secara berpasangan di Dilema Tahanan, untuk menentukan strategi berulang mana yang mencetak skor tertinggi melawan yang lain.

Dalam pertanyaan ini , saya menemukan cara bagi banyak orang untuk memainkan Dilema Tahanan satu sama lain secara bersamaan. Dalam variasi ini, matriks hasil tidak perlu, dengan setiap hasil antara setiap pasangan dari dua pemain menjadi jumlah dari dua keputusan independen yang fungsional.

Tugas Anda adalah membangun AI untuk memainkan versi Dilema Tahanan multi-pemain yang simetris dan umum ini yang akan mencapai skor setinggi mungkin.


Aturan main

Di setiap putaran multipemain ini, Dilema Tahanan multi-putaran, seorang pemain Adapat memutuskan untuk "mengambil 1" dari beberapa pemain lain B. Dalam keadaan ini, Askor meningkat sebesar 1, sedangkan Bskor menurun sebesar 2. Keputusan ini diperbolehkan terjadi antara setiap pasangan pemain yang dipesan.

Ini adalah satu-satunya keputusan yang dibuat untuk masing-masing pemain - baik untuk "mengambil 1" atau tidak "mengambil 1" dari masing-masing pemain lain, yang homolog dengan pembelotan dan kerjasama masing-masing. Matriks hasil efektif antara dua pemain P1dan P2terlihat sebagai berikut:

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

Prosedur Turnamen

Permainan akan terdiri dari P * 25putaran, di mana Pjumlah pemain yang berpartisipasi. Semua pemain mulai dengan skor 0. Setiap putaran terdiri dari prosedur berikut:

Pada awal putaran, setiap program akan diberi riwayat putaran sebelumnya dari input standar , dalam format berikut:

  • Salah satu baris yang berisi 3 nomor, P, D, dan N.

    • Padalah jumlah total pemain dalam game. Setiap pemain secara acak diberi nomor ID dari 1hingga Pdi awal permainan.

    • D adalah ID pemain saat ini.

    • N adalah jumlah putaran yang telah dimainkan.

  • Ngaris, masing-masing garis mewakili hasil putaran. On line kof N, akan ada beberapa jumlah n_kpasangan memerintahkan (a, b), dipisahkan oleh spasi, yang menyatakan bahwa pemain dengan ID a"mengambil 1" dari pemain dengan ID bdi babak itu.

  • Nomor acak seragam Rdari 0ke 18446744073709551615(2 64 - 1), untuk bertindak sebagai seed pseudorandom. Angka-angka ini akan dibaca dari file yang dibuat sebelumnya, yang akan dirilis pada akhir turnamen sehingga orang dapat memverifikasi hasilnya sendiri.

  • Satu baris tambahan yang mewakili beberapa bentuk keadaan untuk dibaca ke dalam program Anda, jika program Anda menghasilkan output seperti itu di babak sebelumnya. Di awal permainan, baris ini akan selalu kosong. Baris ini tidak akan dimodifikasi oleh kode penilaian atau program lain.

Setiap program kemudian akan menggunakan strateginya untuk menghasilkan yang berikut ke output standar :

  • Daftar Kangka, yang merupakan ID program yang akan "diambil 1" dari babak ini. Output kosong berarti tidak akan melakukan apa-apa.

  • Secara opsional, satu baris tambahan yang mewakili beberapa bentuk negara untuk diteruskan ke putaran selanjutnya. Baris persis ini akan diumpankan kembali ke program di babak berikutnya.

Di bawah ini adalah contoh input untuk permulaan gim untuk pemain ID 3dalam gim 4-pemain:

4 3 0
4696634734863777023

Di bawah ini adalah contoh input untuk game yang sama dengan beberapa putaran yang sudah dimainkan:

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

Setiap program akan diberi input yang sama persis untuk satu putaran kecuali untuk nomor ID Dyang unik untuk setiap program.

Di bawah ini adalah contoh output di mana pemain 3mengambil 1 dari orang lain:

1 2 4

Di akhir semua putaran yang diperlukan, pemain dengan skor akhir tertinggi akan menjadi pemenang.


Linimasa

Pengkodean untuk turnamen ini akan berlangsung selama 7 hari. Batas waktu pengiriman adalah 2014-05-09 00:00 UTC.

Jangan memposting program aktual sebelum tanggal ini - memposting hash SHA256 dari kode sumber program Anda sebagai komitmen. Anda dapat mengubah hash ini kapan saja sebelum batas waktu, tetapi komitmen yang dipasang setelah batas waktu tidak akan diterima untuk penilaian. (Silakan gunakan notasi base 64 untuk hash Anda, karena program verifikasi saya mengeluarkan basis 64 dan ini notasi yang lebih kompak.)

Setelah batas waktu berakhir, Anda memiliki 1 hari (hingga 2014-05-10 00:00 UTC) untuk memposting kode sumber aktual program Anda untuk pengiriman Anda. Jika hash SHA256 dari kode sumber Anda yang diposkan tidak cocok dengan hash apa pun yang Anda poskan sebelum batas waktu, kode Anda tidak akan diterima ke dalam turnamen.

Setelah ini, saya akan mengunduh semua kiriman ke komputer saya sendiri, dan menjalankan semua entri turnamen di battle royale ini, semoga memposting hasilnya dalam waktu 2 hari sejak saat itu, oleh 2014-05-12 00:00 UTC.

Saya akan menerima jawaban dengan skor tertinggi, dan memberikan hadiah +100 untuk jawaban itu jika skor akhirnya lebih besar dari 0.

Setelah turnamen selesai, saya akan memposting file seed acak yang digunakan untuk menjalankan kompetisi, dan orang-orang dapat mulai memposting solusi lain yang mencoba untuk mengatasi yang digunakan dalam turnamen. Namun, mereka tidak akan menghitung penerimaan atau hadiah.

Mesin Host

Saya akan menjalankan solusi ini pada mesin virtual di komputer saya. Mesin virtual ini akan menjalankan Ubuntu Linux 14.04, dengan 2 gigabytes RAM. Mesin dasar saya memiliki prosesor Intel i7-2600K yang berjalan pada 3,40 GHz.

Persyaratan

Program Anda harus ditulis dalam bahasa yang kompiler atau juru bahasa yang akan mengkompilasi program Anda ada dan sudah tersedia untuk versi terbaru Ubuntu Linux, sehingga saya dapat menjalankan semua pengiriman dan menilai mereka dalam mesin virtual.

Program Anda tidak boleh lebih dari 2.000 secondsmenjalankan setiap putaran. Jika program Anda kehabisan waktu atau menghasilkan kesalahan, hasilnya akan dianggap kosong untuk putaran itu.

Program Anda harus bersifat deterministik; artinya, ia harus selalu mengembalikan output yang sama untuk input yang sama. Solusi pseudorandom diizinkan; Namun, keacakan mereka harus bergantung pada seed acak yang diberikan padanya sebagai input dan bukan yang lain. File seed dihasilkan menggunakan Python os.urandom. Ini berisi total 500 baris (lebih banyak akan dihasilkan jika perlu), dan hash SHA256-nya adalah K+ics+sFq82lgiLanEnL/PABQKnn7rDAGmO48oiYxZk=. Ini akan diunggah di sini setelah turnamen selesai.


Tanaman

Untuk memulai, akan ada empat "tanaman", yang mewakili strategi naif awal. Ini akan diputar di turnamen bersama dengan kiriman Anda. Namun, jika salah satu dari mereka menang, skor tertinggi yang diperoleh pemain selain tanaman akan dianggap sebagai pemenang.

Untuk menghitung hash dari setiap file tanaman, ganti setiap grup dengan 4 spasi dengan tab, karena pemformat di sini sepertinya tidak menyukai karakter tab.

Malas - tidak pernah melakukan apa pun.

n1bnYdeb/bNDBKASWGywTRa0Ne9hMAkal3AuVZJgovI=

pass

The Greedy - selalu mengambil 1 dari orang lain.

+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 - mengambil 1 dari semua orang di ronde pertama, dan mengambil 1 dari semua orang yang mengambil 1 dari ronde sebelumnya sesudahnya.

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

Envy - mengambil 1 dari 50% pemain dengan skor tertinggi saat ini tidak termasuk dirinya sendiri, dibulatkan ke bawah.

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

Dalam turnamen 100 putaran hanya di antara empat putaran ini, mereka menerima skor dari:

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

Program Penjurian

Saya telah memposting program juri yang akan saya gunakan di Github . Unduh dan uji. (Dan mungkin memperbaiki satu atau dua bug jika Anda menemukannya.: P)

Itu tidak memiliki opsi kompilasi untuk apa pun selain Python saat ini. Saya akan memasukkannya nanti - jika orang dapat berkontribusi dalam kompilasi atau naskah interpretasi untuk bahasa lain, saya akan sangat berkewajiban.


Fase 2: Pengajuan Kode Sumber

Saya telah memposting cabang baru tournamentke repositori Github untuk kontes, yang berisi file pd_rand dan entri instalasi lainnya. Anda dapat memposting kode sumber Anda di sini atau mengirimkannya ke cabang itu sebagai permintaan tarik.

Urutan para kontestan adalah sebagai berikut:

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

Skor Akhir

Output dari program pengujian saya:

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

Peringkat:

 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

Jadi ternyata pemenangnya adalah seorang pemain - ini adalah The Reguler, dengan -204 poin!

Sayangnya, nilainya tidak positif, tetapi kita tidak bisa berharap bahwa dalam simulasi Dilema Tahanan Iterated di mana semua orang bermain untuk menang.

Beberapa hasil mengejutkan (setidaknya yang saya pikir mengejutkan):

  • The Greedy mencetak lebih dari Tit untuk Tat, dan pada kenyataannya, umumnya lebih tinggi daripada kebanyakan pencetak gol sama sekali.

  • Hakim, yang dimaksudkan untuk menjadi semacam karakter "penegak moralitas" (pada dasarnya mengambil 1 dari siapa pun yang mengambil 1 dari siapa pun jumlah rata-rata di atas) berakhir dengan penilaian yang agak tinggi, sementara dalam pengujian simulasi, itu sebenarnya akan dapatkan skor yang agak rendah.

Dan yang lain yang (saya pikir) tidak begitu mengejutkan:

  • The Patient mencetak 484 poin lebih banyak dari The Wrathful. Sangat bermanfaat untuk bekerja sama untuk pertama kalinya.

  • Satu Persen dengan sangat cepat hampir tidak ada yang menendang saat mereka turun. Tampaknya 1% hanya bisa tetap seperti itu karena mereka memiliki lebih banyak pemain dalam permainan.

Ngomong-ngomong, sekarang setelah turnamen selesai, jangan ragu untuk mengirim sebanyak mungkin pemain tambahan, dan coba-coba dengan mereka menggunakan program juri.

Joe Z.
sumber
3
Apakah memposting sumber ke program kontrol dan / atau instalasi menyakiti apa pun? Kami tahu apa yang mereka lakukan, dan saya lebih suka bisa menguji sesuatu tanpa menulis lima program tambahan.
Geobits
2
Saya tidak mengerti. Apakah ada semacam hukuman bagi semua orang yang mengambil 1 sepanjang waktu? Bukankah lebih menguntungkan untuk selalu mengambil 1?
DankMemes
1
Bagaimana bisa serakah tidak memaksimalkan kerusakan? Jika kita mengambil dari pemain lain, pemain lain hanya bisa mendapatkan -1 atau -2, sementara jika kita tidak mengambil, pemain lain bisa mendapatkan 1 atau 0. Jelas mengambil 1 dari pemain lain akan memaksimalkan kerusakan. Dan Greedy tidak akan pernah kalah. Dan itu akan hampir selalu menang, kecuali semua lawan juga rakus, seperti yang Anda katakan.
justhalf
1
@Rimsty Ketika tantangan pertama kali naik, kode untuk tanaman tidak ditampilkan. Melalui seluruh fase pengkodean, kami tidak dapat melihat jawaban lain. Dupes bisa terjadi murni secara tidak sengaja dengan memilih strategi serakah yang sangat jelas .
Geobits
2
@justhalf Jika Anda benar-benar membaca strategi tentang strategi dalam dilema tahanan yang diulang, Anda akan tahu apa yang Anda katakan salah. The Artikel Wikipedia adalah tempat yang baik untuk memulai.
Joe Z.

Jawaban:

3

Biasa

Versi entri ini saya pilih untuk turnamen (SHA-256 :)ggeo+G2psAnLAevepmUlGIX6uqD0MbD1aQxkcys64oc= menggunakan Joey 's " strategi " Pengisap acak (walaupun dengan perubahan kecil dan kemungkinan tidak signifikan), yang berada di posisi kedua dalam kontes terakhir. Sayangnya, versi yang lebih baru dan lebih efektif dikirimkan hanya 3 menit 25 detik sebelum batas waktu memiliki bug yang serius, sehingga tidak dapat digunakan. Namun demikian, versi ini masih relatif baik.

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

Versi buggy memiliki hash 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";

Untuk memperbaikinya, lakukan penggantian ini:

  • Menggantikan $hashOutput = rtrim(fgets(STDIN), "\n"); dengan $line .= fgets(STDIN);(bukan itu yang benar-benar penting).
  • Ganti if ($betterScore >= 3 * $myScore) {dengan if ($betterScore >= 0.5 * $myScore && !psRand(0, $betterPlayer)) {(inilah yang membunuhnya).
PleaseStand
sumber
1
3 menit dan 25 detik sebelum batas waktu. Saya terkesan.
Joe Z.
Hanya pengingat yang ramah: fase pengkodean telah berakhir; Anda punya waktu untuk memposting kode sumber Anda. (Prosedur ada di bagian bawah pertanyaan.)
Joe Z.
Terlepas dari apakah saya menggunakan versi lama Anda atau versi baru Anda, program Anda masih keluar dulu. Selamat!
Joe Z.
2

Satu persen

b61189399ae9494b333df8a71e36039f64f1d2932b838d354c688593d8f09477

Memandang rendah tahanan-tahanan yang dia pertimbangkan di bawahnya.


Cukup mengambil dari setiap orang yang memiliki poin kurang dari atau sama dengan dirinya sendiri. Asumsinya adalah bahwa para tahanan itu cenderung tidak menerima balasan (atau mereka akan mendapatkan lebih banyak). Saya tidak tahu seberapa bagus asumsi itu, tetapi itulah yang sedang dia lakukan.

Juga mengambil dari semua orang di babak terakhir. Tidak ada kerugian untuk ini, karena tidak ada yang bisa membalas dendam setelah itu.

Jika Anda memiliki masalah dalam mendapatkan hash karena tab / spasi dari kode yang disisipkan, inilah tautan ke file itu sendiri.

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

}
Geobit
sumber
Ingat kalian bisa terus melakukan perbaikan solusi Anda sampai 05-09 00:00batas waktu.
Joe Z.
Ya. Jika saya memikirkan hal lain, saya akan melakukannya. Tapi aku kesulitan percaya ada orang yang akan mengklaim hadiah itu. Menjadi positif dalam permainan ini adalah ... tidak biasa.
Geobits
Ya, saya tidak berharap ada orang yang benar-benar mencapai karunia itu. Ini benar-benar akan menjadi prestasi yang menantang teori permainan, mungkin bernilai uang nyata dalam kemungkinan penelitian (Solusi yang bekerja lebih baik daripada dua orang yang selalu bekerja sama! Bayangkan itu!) Alih-alih hanya reputasi yang sangat sedikit di Stack Exchange.
Joe Z.
1
@ Joz. Dengan pengetahuan tentang apa yang akan dilakukan orang lain, tentu saja;) Terhadap entri yang tidak diketahui, saya tidak bisa melihat strategi yang andal . Outlier akan outlier, saya kira.
Geobits
1
Saya pikir saya masih akan menerimanya kali ini, karena strategi kode Anda tampaknya tidak berbahaya dan ada terlalu sedikit pendaftar untuk masalah.
Joe Z.
1

Berikut adalah beberapa pabrik lagi yang akan berpartisipasi dalam permainan. Yang ini lebih maju, dan kode sumbernya tidak akan terungkap sampai akhir fase pengkodean.

Sama seperti empat pabrik dalam pertanyaan, jika mereka berhasil mencetak skor lebih tinggi dari semua pemain lain, hanya skor tertinggi yang dicapai oleh kontestan yang sebenarnya akan dianggap sebagai pemenang.


Si pengganggu

29AGVpvJmDEDI5Efe/afmMJRLaJ+TpjwVcz1GkxgYZs=

Pilihan pada orang-orang.


Hakim

yjdCQ3uQ4YKe7xAKxdTFLF4d72fD4ACYpDLwkbzdISI=

Menghukum orang yang bersalah.


Orang gila

m3FsRPocekCcK6GDswgnobV2CYOxX8LquChnKxrx1Wo=

Tidak tahu apa yang dilakukannya.


Pasien

nd7Pt3bVpFnuvDVeHQ5T9EPTq7KjNraVzp/KGtI73Vo=

Tidak pernah melakukan langkah pertama.

Joe Z.
sumber
Jika ini hanya tanaman, saya tidak melihat alasan untuk tidak mengizinkannya. Jika mereka adalah kontestan yang bisa menang , saya pikir itu adil bahwa Anda hanya mendapatkan satu entri per komentar di atas.
Geobits
Saya sempat mempertimbangkan memiliki entri saya sendiri, kemudian memutuskan bahwa itu sebuah proposisi yang tidak adil sama sekali bahkan jika saya hanya masuk satu lagi, karena terlalu banyak unsur-unsur lain dari permainan berada di bawah kendali saya. Jadi setiap entri yang saya tempatkan di sini semuanya akan menjadi tanaman saja.
Joe Z.
Alasan saya pikir orang mungkin tidak menginginkan mereka bahkan sebagai tanaman adalah karena itu mewakili perubahan yang agak radikal dalam pemain dasar yang tersedia (dan dengan demikian strategi dasar) yang tidak tersedia di awal permainan. Tetapi jika kita pergi dengan asumsi bahwa solusi harus dikodekan agar menjadi optimal terlepas dari pemain dimasukkan sebagai tanaman, maka saya kira saya bisa memasukkannya juga.
Joe Z.
Entri harus dikodekan ke "optimal" (jika ada di sini) terlepas dari pemain yang terlibat hanya karena kita tidak dapat melihat jawaban lain. Tidak ada bedanya jika ini adalah tanaman atau jawaban lain untuk program, kecuali bahwa ini tidak dapat "menang". Dengan anggapan bahwa pemenang didefinisikan sebagai bukan-tanaman dengan skor tertinggi, saya tidak melihat seberapa penting hal itu. Saya katakan biarkan mereka masuk.
Geobits
1

Gayung-untung

9GkjtTDD2jrnMYg/LSs2osiVWxDDoSOgLCpWvuqVmSM=

Mirip dengan Wrathful, dengan beberapa (semoga) perubahan peningkatan kinerja.

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
Ypnypn
sumber
Apakah Anda mendapatkan alamat email saya?
Joe Z.
@ Jo; Iya; Terima kasih. (Saya tidak yakin saya akan membutuhkannya, tapi terima kasih sudah membantu.)
Ypnypn
Baiklah, saya hanya ingin tahu sehingga saya bisa menghapusnya.
Joe Z.
1
@luserdroog Orang-orang memposting hash kode sumber program mereka alih-alih program itu sendiri. Setelah 7 hari untuk menulis kode, orang akan mengungkapkan program aktual mereka untuk pengujian.
Joe Z.
1
Ya itu benar. Kiriman mungkin harus memiliki judul dan setidaknya tagline seperti yang dimiliki Geobits di sana.
Joe Z.
1

Backstab

Python 3

Terlepas dari namanya, bot ini sebenarnya cukup ramah. Tapi jangan mencentangnya.

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)

EDIT 2 : Sumber yang diposting. Yay.

EDIT : Setelah beberapa pengujian saya memperbaiki beberapa kekurangan yang saya temukan. Mereka tidak algoritmik, hanya beberapa masalah membaca input.

cjfaure
sumber
Hanya pengingat yang ramah: fase pengkodean telah berakhir; Anda punya waktu untuk memposting kode sumber Anda. (Prosedur ada di bagian bawah pertanyaan.)
Joe Z.
@ Joz. Diposting Saya harap saya tepat waktu. : P
cjfaure
P, D, N, R terdengar seperti drive yang dapat digeser mobil.
Joe Z.
1
@ Joz. xD Mereka dari pos Anda, jadi; 3
cjfaure
Oh, salahku. Maaf: S
Joe Z.
1

Itu Begrudger

g1TXBu2EfVz/uM/RS24VeJuYMKLOaRatLxsA+DN1Mto=

Kode

Saya akan mengakui bahwa saya tidak menghabiskan banyak waktu untuk ini ...

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)
kitcar2000
sumber
Hanya pengingat yang ramah: fase pengkodean telah berakhir; Anda punya waktu untuk memposting kode sumber Anda. (Prosedur ada di bagian bawah pertanyaan.)
Joe Z.
Saya mencoba menjalankan ini dan mengalami bug berikut: o += a.split(', ')[0]tidak menyisakan ruang di antara angka-angka.
PleaseStand
@PleaseStand saya sudah memperbaikinya, tapi saya pikir versi yang diuji akan berakhir dengan bug karena kompetisi sudah berakhir.
kitcar2000
Ya, kode Anda menghasilkan bug setiap kali saya menjalankannya, dan saya tidak tahu cara memperbaikinya. Itu sedikit lebih baik daripada The Lazy.
Joe Z.