Эта задача является частью первого периодического премьер - программирования головоломка Пуш и предназначена как демонстрация нового короля-оф-хилл вызов типа предложения .
Задача состоит в том, чтобы написать программу, которая сыграет дилемму повторного заключенного лучше, чем другие участники.
Смотри, Винни. Мы знаем твоего сокамерника --- как его зовут? Да, МакВонгски, иппо-ирландско-украинский бандит - что-то замышляет, и вы знаете, что это такое.
Мы стараемся быть милыми здесь, Винни. Предоставляю тебе шанс.
Если вы скажете нам, что он планирует, мы увидим, что вы получите хорошую работу.
И если ты не ...
Правила игры
- Конкурс состоит из полной круговой игры (все возможные пары) двух участников одновременно (включая самостоятельные игры).
- Между каждой парой сыграно 100 раундов
- В каждом раунде каждого игрока просят выбрать между сотрудничеством с другим игроком или предательством, не зная намерений других игроков в этом вопросе, но имея в виду результаты предыдущих раундов, сыгранных против этого противника.
- Очки начисляются за каждый раунд на основе комбинированного выбора. Если оба игрока сотрудничают, они получают по 2 очка. Взаимное предательство приносит 1 очко каждому. В смешанном случае предающему игроку присуждается 4 очка, а соучастнику штрафуется 1.
- «Официальный» матч будет проведен не ранее, чем через 10 дней после публикации всех заявок, которые я смогу получить на работу и использовать для выбора «принятого» победителя. У меня есть Mac OS 10.5, поэтому решения POSIX должны работать, но есть linuxisms, которые не работают. Кроме того, у меня нет поддержки Win32 API. Я готов приложить основные усилия, чтобы установить вещи, но есть предел. Пределы моей системы никоим образом не представляют собой пределы приемлемых ответов, просто те, которые будут включены в «официальный» матч.
Интерфейс программиста
- Записи должны быть в форме программ, которые можно запускать из командной строки; Решение должно (единственный!) вывод программы на стандартный вывод. История предыдущих раундов с этим противником будет представлена в качестве аргумента командной строки.
- Вывод либо «с» (для моллюска ) или «т» (для все ).
- История представляет собой единую строку символов, представляющую предыдущие раунды, причем самые последние раунды будут самыми ранними в строке. Персонажи
- «К» (для сохранения веры означает взаимное сотрудничество)
- "R" (для крысы b @ st @ rd продал меня! )
- «S» (для присоски! Означает, что вы выиграли от предательства)
- «Е» (потому что каждый ищет взаимного предательства)
Кронштейн
Четыре игрока будут предоставлены автором
- Ангел - всегда сотрудничает
- Дьявол - всегда говорит
- TitForTat - сотрудничает в первом раунде, затем всегда делает то, что сделал в последнем раунде
- Случайный - 50/50
к которому я добавлю все записи, которые я могу запустить.
Общая оценка будет суммой очков против всех оппонентов (включая самостоятельные игры только один раз и с использованием средней оценки).
Абитуриенты
(по состоянию на 2 мая 2011 г. 7:00)
Тайное рукопожатие | Анти-Т42Т Ракета | Недоверие (вариант) | Анти-рукопожатие | Маленький Лиспер | Сходимость | Акула | Вероятностный | Павлов - Win Stay, Lose Switch | Честь среди воров | Помогите вампиру | Друид | Маленький интриган | Прошлое | Синица для двух татов | Простак |
маркер
#! /usr/bin/python
#
# Iterated prisoner's dilemma King of Hill Script Argument is a
# directory. We find all the executables therein, and run all possible
# binary combinations (including self-plays (which only count once!)).
#
# Author: dmckee (https://codegolf.stackexchange.com/users/78/dmckee)
#
import subprocess
import os
import sys
import random
import py_compile
###
# config
PYTHON_PATH = '/usr/bin/python' #path to python executable
RESULTS = {"cc":(2,"K"), "ct":(-1,"R"), "tc":(4,"S"), "tt":(1,"E")}
def runOne(p,h):
"""Run process p with history h and return the standard output"""
#print "Run '"+p+"' with history '"+h+"'."
process = subprocess.Popen(p+" "+h,stdout=subprocess.PIPE,shell=True)
return process.communicate()[0]
def scoreRound(r1,r2):
return RESULTS.get(r1[0]+r2[0],0)
def runRound(p1,p2,h1,h2):
"""Run both processes, and score the results"""
r1 = runOne(p1,h1)
r2 = runOne(p2,h2)
(s1, L1), (s2, L2) = scoreRound(r1,r2), scoreRound(r2,r1)
return (s1, L1+h1), (s2, L2+h2)
def runGame(rounds,p1,p2):
sa, sd = 0, 0
ha, hd = '', ''
for a in range(0,rounds):
(na, ha), (nd, hd) = runRound(p1,p2,ha,hd)
sa += na
sd += nd
return sa, sd
def processPlayers(players):
for i,p in enumerate(players):
base,ext = os.path.splitext(p)
if ext == '.py':
py_compile.compile(p)
players[i] = '%s %sc' %( PYTHON_PATH, p)
return players
print "Finding warriors in " + sys.argv[1]
players=[sys.argv[1]+exe for exe in os.listdir(sys.argv[1]) if os.access(sys.argv[1]+exe,os.X_OK)]
players=processPlayers(players)
num_iters = 1
if len(sys.argv) == 3:
num_iters = int(sys.argv[2])
print "Running %s tournament iterations" % (num_iters)
total_scores={}
for p in players:
total_scores[p] = 0
for i in range(1,num_iters+1):
print "Tournament %s" % (i)
scores={}
for p in players:
scores[p] = 0
for i1 in range(0,len(players)):
p1=players[i1];
for i2 in range(i1,len(players)):
p2=players[i2];
# rounds = random.randint(50,200)
rounds = 100
#print "Running %s against %s (%s rounds)." %(p1,p2,rounds)
s1,s2 = runGame(rounds,p1,p2)
#print (s1, s2)
if (p1 == p2):
scores[p1] += (s1 + s2)/2
else:
scores[p1] += s1
scores[p2] += s2
players_sorted = sorted(scores,key=scores.get)
for p in players_sorted:
print (p, scores[p])
winner = max(scores, key=scores.get)
print "\tWinner is %s" %(winner)
total_scores[p] += 1
print '-'*10
print "Final Results:"
players_sorted = sorted(total_scores,key=total_scores.get)
for p in players_sorted:
print (p, total_scores[p])
winner = max(total_scores, key=total_scores.get)
print "Final Winner is " + winner
- Жалобы на мой ужасный питон приветствуются, так как я уверен, что это отстой более чем один способ
- Исправления ошибок приветствуются
История изменений бомбардира:
- Распечатайте отсортированных игроков и результаты и объявите победителя (4/29, Кейси)
- При желании можно запустить несколько турниров (по
./score warriors/ num_tournaments)
умолчанию = 1), обнаружить и скомпилировать исходники Python (4/29, Кейси) - Исправлена ошибка, из-за которой второму игроку передавали неверную историю. (4/30, dmckee; спасибо, Джош)
Начальные воины
В качестве примера и так, чтобы результаты могли быть проверены
ангел
#include <stdio.h>
int main(int argc, char**argv){
printf("c\n");
return 0;
}
или
#!/bin/sh
echo c
или
#!/usr/bin/python
print 'c'
дьявол
#include <stdio.h>
int main(int argc, char**argv){
printf("t\n");
return 0;
}
случайный
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
int main(int argc, char**argv){
srandom(time(0)+getpid());
printf("%c\n",(random()%2)?'c':'t');
return 0;
}
Обратите внимание, что бомбардир может повторно вызывать воина много раз за одну секунду, поэтому необходимо предпринять серьезные усилия для обеспечения случайности результатов, если время используется для посева PRNG.
TitForTat
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char**argv){
char c='c';
if (argv[1] && (
(argv[1][0] == 'R') || (argv[1][0] == 'E')
) ) c='t';
printf("%c\n",c);
return 0;
}
Первый, который действительно что-то делает с историей.
Запуск бомбардира только на предоставленных воинах
Finding warriors in warriors/
Running warriors/angel against warriors/angel.
Running warriors/angel against warriors/devil.
Running warriors/angel against warriors/random.
Running warriors/angel against warriors/titfortat.
Running warriors/devil against warriors/devil.
Running warriors/devil against warriors/random.
Running warriors/devil against warriors/titfortat.
Running warriors/random against warriors/random.
Running warriors/random against warriors/titfortat.
Running warriors/titfortat against warriors/titfortat.
('warriors/angel', 365)
('warriors/devil', 832)
('warriors/random', 612)
('warriors/titfortat', 652)
Этот дьявол, он мастерский, и хорошие парни, очевидно, приходят последними.
Полученные результаты
"официального" забега
('angel', 2068)
('helpvamp', 2295)
('pavlov', 2542)
('random', 2544)
('littleschemer', 2954)
('devil', 3356)
('simpleton', 3468)
('secrethandshake', 3488)
('antit42t', 3557)
('softmajo', 3747)
('titfor2tats', 3756)
('convergence', 3772)
('probabimatic', 3774)
('mistrust', 3788)
('hyperrationalwasp', 3828)
('bygones', 3831)
('honoramongthieves', 3851)
('titfortat', 3881)
('druid', 3921)
('littlelisper', 3984)
('shark', 4021)
('randomSucker', 4156)
('gradual', 4167)
Winner is ./gradual
return (s1, L1+h1), (s2, L2+h1)
на return (s1, L1+h1), (s2, L2+h2)
[Примечание, L2+h2
а L2+h1
не в конце]? // Ошибка «вырезать и вставить» или что-то такое же идиотское. Sheesh!