To zadanie jest częścią First Periodic Premier Programming Puzzle Push i ma na celu demonstrację nowej propozycji typu wyzwanie króla wzgórza .
Zadanie polega na napisaniu programu, który lepiej rozwiąże dylemat więźnia niż inni uczestnicy.
Spójrz, Vinny. Znamy twojego kolegę z celi - jak on się nazywa? Tak, McWongski, Nippo-irlandzko-ukraiński gangster - coś knuje i wiesz, co to jest.
Próbujemy być tutaj mili, Vinnie. Daje ci szansę.
Jeśli powiesz nam, co planuje, zobaczymy, że dostałeś dobre zadanie.
A jeśli nie ...
Zasady gry
- Konkurs składa się z pełnego rundy (wszystkie możliwe parowania) dwóch zawodników jednocześnie (w tym gry własnej).
- Rozgrywa się 100 rund między każdą parą
- W każdej rundzie każdy gracz jest proszony o wybór pomiędzy współpracą z innym graczem lub zdradzeniem go, bez znajomości intencji innych graczy w tej sprawie, ale z pamięcią wyników poprzednich rund rozgrywanych z tym przeciwnikiem.
- Punkty są przyznawane za każdą rundę na podstawie połączonego wyboru. Jeśli obaj gracze współpracują, każdy otrzymuje 2 punkty. Wzajemna zdrada daje po 1 punkcie. W przypadku mieszanym zdradzający gracz otrzymuje 4 punkty, a kooperator zostaje ukarany 1.
- „Oficjalny” mecz zostanie rozegrany nie wcześniej niż 10 dni po opublikowaniu wszystkich zgłoszeń, które mogę zabrać do pracy i zostaną użyte do wybrania „zaakceptowanego” zwycięzcy. Mam system Mac OS 10.5, więc rozwiązania POSIX powinny działać, ale istnieją linuksizmy, które nie działają. Podobnie nie mam wsparcia dla interfejsu API win32. Chcę podjąć podstawowy wysiłek, aby zainstalować rzeczy, ale jest pewien limit. Granice mojego systemu w żaden sposób nie reprezentują granic akceptowalnych odpowiedzi, po prostu te, które zostaną uwzględnione w „oficjalnym” meczu.
Interfejs programisty
- Wpisy powinny mieć postać programów, które można uruchamiać z wiersza poleceń; decyzja musi być (jedynym!) wyjściem programu na standardowe wyjście. Historia poprzednich rund z tym przeciwnikiem zostanie przedstawiona jako argument wiersza poleceń.
- Wyjście to „c” (dla clam up ) lub „t” (dla Tell all ).
- Historia jest pojedynczym ciągiem znaków reprezentujących poprzednie rundy, przy czym najnowsze rundy pojawiają się najwcześniej w ciągu. Postacie są
- „K” (dla zachowania wiary oznacza wzajemną współpracę)
- „R” (dla szczura b @ st @ rd mnie wyprzedał! )
- „S” (dla frajera! Co oznacza, że skorzystałeś ze zdrady)
- „E” (bo wszyscy szukają numer jeden na wzajemnej zdradzie)
Wspornik
Autor zapewni czterech graczy
- Anioł - zawsze współpracuje
- Diabeł - zawsze mówi
- TitForTat - Współpracuje w pierwszej rundzie, a następnie zawsze robi to, co zrobił w ostatniej rundzie
- Losowo - 50/50
do którego dodam wszystkie wpisy, które mogę uruchomić.
Całkowity wynik będzie sumą punktów przeciwko wszystkim przeciwnikom (w tym samobójstwom tylko raz i przy użyciu średniego wyniku).
Uczestnicy
(aktualny od 2 maja 2011 r. 7:00)
Tajny uścisk dłoni | Pocisk anty-T42T | Nieufność (wariant) | Anti-Handshake | Mały Lisper | Konwergencja | Rekin | Probabimatic | Pavlov - Win Stay, Lose Switch | Honor Wśród Złodziei | Pomóż wampirowi | Druid | Mały Schemer | Bygones | Tit for Two Tats | Simpleton |
Markier
#! /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
- Skargi dotyczące mojego okropnego pytona są mile widziane, ponieważ jestem pewien, że jest to do bani więcej niż jeden sposób
- Mile widziane poprawki błędów
Dziennik zmian strzelców:
- Wydrukuj posortowanych graczy i wyniki oraz ogłosić zwycięzcę (4/29, Casey)
- Opcjonalnie uruchom wiele turniejów (
./score warriors/ num_tournaments)
) domyślnie = 1, wykryj i skompiluj źródła python (4/29, Casey) - Napraw szczególnie głupi błąd, w którym drugiemu graczowi podawano nieprawidłową historię. (4/30, dmckee; dzięki Josh)
Początkowi wojownicy
Przykładowo, aby wyniki mogły zostać zweryfikowane
Anioł
#include <stdio.h>
int main(int argc, char**argv){
printf("c\n");
return 0;
}
lub
#!/bin/sh
echo c
lub
#!/usr/bin/python
print 'c'
Diabeł
#include <stdio.h>
int main(int argc, char**argv){
printf("t\n");
return 0;
}
Losowy
#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;
}
Należy pamiętać, że sekretarz może wielokrotnie przywoływać wojownika w ciągu jednej sekundy, dlatego należy podjąć poważny wysiłek, aby zapewnić losowość wyników, jeśli czas zostanie wykorzystany do zainicjowania 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;
}
Pierwszy, który faktycznie ma coś wspólnego z historią.
Uruchamianie sekretarza tylko na podanych wojownikach daje
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)
Ten diabeł jest rzemieślnikiem, a sympatyczni faceci najwyraźniej wchodzą ostatni.
Wyniki
„oficjalnego” biegu
('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)
na return (s1, L1+h1), (s2, L2+h2)
[Uwaga L2+h2
zamiast L2+h1
na końcu]? // Błąd wycinania i wklejania lub coś równie idiotycznego. Do licha!