In Imperial China, ranks in society were not decided by birth or wealth, but by a person's ability to excel in the Imperial Examinations. The Jade Emperor, divine ruler of the Heavens, has called for all his subjects to be examined to determine their worth, and whom to next give the Divine Mandate to rule China.
Rules of the Bureaucracy:
- The Divine Bureaucracy consists of non-negative integer-valued ranks, starting with 0. Each member (bot) of the bureaucracy belongs to one rank. Each rank can hold arbitrary many members, but can't be empty unless all ranks above are empty
- At the start of the game, all members have rank 0
- Every turn, each member of the bureaucracy has to answer an exam. The exam consist of correctly guessing the boolean values of a list. The length of the list is the number of the rank above the member.
- The exam questions are prepared by a random member of the rank above. Members of the highest rank get their questions directly from the
JadeEmperor
(see below) - A member scoring at least 50% on their exam is eligible for Promotion. A member scoring less than 50% on their exam is eligible for Demotion.
- A member eligible for Demotion has their rank decreased by one only if there is a member eligible for Promotion on the rank below to take their place.
- All members eligible for Promotion have their rank increased by one as long as this leaves no rank empty.
- If not all eligible members can be Demoted or Promoted, the preference goes to those of lowest (for Demotion) resp. highest (for Promotion) score. Ties are broken randomly.
- The rank of a member can only change by at most 1 each turn.
Rules of the game:
- Each bot will be randomly assigned an ID at the start of the game, which will not change over its course. The
JadeEmperor
has the ID -1, all others have consecutive non-negative IDs, starting with 0. - All bots compete at the same time
- The game runs for 100 turns, the score of the bot is its average rank possessed over that time.
- Total score is acquired by running 1000 games and averaging the results.
- Each Bot is a Python 3 class implementing the following four functions:
ask(self,n,ID)
, which makes an exam by returning alist
of Booleans of length n. ID is the ID of the bot who has to guess that list.ask()
can be called many times during a single round for any bot, but also not at all.answer(self,n,ID)
, which is an attempt to answer an exam by returning alist
of Booleans of length n. ID is the ID of the bot whoseask()
generated the exam.answer()
is called exactly once per round for each bot.update(self,rankList,ownExam,otherExams)
is called once the Controller has performed all Pro- and Demotions. Its arguments are: A list of integers, listing all ranks by ID of all bots; a tuple, consisting of two lists, first the exam questions, then the answers the bot gave (in case it forgot); then a list of tuples, similarly consisting of exam-answer pairs, this time for all exams the bot handed out.__init__(self, ID, n)
passes the bot its own ID and the number of competing bots.
- Classes are allowed to implement other functions for private use
- Defining further variables and using them to store data about past exams is explicitly allowed.
- Programming meta-effects are forbidden, meaning any attempts to directly access other bots' code, the Controller's code, causing Exceptions or similar. This is a contest of strategies for the exams, not of code hacking.
- Bots trying to help each other are explicitly allowed, as long as they don't do it via meta-effects, but purely by the information passed through
update()
- Other languages are allowed only in case they can be easily converted to Python 3.
- The library numpy will be imported as
np
. The version is 1.6.5, meaning it uses the old random library. If you have numpy 1.7, the old functions are available undernumpy.random.mtrand
for testing. Please remember to strip the mtrand for submission. - If a bot causes an Exception during runtime, it is disqualified. Any bot whose code is so obfuscated that it's impossible to tell if it generates a list of length n when
ask()
oranswer()
is called will also be disqualified preemptively. A bot forcing me to deep-copy outputs gets -1 on the score. - Class names have to be unique
- Multiple bots per person are allowed, but only the latest version will be taken of iteratively updated bots.
- Since there seems to be some confusion about bot similarity:
- You are not allowed to post a copy of another bot. This is the only Standard Loophole which really applies in this challenge.
- You are allowed to have shared code with other bots, including bots of other people.
- You are not allowed to submit a bot which differs from another only by a trivial change to the strategy (like a change in the seed for the question generation) unless you can prove that the number of such carbon copy bots is the minimum required for successful enactment of their strategy (That will usually be two bots for a cooperation).
Example Bots:
The JadeEmperor
is always part of the game, but does not compete; he serves as generator for exams of highest-rank bots. His exams are random, but not uniformly, to allow smart bots a way to advance.
class JadeEmperor:
def __init__(self):
pass
def ask(self,n,ID):
num=min(np.random.exponential(scale=np.sqrt(np.power(2,n))),np.power(2,n)-1)
bi=list(np.binary_repr(int(num),width=n))
return [x=='0' for x in bi]
The Drunkard produces exams and answers completely randomly. He will be part of the game.
class Drunkard:
def __init__(self,ID,n):
pass
def ask(self,n,ID):
return list(np.random.choice([True,False],size=n,replace=True))
def answer(self,n,ID):
return list(np.random.choice([True,False],size=n,replace=True))
def update(self,rankList,ownExam,otherExams):
pass #out
The Plagiarist just copies previous exams. He will also be part of the game.
class Plagiarist:
def __init__(self,ID,n):
self.exam=[True]
def ask(self,n,ID):
return (self.exam*n)[0:n]
def answer(self,n,ID):
return (self.exam*n)[0:n]
def update(self,rankList,ownExam,otherExams):
self.exam=ownExam[0]
Controller code available here. For testing, you can put your own class into a Contestants.py file in the same folder, and they will be imported.
Chatroom can be found here.
The Examinations begin!
Current score, in higher precision (10000 runs) for Oct20:
$$ \begin{array}{|c|c|c|}\hline \textbf{Entrant}&\textbf{Author}&\textbf{Score}\\\hline % \text{Alpha}&\text{Sleafar}&9.669691\\ \hline \text{Gamma}&\text{Sleafar}&9.301362\\ \hline \text{Beta}&\text{Sleafar}&9.164597\\ \hline \text{WiQeLu}&\text{Purple P}&7.870821\\ \hline \text{StudiousBot}&\text{Dignissimus - Spammy}&7.538537\\ \hline \text{Santayana}&\text{Sara J}&7.095528\\ \hline \text{Plagiarist}&\text{}&6.522047\\ \hline \text{CountOracular}&\text{IFcoltransG}&5.881175\\ \hline \text{Thomas}&\text{Alien@System}&5.880041\\ \hline \text{Contrary}&\text{Draco18s}&5.529652\\ \hline \text{Marx}&\text{sugarfi}&5.433808\\ \hline \text{Drunkard}&\text{}&5.328178\\ \hline \text{YinYang}&\text{Purple P}&5.102519\\ \hline \text{Equalizer}&\text{Mnemonic}&4.820996\\ \hline \text{TitForTat}&\text{Anonymous}&3.35801\\ \hline \end{array}$$
Contests will be run with each new entry for the foreseeable future.
ID, n
but the other method argumentsn, ID
? \$\endgroup\$