Ділема в'язня v.2 - Battle Royale


15

У цьому питанні була розроблена гра, в якій гравці зіштовхуватимуться один з одним за парою в дилемі в'язня, щоб визначити, яка ітеративна стратегія набрала найбільшу оцінку проти інших.

У цьому питанні я розробив спосіб для кількох людей грати в дилему в'язнів один проти одного одночасно. У цьому варіанті матриця виплат є непотрібною, при цьому кожен результат між кожною парою двох гравців є сумою двох функціонально незалежних рішень.

Ваше завдання - створити AI, щоб грати в цю симетричну, узагальнену версію мультиплікаційної дилеми в'язня, яка дозволить досягти максимально можливого балу


Правила гри

У кожному раунді цієї багатокористувацької, багатогранної дилеми в'язня, гравець Aможе вирішити "взяти 1" у якогось іншого гравця B. У цьому випадку Aрахунок збільшується на 1, а Bрахунок зменшується на 2. Це рішення дозволяється відбуватися між кожною впорядкованою парою гравців.

Це єдине рішення, яке приймається для кожного гравця - або "брати 1", або не "брати 1" один від одного гравця, які є гомологічними до дефектів і співпраці відповідно. Ефективна матриця виграшів між двома гравцями P1і P2виглядають наступним чином :

  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- загальна кількість гравців у грі. Кожному гравцеві випадково присвоюється ідентифікаційний номер від 1до Pпочатку гри.

    • D ідентифікатор поточного гравця.

    • N - кількість відіграних раундів.

  • Nрядки, кожен рядок представляє результати раунду. На лінії kз N, буде деяка кількість n_kупорядкованих пар (a, b), розділених пробілами, які представляють собою , що гравець з ідентифікатором a«прийняв 1» від гравця з ID bв цьому раунді.

  • Рівномірно випадкове число Rвід 0до 18446744073709551615(2 64 - 1), щоб діяти як псевдовипадкове насіння. Ці цифри будуть прочитані з попередньо створеного файлу, який буде випущений наприкінці турніру, щоб люди могли перевірити результати для себе.

  • Один додатковий рядок, який представляє певну форму стану, яку слід прочитати у вашій програмі, якщо ваша програма дала такий результат у попередньому раунді. На початку гри цей рядок завжди буде порожнім. Цей рядок не змінюватиметься ні кодируючим кодом, ні іншими програмами.

Після цього кожна програма використовуватиме свою стратегію для отримання наступних стандартних результатів :

  • Список Kномерів, які є ідентифікаторами програм, які він "займе 1" з цього раунду. Порожній вихід означає, що він нічого не зробить.

  • Необов'язково - одна додаткова лінія, яка представляє певну форму стану для переходу до наступних раундів. Цей точний рядок буде повернуто програмі в наступному раунді.

Нижче наводиться приклад для початку гри для гравця з ідентифікатором 3у грі для 4 гравців:

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який є унікальним для кожної програми.

Нижче наведено приклад результату, у якому гравець 3бере 1 від усіх інших:

1 2 4

В кінці всіх необхідних раундів переможець буде гравець з найвищим підсумковим балом.


Хронологія

Кодування цього турніру триватиме загалом 7 днів. Кінцевий термін подання заявок - 2014-05-09 00:00 UTC.

Не публікуйте фактичні програми до цієї дати - опублікуйте хеш SHA256 вихідного коду вашої програми як зобов’язання. Ви можете змінити цей хеш будь-коли до встановленого терміну, але зобов'язання, розміщені після цього терміну, не приймаються до рішення. (Будь ласка, використовуйте позначення бази 64 для своїх хешів, оскільки моя програма підтвердження випилює базу 64, і це більш компактне позначення.)

Після закінчення терміну у вас буде 1 день (до 2014-05-10 00:00 UTC), щоб опублікувати фактичний вихідний код вашої програми для подання. Якщо хеш SHA256 вашого розміщеного вихідного коду не відповідає жодному хешу, який ви опублікували до встановленого терміну, ваш код не буде прийнятий до турніру.

Після цього я завантажу всі матеріали на свій власний комп'ютер і запускаю всі записи турніру в цій бойовій рояллі, сподіваюся, розміщую результати протягом 2 днів з того часу 2014-05-12 00:00 UTC.

Я прийму відповідь з найбільшою оцінкою та нагороду отримаю в розмірі +100 за цю відповідь, якщо її кінцевий бал перевищує 0.

Після закінчення турніру я опублікую випадковий насіннєвий файл, який використовується для проведення змагань, і люди можуть почати розміщувати інші рішення, намагаючись довершити ті, які використовуються в турнірі. Однак вони не зараховуються до акцепту чи виграші.

Хост-машина

Я буду запускати ці рішення на віртуальній машині на своєму комп’ютері. Ця віртуальна машина буде працювати з Ubuntu Linux 14.04, з 2 гігабайтами оперативної пам’яті. У моєї базової машини є процесор Intel i7-2600K, який працює на частоті 3,40 ГГц.

Вимоги

Ваша програма повинна бути написана мовою, для якої існує компілятор або інтерпретатор, який буде компілювати вашу програму, і вона є доступною для останньої версії Ubuntu Linux, щоб я міг запускати всі матеріали та оцінювати їх у віртуальній машині.

Ваша програма не повинна займати більше, ніж 2.000 secondsпроводити кожен раунд. Якщо у вашої програми не вистачає часу або виникає помилка, її висновок буде вважатися порожнім для цього раунду.

Ваша програма повинна бути детермінованою; тобто він повинен завжди повертати один і той же вихід на один і той же вхід. Дозволені псевдовипадкові розчини; однак їх випадковість повинна залежати від випадкового насіння, що дається йому як вхідне і нічого іншого. Насіннєвий файл був створений за допомогою Python's os.urandom. Він містить загалом 500 рядків (при необхідності буде створено більше), а його хеш SHA256 є K+ics+sFq82lgiLanEnL/PABQKnn7rDAGmO48oiYxZk=. Він буде завантажений сюди, коли турнір закінчиться.


Рослини

Щоб розпочати справи, будуть чотири "заводи", що представляють початкові наївні стратегії. Вони будуть грати в турнірі разом з вашими заявами. Однак у маловірогідному випадку, коли хтось із них виграє, найвищий бал, отриманий гравцем, крім рослини, буде вважатися переможцем.

Щоб обчислити хеш файлів кожної рослини, замініть кожну групу з 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

Заздрісники - беруть 1 із 50% гравців, за винятком яких є найвищий бал, закруглюючи його вниз.

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 . Завантажте його і протестуйте. (І, можливо, виправте помилку чи дві, якщо її знайдете.: 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

Так виходить, що переможець справді є гравцем - це The Regular, з -204 балами!

На жаль, його оцінка не була позитивною, але навряд чи можна очікувати, що в симуляції Ітерованої дилеми в'язня, де всі грають, щоб перемогти.

Деякі дивовижні результати (принаймні, я вважав, що вони дивні):

  • Жадібний набрав більше, ніж Тит за Тата, і насправді, взагалі вище, ніж більшість бомбардирів взагалі.

  • Суддя, який мав бути своєрідним "правозахисником" характеру (в основному це брав 1 від того, хто взяв 1 у когось вище середнього числа разів) закінчився очок досить високим, тоді як в симуляційному тестуванні це було б насправді отримати досить низький бал.

І інші, які (я думав) були не такі дивні:

  • Пацієнт набрав повних 484 балів більше, ніж The Wrathful. Це дійсно платить співпрацювати в перший раз.

  • Один Процент дуже швидко не мав кого бити, поки вони були вниз. Здається, що 1% може залишатися таким, тому що в грі більше гравців.

У будь-якому випадку, тепер, коли турнір закінчився, сміливо розміщуйте стільки зайвих гравців, скільки хочете, і тестуйте їх разом із програмою судді.


3
Чи буде розміщення джерела в контрольній програмі та / або рослинах щось завдає шкоди? Ми все-таки знаємо, чим вони займаються, і я вважаю за краще мати змогу протестувати проти чогось, не написавши п'ять додаткових програм.
Геобіць

2
Я не розумію. Чи є якийсь штраф за кожного, хто приймає 1 весь час? Не було б найвигідніше завжди брати 1?
DankMemes

1
Як жадібний не максимізувати шкоду? Якщо ми беремо від іншого гравця, інший гравець може отримати лише -1 або -2, тоді як якщо ми не візьмемо, то другий гравець може отримати 1 або 0. Очевидно, що взяти 1 у іншого гравця максимально збиток. І тому Жадібний ніколи не програє. І майже завжди виграє, якщо тільки не всі суперники теж жадібні, як ви сказали.
justhalf

1
@Trimsty Коли виклик вперше піднявся, код для рослин не відображався. Через всю фазу кодування ми не могли побачити інших відповідей. Дупс міг статися чисто випадково, вибравши дуже очевидну жадібну стратегію.
Геобіць

2
@justhalf Якщо ви насправді читали будь-які дослідження стратегій в ітераційній дилемі ув'язненого, то знаєте, що ви говорите неправдиво. Стаття у Вікіпедії - гарне місце для початку.
Джо З.

Відповіді:


3

Регулярний

Я вибрав для цього турніру версію цього запису (SHA-256 :)ggeo+G2psAnLAevepmUlGIX6uqD0MbD1aQxkcys64oc= використовує стратегію Джоуї " Випадкове присмоктування " (хоча і з незначною і, ймовірно, незначною зміною), яка посіла друге місце в останньому змаганні. На жаль, новіша, більш ефективна версія, представлена ​​лише за 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 секунд до встановленого терміну. Я вражений.
Джо З.

Просто дружнє нагадування: фаза кодування закінчена; у вас є день для публікації вихідного коду. (Процедура знаходиться в нижній частині питання.)
Джо 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терміну.
Джо З.

Так. Якщо я придумаю щось інше, я буду. Мені важко вірити, що хтось буде претендувати на цю винагороду. Позитив у цій грі був би ... незвичним.
Геобіт

Так, я не сподіваюся, що хтось дійсно досягне цієї виграші. Це справді було б цілком теоретичним ігровим завданням, яке, можливо, вартує реальних грошей на дослідницьких можливостях (рішення, яке працює краще, ніж двоє людей, які завжди співпрацюють! Уявіть собі це!) Замість просто потворної репутації 100 на Stack Exchange.
Джо З.

1
@JoeZ. Зі знанням того, що робитимуть інші, впевнені;) На тлі невідомих записів я не бачу дуже надійної стратегії. Гадаю, люди, що пережили свою роботу, стануть пережилими.
Геобіт

1
Думаю, я все одно прийму це на цей раз, оскільки стратегія вашого коду, здається, не є зловмисною, і для абітурієнтів це не так вже й мало.
Джо З.

1

Ось ще кілька рослин, які братимуть участь у грі. Ці більш досконалі, і їх вихідний код не буде розкритий до кінця фази кодування.

Як і чотири заводи у питанні, якщо їм вдасться набрати вище, ніж усі інші гравці, переможцем вважатиметься лише найвищий бал, досягнутий фактичним учасником.


Хуліган

29AGVpvJmDEDI5Efe/afmMJRLaJ+TpjwVcz1GkxgYZs=

Вибирає людей.


Суддя

yjdCQ3uQ4YKe7xAKxdTFLF4d72fD4ACYpDLwkbzdISI=

Покарає кривдників.


Лунатик

m3FsRPocekCcK6GDswgnobV2CYOxX8LquChnKxrx1Wo=

Поняття не має, що це робить.


Паціент

nd7Pt3bVpFnuvDVeHQ5T9EPTq7KjNraVzp/KGtI73Vo=

Ніколи не робить перший хід.


Якщо це лише рослини, я не бачу причин не допускати їх. Якщо вони є учасниками, які можуть перемогти , я думаю, що справедливо, що ви отримуєте лише один запис на коментарі вище.
Геобіт

Я коротко подумав про те, що я маю власну заяву, а потім вирішив, що це взагалі несправедливе судження, навіть якщо я лише ввів ще один, оскільки надто багато інших елементів гри під моїм контролем. Тож будь-які записи, які я розміщую тут, будуть просто рослинами.
Джо З.

Причина, по якій я вважав, що люди, можливо, не хотіли їх навіть як рослини, - це те, що це являє собою досить радикальну зміну базових гравців, які є доступними (і, таким чином, базовими стратегіями), які були недоступні на початку гри. Але якщо ми підемо з припущення, що рішення повинні бути кодовані як оптимальні незалежно від гравців, що вставлені як рослини, то, я вважаю, я міг би також ввести їх.
Джо З.

Ну а записи повинні бути закодовані в "оптимальний" (якщо такий існує тут) незалежно від залучених гравців, просто тому, що ми не можемо бачити інших відповідей. Не має значення, якщо це були рослини чи інші відповіді на програму, за винятком того, що вони не можуть "перемогти". Якщо припустити, що переможець визначається як невиробник з найвищим балом, я не бачу, як це буде мати велике значення. Я кажу, пустіть їх.
Геобіт

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; так; Спасибі. (Я не впевнений, що мені це потрібно, але дякую, що розмістив.)
Ypnypn

Добре, я просто хотів знати, щоб я міг її видалити.
Джо З.

1
@luserdroog Люди розміщують хеші вихідного коду програми замість самої програми. Після закінчення 7 днів для написання коду люди розкриють свої фактичні програми для тестування.
Джо З.

1
Так, це правда. Надіслання, ймовірно, повинно мати назву та принаймні теговий рядок, як один у Geobits.
Джо З.

1

Backstab

Пітон 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)

EDIT 2 : Розміщене джерело. Так.

EDIT : Після деяких тестувань я усунув деякі виявлені вади. Вони не алгоритмічні, лише деякі питання читання введення.


Просто дружнє нагадування: фаза кодування закінчена; у вас є день для публікації вихідного коду. (Процедура знаходиться внизу запитання.)
Джо Z.

@JoeZ. Опубліковано. Я сподіваюся, що я встигну. : P
cjfaure

P, D, N, R звучить так, ніби приводи автомобіля можуть перетворюватися на.
Джо З.

1
@JoeZ. xD Вони з вашої посади, так; 3
cjfaure

Ой, моя погана. Вибачте: 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)

Просто дружнє нагадування: фаза кодування закінчена; у вас є день для публікації вихідного коду. (Процедура знаходиться внизу запитання.)
Джо З.

Я спробував запустити це і наткнувся на наступну помилку: o += a.split(', ')[0]не залишає місця між номерами.
Будь ласка, продовжуйте

@PleaseStand Я це виправив, але думаю, що перевірена версія закінчиться помилкою, оскільки конкуренція закінчилася.
kitcar2000

Так, ваш код створював помилку, коли я його запускав, і я не міг зрозуміти, як його виправити. Хоча це було трохи краще, ніж Ледачий.
Джо З.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.