Die himmlische Bürokratie KoTH


14

Im kaiserlichen China wurden Ränge in der Gesellschaft nicht durch Geburt oder Reichtum bestimmt, sondern durch die Fähigkeit einer Person, bei den kaiserlichen Prüfungen hervorragende Leistungen zu erbringen. Der Jadekaiser, der göttliche Herrscher des Himmels, hat alle seine Untertanen aufgefordert, auf ihren Wert hin untersucht zu werden und wem als Nächstes das göttliche Mandat zu erteilen, um China zu regieren.

Regeln der Bürokratie:

  • Die Göttliche Bürokratie besteht aus nicht negativen ganzzahligen Rängen, die mit 0 beginnen. Jedes Mitglied (Bot) der Bürokratie gehört einem Rang an. Jeder Rang kann beliebig viele Mitglieder enthalten, kann aber nur leer sein, wenn alle darüber liegenden Ränge leer sind
  • Zu Beginn des Spiels haben alle Mitglieder den Rang 0
  • In jeder Runde muss jedes Mitglied der Bürokratie eine Prüfung beantworten. Die Prüfung besteht darin, die Booleschen Werte einer Liste richtig zu erraten. Die Länge der Liste ist die Nummer des Ranges über dem Mitglied.
  • Die Prüfungsfragen werden von einem zufälligen Mitglied des obigen Ranges vorbereitet. Mitglieder mit dem höchsten Rang erhalten ihre Fragen direkt von der JadeEmperor(siehe unten)
  • Ein Mitglied, das bei seiner Prüfung mindestens 50% erreicht, ist zur Promotion berechtigt. Ein Mitglied, das bei seiner Prüfung weniger als 50% erzielt, hat Anspruch auf Herabstufung.
  • Ein Mitglied, das für eine Herabstufung in Frage kommt, wird nur dann um eins herabgesetzt, wenn es ein Mitglied gibt, das für eine Herabstufung in Frage kommt, um seinen Platz einzunehmen.
  • Alle beförderungsberechtigten Mitglieder haben einen um eins erhöhten Rang, sofern dadurch kein Rang frei bleibt.
  • Wenn nicht alle berechtigten Mitglieder herabgestuft oder befördert werden können, werden die niedrigsten (für Herabstufung) bzw. niedrigsten Mitglieder bevorzugt. Höchste (für Promotion) Punktzahl. Krawatten werden zufällig gebrochen.
  • Der Rang eines Mitglieds kann sich nur um höchstens 1 pro Runde ändern.

Spielregeln:

  • Jedem Bot wird zu Beginn des Spiels zufällig eine ID zugewiesen, die sich im Laufe des Spiels nicht ändert. Der JadeEmperorhat die ID -1, alle anderen haben aufeinanderfolgende nicht negative IDs, beginnend mit 0.
  • Alle Bots treten gleichzeitig an
  • Das Spiel läuft über 100 Runden, die Punktzahl des Bots ist der durchschnittliche Rang, den er in dieser Zeit innehatte.
  • Die Gesamtpunktzahl wird durch Ausführen von 1000 Spielen und Mitteln der Ergebnisse ermittelt.
  • Jeder Bot ist eine Python 3- Klasse, die die folgenden vier Funktionen implementiert:
    • ask(self,n,ID), der eine Prüfung durch Rückgabe eines listBooleschen Wertes der Länge n durchführt. ID ist die ID des Bots, der diese Liste erraten muss. ask()kann in einer Runde für jeden Bot mehrmals aufgerufen werden, aber auch gar nicht.
    • answer(self,n,ID)listDies ist ein Versuch, eine Prüfung zu beantworten, indem ein Boolescher Wert der Länge n zurückgegeben wird. ID ist die ID des Bots ask(), der die Prüfung generiert hat. answer()wird genau einmal pro Runde für jeden Bot aufgerufen.
    • update(self,rankList,ownExam,otherExams)wird aufgerufen, sobald der Controller alle Vor- und Zurückstufungen durchgeführt hat. Die Argumente sind: Eine Liste von ganzen Zahlen, in der alle Ränge nach ID aller Bots aufgelistet sind; ein Tupel, bestehend aus zwei Listen, zuerst die Prüfungsfragen, dann die Antworten, die der Bot gegeben hat (falls er sie vergessen hat); dann eine Liste von Tupeln, die ebenfalls aus Prüfungs-Antwort-Paaren besteht, diesmal für alle Prüfungen, die der Bot austeilt.
    • __init__(self, ID, n) Übergibt dem Bot seine eigene ID und die Anzahl der konkurrierenden Bots.
  • Klassen dürfen andere Funktionen für den privaten Gebrauch implementieren
  • Das Definieren weiterer Variablen und deren Verwendung zum Speichern von Daten über vergangene Prüfungen ist ausdrücklich gestattet.
  • Das Programmieren von Metaeffekten ist verboten, dh es wird versucht, direkt auf den Code anderer Bots, den Code des Controllers, zuzugreifen, was Ausnahmen oder ähnliches zur Folge hat. Dies ist ein Wettbewerb von Strategien für die Prüfungen, nicht von Code-Hacking.
  • Bots, die versuchen, sich gegenseitig zu helfen, sind ausdrücklich erlaubt, solange sie dies nicht über Metaeffekte, sondern nur über die übermittelten Informationen tun update()
  • Andere Sprachen sind nur zulässig, wenn sie leicht in Python 3 konvertiert werden können.
  • Die Bibliotheksnummer wird importiert als np. Die Version ist 1.6.5, dh es wird die alte Zufallsbibliothek verwendet. Wenn Sie numpy 1.7 haben, stehen Ihnen die alten Funktionen unter numpy.random.mtrandzum Testen zur Verfügung. Bitte denken Sie daran, den mtrand für die Einreichung abzustreifen.
  • Wenn ein Bot während der Laufzeit eine Ausnahme verursacht, wird er disqualifiziert. Jeder Bot, dessen Code so verschleiert ist, dass nicht zu erkennen ist, ob er beim Aufruf eine Liste mit der Länge n generiert, ask()oder ob er answer()aufgerufen wird, wird ebenfalls präventiv disqualifiziert. Ein Bot, der mich zum Kopieren von Ausgaben zwingt, erhält -1 für die Punktzahl.
  • Klassennamen müssen eindeutig sein
  • Es sind mehrere Bots pro Person zulässig, von iterativ aktualisierten Bots wird jedoch nur die neueste Version verwendet.
  • Da es einige Verwirrung über die Ähnlichkeit der Bot zu geben scheint:
    • Du darfst keine Kopie eines anderen Bots posten. Dies ist die einzige Standard-Lücke, die für diese Herausforderung wirklich gilt.
    • Sie dürfen Code mit anderen Bots teilen, einschließlich Bots anderer Personen.
    • Du darfst nicht , einen Bot einzureichen, der sich von einem anderen nur durch eine geringfügige Änderung der Strategie unterscheidet (wie eine Änderung des Ausgangs für die Generierung von Fragen), es sei denn Sie können nachweisen, dass die Anzahl solcher Bots für eine erfolgreiche mindestens so hoch ist Umsetzung ihrer Strategie (Das sind normalerweise zwei Bots für eine Kooperation).

Beispiel Bots:

Das JadeEmperor ist immer Teil des Spiels, konkurriert aber nicht; Er dient als Generator für Prüfungen von Bots mit dem höchsten Rang. Seine Prüfungen sind zufällig, aber nicht einheitlich, damit intelligente Bots vorankommen können.

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]

Der Säufer erstellt Prüfungen und antwortet völlig zufällig. Er wird Teil des Spiels sein.

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

Der Plagiat kopiert nur frühere Prüfungen. Er wird auch Teil des Spiels sein.

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 verfügbar hier . Zum Testen können Sie Ihre eigene Klasse in eine Contestants.py-Datei in demselben Ordner einfügen, und sie werden importiert.

Chatroom kann gefunden werden hier .

Die Prüfungen beginnen!

Aktuelle Punktzahl in höherer Präzision (10000 Läufe) für den 20. Oktober:

TeilnehmerAutorErgebnisAlphaSleafar9.669691GammaSleafar9.301362BetaSleafar9.164597WiQeLuLila P7.870821StudiousBotDignissimus - Spammy7.538537SantayanaSara J7.095528Plagiator6.522047CountOracularIFcoltransG5,881175ThomasAlien @ System5.880041GegenteilDraco18s5.529652Marxsugarfi5.433808Säufer5.328178Yin-YangLila P5.102519EqualizerGedächtnisstütze4.820996Wie du mir so ich dirAnonym3.35801

Mit jedem neuen Beitrag werden auf absehbare Zeit Wettbewerbe durchgeführt.


1
Kopien von Bots sind eine Standardlücke, also nein. Wenn Sie versuchen, die Regel "Mehrere Bots pro Autor" zu missbrauchen, indem Sie fast, aber keine vollständigen Kopien einreichen, werde ich sie entfernen.
AlienAtSystem

1
@AlienAtSystem Warum erlauben Sie Bots, sich gegenseitig zu helfen? Es scheint nur mehr Chaos und Zufälligkeit zu geben.
Don Thousand

2
Warum sind die Konstruktorargumente ID, ndie anderen Methodenargumente n, ID?
Lila P

1
@DonThousand, weil ich der Meinung bin, dass es unter den gegebenen Bedingungen eine ziemliche Leistung ist, zwei Bots zu erstellen, die A) erfolgreich per Handshake (beachten Sie, dass der Plagiarizer versehentlich einen Mann in der Mitte spielt) und B) dann eine Strategie entwickeln, die diesem Bot zuverlässig hilft aber kein anderer zu erheben.
AlienAtSystem

1
@jemand zählt aufwärts. Sie beginnen bei 0 und arbeiten sich zu höheren Zahlen vor
AlienAtSystem

Antworten:


4

Santayana

Diejenigen, die sich nicht an die Vergangenheit erinnern können, sind dazu verdammt, sie zu wiederholen. Wir treffen unsere Entscheidungen auf der Grundlage des Verhaltens der anderen in der Vergangenheit, antworten auf der Grundlage der Antwort, die der Fragesteller normalerweise von uns bei einem bestimmten Index erwartet hat, und fragen nach der Antwort, die er uns bei einem bestimmten Index am seltensten gegeben hat .

import numpy as np

class Santayana:
    """
    Those who cannot remember the past are condemned to repeat it
    """
    def __init__(self, ID, num_competitors):
        self.ID = ID
        self.exams_taken = {}
        self.exams_issued = {}
        self.last_exam_asker = None
        self.recent_exam_takers = []

        for i in range(num_competitors):
            self.exams_taken[i] = []
            self.exams_issued[i] = []

    def ask(self, length, taker_ID):
        # Remember who asked
        self.recent_exam_takers.append(taker_ID)
        new_exam = []

        # At every index, expect the answer they've given the least often (default to False if equal)
        for i in range(length):
            trues = 0
            falses = 0
            for exam in self.exams_issued[taker_ID]:
                if len(exam) <= i: continue
                if exam[i]:
                    trues += 1
                else:
                    falses += 1
            new_exam.append(trues < falses)
        return new_exam

    def answer(self, num_answers, asker_ID):
        self.last_exam_asker = asker_ID
        if asker_ID == -1:
            # Copy emperor's process to hopefully get a similar exam
            num = min(np.random.exponential(scale=np.sqrt(np.power(2,num_answers))),np.power(2,num_answers)-1)
            as_bin = list(np.binary_repr(int(num),width=num_answers))
            return [x=='0' for x in as_bin]
        else:
            new_answer = []

            # At every index, give the answer that's been correct the greatest number of times (default to True if equal)
            for i in range(num_answers):
                trues = 0;
                falses = 0;
                for exam in self.exams_taken[asker_ID]:
                    if len(exam) <= i: continue
                    if exam[i]:
                        trues += 1
                    else:
                        falses += 1
                new_answer.append(trues >= falses)
            return new_answer

        return [True for i in range(num_answers)]

    def update(self, rank_list, own_exam, other_exams):
        if self.last_exam_asker > -1:
            # Save the exam we took, unless it was from the Emperor - we already know how he operates
            self.exams_taken[self.last_exam_asker].append(own_exam[0])
        for i in range(len(self.recent_exam_takers)):
            # Save the responses we got
            self.exams_issued[i].append(other_exams[i][1])

        self.recent_exam_takers = []

3

Fleißiger Bot

Dieser Bot studiert zu Testzwecken! Es versucht, Muster in Tests zu finden, die von verschiedenen Bots ausgegeben werden, und verhält sich entsprechend.

Meiner Meinung nach übertrifft dieser Bot bisher alle anderen Bots, die ich auf meinem Computer zum Arbeiten bringen könnte, mit Ausnahme von Alpha, Beta und Gamma (die für die Zusammenarbeit programmiert wurden). Der Bot macht sich die Tatsache nicht zunutze, dass Teaming erlaubt ist, weil ich das Gefühl hatte, dass es ein bisschen wie Schummeln und etwas schmutzig war. Wenn man sich das ansieht, scheint Teaming ziemlich effektiv zu sein.

Der Bot versucht zu erkennen, wann die Antworten auf die Tests zufällig sind, und als Reaktion darauf entspricht dies hoffentlich einem Durchschnitt von 50% der Tests.

Der Bot versucht auch zu erkennen, wann ein Bot nur seine Antworten umgedreht hat, um andere Bots abzuwerfen, die versuchen, ihr Verhalten vorherzusagen.

Ich habe den Code mit einigen Kommentaren versehen, um die Lesbarkeit zu verbessern

import random
import numpy as np


class StudiousBot:
    GRAM_SIZE = 5
    def __init__(self, identifier, n):
        self.id = identifier
        self.ranks = {i: 0 for i in range(n)} # Stores ranks
        self.study_material = {i: [] for i in range(n)} # Stores previous exam data
        self.distribution = {i: [] for i in range(n)} # Stores the percentage of answers that were `True` on a Bot's tests over time
        self.last_examiner = None

    def ask(self, n, identifier):
        # This bot gives random tests, it doesn't bother making them difficult based on answers to them
        # The reason for this is that I can't personalise the tests for each bot
        return [random.choice([True, False]) for i in range(n)] 

    def answer(self, n, examiner_id):
        self.last_examiner = examiner_id
        if examiner_id == -1:
            return StudiousBot.answer_emperor(n) # Easy win, I know the distribution of answers for the Emperor's tests

        bother_predicting = True # Whether or not the Bot will attempt to predict the answers to the exam
        study_material = self.study_material[examiner_id]
        distribution = self.distribution[examiner_id]
        if len(distribution) > 0: # If there is actually data to analyse
            sd = StudiousBot.calculate_standard_deviation(distribution)
            normalised_sd = StudiousBot.calculate_normalised_standard_deviation(distribution)

            if abs(30 - sd) < 4: # 30 is the expected s.d for a random distribution
                bother_predicting = False # So I won't bother predicting the test 

            if abs(sd - normalised_sd * 2) > 4: # The bot is merely inverting answers to evade being predicted
                pass # However, at this time, I'm not certain how I should deal with this. I'll continue to attempt to predict the test 


        if bother_predicting and len(study_material) >= StudiousBot.GRAM_SIZE:
            return StudiousBot.predict(study_material, n)

        return [random.choice([True, False]) for i in range(n)]

    def predict(study_material, n): # Predicts the answers to tests with `n` questions
        grams = StudiousBot.generate_ngrams(study_material, StudiousBot.GRAM_SIZE) # Generate all n-grams for the study material
        last_few = study_material[-(StudiousBot.GRAM_SIZE - 1):] # Get the last 9 test answers
        prediction = None
        probability = -1
        for answer in [True, False]: # Finds the probabiility of the next answer being True or False, picks the one with the highest probability
            new_prediction = last_few + [answer]
            new_probability = grams.count(new_prediction)         

            if new_probability > probability:
                prediction = answer
                probability = new_probability

        if n == 1:
            return [prediction]

        return [prediction] + StudiousBot.predict(study_material + [prediction], n-1)          


    @staticmethod
    def calculate_standard_deviation(distribution):
        return np.std(distribution)

    def calculate_normalised_standard_deviation(distribution): # If the answers happen to be inverted at some point, this function will return the same value for answers that occured both before and after this point  
        distribution = list(map(lambda x: 50 + abs(50-x), distribution))
        return StudiousBot.calculate_standard_deviation(distribution)   

    @staticmethod
    def generate_ngrams(study_material, n):
        assert len(study_material) >= n
        ngrams = []
        for i in range(len(study_material) - n + 1):
            ngrams.append(study_material[i:i+n])

        return ngrams

    def update(self, ranks, own_exam, other_exams):
        self.ranks = dict(enumerate(ranks))
        if self.last_examiner != -1:
            self.study_material[self.last_examiner] += own_exam[0]
            self.distribution[self.last_examiner].append(own_exam[0].count(True) / len(own_exam[0]) * 100) # Stores the percentage of the answers which were True

    @staticmethod
    def answer_emperor(n): # Algorithm to reproduce Emperor's distribution of test answers  
        exp = np.random.exponential(scale=np.sqrt(np.power(2,n)))
        power = np.power(2,n) - 1        
        num = min(exp, power)
        bi = list(np.binary_repr(int(num), width=n))
        return [x == '0' for x in bi]

Gemessen an unserer Leistung haben Sie den besten Algorithmus zum Antworten und Wi Qe Lu hat den besten Algorithmus zum Fragen. Ich schlage vor, dass wir unsere Bots in einem einzigen Bot namens Xuézhě (chinesisch für "Gelehrter") kombinieren, der sich zufällig wie "Umschalter" anhört.
Purple P

Ich habe es gehackt und die Untersuchungen auf meiner Maschine durchgeführt. Seltsamerweise übertraf es Studious Bot, aber nicht Wi Qe Lu.
Lila P

@ Lila Haha! Das klingt sehr interessant, ich glaube nicht , dass es genug Zeit für mich , meine Bot zu verbessern , aber man kann es als Vorlage hier posten
Dignissimus - Spammy

3

Graf Oracular

Dieser Bot verwendet einen Algorithmus, der die Prüfungen aller anderen funktionierenden Bots (unter Berücksichtigung der runden Zahl und einiger schrecklicher Heuristiken) mittelt, um zu entscheiden, was jeder andere Bot als Prüfung festlegt.
Der Graf fragt seine Prüfungen mit einem md5-Hash ab. Sowohl seine Fragen als auch seine Antworten sind daher deterministisch. Es ignoriert die meisten Eingaben und fragt und beantwortet genau dieselben Sequenzen von Booleschen, Regen oder Sonnenschein, auch gegen Jade Emporer.

import numpy as np
import hashlib

class CountOracular:
    '''Uses very little external data to make heuristical statistical
    deterministic predictions about the average exam.
    (Assonance not intended.)
    To generate its own exams, uses a deterministic hash.'''
    def __init__(self, id, number_of_bots):
        self.last_round = []
        #functions for calculating what other bots will likely do.
        self.bots_calculators = [
            self._jad, #Jade Emporer
            self._alp, #Alpha
            self._bet, #Beta
            self._gam, #Gamma
            self._wiq, #Wi Qe Lu
            self._stu, #StudiousBot
            self._pla, #Plagiarist
            self._san, #Santayana
            self._tho, #Thomas
            self._dru, #Drunkard
            self._yin, #YinYang
            self._con, #Contrary
            self._tit, #TitForTat
            self._equ, #Equalizer
            self._mar, #Marx
        ]
        self.bot_types = len(self.bots_calculators)
    def ask(self, n, id):
        #if we can, show that hardcoding is no match for the power of heuristics:
        if n == 2:
            return [False, True]
        #otherwise, refer to the wisdom of Mayor Prentiss in order to command The Ask
        #i.e. hashes a quote, and uses that as the exam.
        salt = b"I AM THE CIRCLE AND THE CIRCLE IS ME " * n
        return self._md5_from(salt, n)
    def answer(self, n, id):
        #uses the power of heuristics to predict what the average bot will do
        #ignores all inputs except the length of the output
        #very approximate, and deterministic
        #i.e. every game, Count Oracular will send the same lists of answers, in the same order
        best_guess_totals = [0.5] * n #halfway between T and F
        for bot in self.bots_calculators:
            exam, confidence = bot(n)
            if not exam:
                continue
            while len(exam) < n:
                #ensure exam is long enough
                exam += exam[:1]
            exam = exam[:n] #ensure exam is short enough
            #map T and F to floats [0,1] based on confidence
            weighted_exam = [0.5+confidence*(0.5 if q else -0.5) for q in exam]
            best_guess_totals = [current+new for current,new in zip(best_guess_totals, weighted_exam)]
        best_guess_averages = [total/self.bot_types
            for total
            in best_guess_totals
        ]
        best_guess = [avg > 0.5 for avg in best_guess_averages]
        self.last_round = best_guess
        return best_guess
    def update(self, ranks, own, others):
        pass
    def _md5_from(self, data, n):
        md5 = hashlib.md5(data)
        for i in range(n):
            md5.update(data)
        exam = []
        while len(exam) < n:
            exam += [x == "0"
                for x
                in bin(int(md5.hexdigest(), 16))[2:].zfill(128)
            ]
            md5.update(data)
        return exam[:n]
    def _invert(self, exam):
        return [not val for val in exam]
    def _digits_to_bools(self, iterable):
        return [char=="1" for char in iterable]
    def _plagiarise(self, n):
        copy = (self.last_round * n)[:n]
        return copy

    '''functions to calculate expected exams for each other bot:
       (these values, weighted with corresponding confidence ratings,
       are summed to calculate the most likely exam.)'''
    def _jad(self, n):
        '''Calculate the mean of _jad's distribution, then
        use that as the guess'''
        mean = max(int(np.sqrt(np.power(2,n))), (2<<n)-1)
        string_mean = f"{mean}".zfill(n)
        exam = self._invert(self._digits_to_bools(string_mean))
        return exam, 0.5
    def _alp(self, n):
        '''Alpha uses a predictable hash,
        until it figures out we aren't Beta,
        modelled by the probability of giving or solving
        Alpha's exam'''
        #probability that Alpha thinks we're Beta
        #assuming we fail to pretend to be Beta if we meet Alpha
        chance_beta = ((1 - 1/self.bot_types) ** n) ** 2
        return self._md5_from(b"Beta", n), chance_beta
    def _gam(self, n):
        '''Gamma is like Beta, except after realising,
        switches to 50-50 random choice of inverse
        either Beta or Alpha's hash'''
        #probability that Gamma thinks we're Alpha still
        #(Unlikely that Gamma will think we're Beta;
        #we'd need to fail Alpha but pass Beta,
        #therefore, not accounted for)
        chance_unknown = ((1 - 1/self.bot_types) ** n) ** 2
        #default exam that assumes that Gamma thinks we're Alpha
        exam = self._md5_from(b"Beta", n)
        if chance_unknown > 0.5:#there exists a better heuristic here
            #assume Gamma will consider us Alpha
            confidence = chance_unknown
        else:
            #assume Gamma considers us neither Alpha nor Beta
            alpha = self._invert(self._md5_from(b"Beta", n))
            beta = self._invert(self._md5_from(b"Alpha", n))
            #check for bools where both possible exams match
            and_comp = [a and b for a, b in zip(alpha, beta)]
            nor_comp = [not (a or b) for a, b in zip(alpha, beta)]
            #count up matches vs times when fell back on default
            #to calculate ratio of default
            #to bools where hashes agree
            confidence_vs_default = (sum(and_comp)+sum(nor_comp)) / n
            confidence = confidence_vs_default * chance_unknown + (1 - confidence_vs_default) * (1 - chance_unknown)
            for i in range(n):
                if and_comp[i]:
                    exam[i] = True
                if nor_comp[i]:
                    exam[i] = False
        return exam, confidence
    def _bet(self, n):
        '''Beta is like Alpha, but with a different hash'''
        #probability we haven't matched with Beta yet
        #i.e. probability that Beta still thinks we're Alpha
        chance_alpha = ((1 - 1/self.bot_types) ** n) ** 2
        return self._md5_from(b"Alpha", n), chance_alpha
    def _wiq(self, n):
        '''Wi Qe Lu is hard to model, so we pretend
        that it mimicks Plagiarist for the most part'''
        if n == 1:
            #first round is random
            return [False], 0
        #other rounds are based on exams it met
        #leaning towards same as the previous exam
        return self._plagiarise(n), 0.1
    def _stu(self, n):
        '''StudiousBot is random'''
        return [False] * n, 0
    def _pla(self, n):
        '''Plagiarist copies the exams it received,
        which can be modelled with the standard prediction
        calculated for the previous round, padded with its first
        element.'''
        if n == 1:
            return [True], 1
        return self._plagiarise(n), 0.3
    def _san(self, n):
        '''Santayana is based on answers, which we don't predict.
        Modelled as random.'''
        #mostly random, slight leaning towards default False
        return [False] * n, 0.1
    def _tho(self, n):
        '''Thomas has an unpredictable threshold.'''
        #for all intents, random
        return [False] * n, 0
    def _dru(self, n):
        '''Drunkard is utterly random.'''
        return [False] * n, 0
    def _yin(self, n):
        '''YinYang inverts itself randomly, but not unpredictably.
        We can model it to find the probability. Also notably,
        one index is inverted, which factors into the confidence
        especially for lower n.'''
        if n == 1:
            #one element is inverted, so whole list must be False
            return [False], 1
        if n == 2:
            #split half and half randomly; can't predict
            return [True] * n, 0
        #cumulative chance of mostly ones or mostly zeros
        truthy = 1
        for _ in range(n):
            #simulate repeated flipping
            truthy = truthy * 0.44 + (1-truthy) * 0.56
        falsey = 1 - truthy
        if falsey > truthy:
            return [False] * n, falsey - 1/n
        return [True] * n, truthy - 1/n
    def _con(self, n):
        '''Contrary is like Jade Emporer, but inverts itself
        so much that modelling the probability of inversion
        is not worth the effort.'''
        #there are some clever ways you could do statistics on this,
        #but I'm content to call it uniform for now
        return [False] * n, 0
    def _tit(self, n):
        '''TitForTat is most likely to give us False
        but the confidence drops as the chance of having
        met TitForTat increases.
        The square root of the probability we calculate for
        Alpha, Beta and Gamma, because those also care about what
        we answer, whereas TitForTat only cares about what we ask'''
        #probability that we've not given TitForTat an exam
        chance_friends = (1 - 1/self.bot_types) ** n
        return [False] * n, chance_friends
    def _equ(self, n):
        '''Equalizer always asks True'''
        #certain that Equalizer's exam is all True
        return [True] * n, 1
    def _mar(self, n):
        '''Marx returns mostly True, randomised based on our rank.
        We don't predict our rank.
        There's ~50% chance an answer is random'''
        #75% chance we guess right (= 50% + 50%*50%)
        return [True] * n, 0.75

Theoretisch eine großartige Idee, aber in seinem ersten Wettbewerb schnitt Count Oracular schlechter ab als YinYang, trotz seiner Bemühungen, YinYang zu simulieren.
Lila P

1
@ PurpleP Ja, es ist nicht sehr gut. Der Grund dafür ist, dass versucht wird, eine allgemein optimale Strategie zu wählen, indem alle spezifischen Strategien zusammengemittelt werden. Es wird beispielsweise keine Strategie angewendet, die darauf zugeschnitten ist, YinYang zu schlagen, wenn es auf YinYang trifft. Es wird nicht einmal eine bestimmte Strategie für Jade Emporer verwendet: Es wird lediglich die Jade Emporer-Strategie zum Durchschnitt hinzugefügt. Es wird besser als zufällig sein, aber nicht viel.
IFcoltransG

Marx wurde behoben. Sie sollten Count Oracular aktualisieren, um dies vorherzusagen.
Lila P

@ PurpleP Marx sollte jetzt unterstützt werden. Es ist wie es ist wieder 1917.
IFcoltransG

2

Yin-Yang

Antworten entweder alle Trueoder alle False, mit Ausnahme eines Indexes, der zufällig als das Gegenteil ausgewählt wurde. Fragt das Gegenteil von dem, was es antwortet. Swaps zufällig, um Gegner abzuwerfen.

import random

class YinYang:
    def __init__(self, ID, n):
        self.exam = True

    def update(self, rankList, ownExam, otherExams):
        if random.random() < 0.56:
            self.exam = not self.exam

    def answer(self, n, ID):
        a = [not self.exam] * n
        a[random.randint(0, n-1)] = self.exam
        return a

    def ask(self, n, ID):
        e = [self.exam] * n
        e[random.randint(0, n-1)] = not self.exam
        return e

Wi Qe Lu (Switcheroo)

Antwortet und fragt zufällig in der ersten Runde. Anschließend verwendet er die Antworten aus der vorherigen Prüfung und ändert eine Frage, wenn eine überdurchschnittliche Anzahl von Teilnehmern die richtigen Antworten gefunden hat.

class WiQeLu:
    def __init__(self, ID, n):
        self.rounds = 1
        self.firstexam = True
        self.firstanswer = True
        self.lastexaminer = -1
        self.exam = []
        self.pastanswers = {}

    def update(self, rankList, ownExam, otherExams):
        questions, lastanswers = ownExam
        self.pastanswers[self.lastexaminer] = questions

        if len(otherExams) == 0:
            return
        correctCounts = [0 for i in otherExams[0][0]]
        for ourExam, response in otherExams:
            for i in range(len(response)):
                if ourExam[i] == response[i]:
                    correctCounts[i] += 1

        newExam = otherExams[0][0]
        meanWhoAnsweredCorrectly = sum(correctCounts) / len(correctCounts)
        for i in range(len(correctCounts)):
            if correctCounts[i] > meanWhoAnsweredCorrectly:
                newExam[i] = not newExam[i]
        self.exam = newExam

    def answer(self, n, ID):
        self.lastexaminer = ID
        if ID not in self.pastanswers:
            randomanswer = [random.randint(0, 1) == 1] * n
            self.pastanswers[ID] = randomanswer
            return randomanswer
        return (self.pastanswers[ID] * n)[:n]

    def ask(self, n, ID):
        if self.firstexam:
            self.firstexam = False
            self.exam = [random.randint(0, 1) == 1] * n
        return (self.exam * n)[:n]

5
Laut Google Translate wird "wi qe lu" grob übersetzt als "Ich bin Pinguinstraße".
Lila P

2

Ein Bot von mir:

Thomas

Ein Reisender aus einem fernen Land hat einige gefährliche Vorstellungen über vergangene Ergebnisse, die auf die zukünftige Leistung hindeuten. Er nutzt diese, um andere Bots unter Kontrolle zu halten, es sei denn, dies behindert seinen eigenen Fortschritt.

class Thomas:
    def __init__(self,ID,n):
        N=10
        self.ID=ID
        self.myrank=n
        self.lowerank=0
        #The highest number of questions is equal to the number of participants, so we can do this:
        self.probs=[{i:1.0/N for i in np.linspace(0,1,num=N)} for i in np.arange(n)]
        self.output=[0.5]*n

    def ask(self,n,ID):
        if self.myrank==1 and self.lowerrank > 1: #I can't advance without promoting somebody first
            return [self.output[i]>np.random.rand() for i in np.arange(n)]
        #Otherwise, try to step on their fingers by going against the expected probability
        return [self.output[i]<np.random.rand() for i in np.arange(n)]


    def answer(self,n,ID):
        return [self.output[i]>np.random.rand() for i in np.arange(n)]

    def update(self,rankList,ownExam,otherExams):
        #Update our ranks
        self.myrank=len([i for i in rankList if i==rankList[self.ID]])
        self.lowerrank=len([i for i in rankList if i==rankList[self.ID]-1])
        #Update our expectations for each input we've been given
        self.bayesianupdate(ownExam[0])
        for ex in otherExams:
            self.bayesianupdate(ex[1])
        #Compress into output variable
        self.output=[np.sum([l[entry]*entry for entry in l]) for l in self.probs]

    def bayesianupdate(self,data):
        for i in np.arange(len(data)):
            if data[i]: #Got a True
                self.probs[i].update({entry:self.probs[i][entry]*entry for entry in self.probs[i]})
            else: #Got a False
                self.probs[i].update({entry:self.probs[i][entry]*(1-entry) for entry in self.probs[i]})
            s=np.sum([self.probs[i][entry] for entry in self.probs[i]]) #Renormalize
            self.probs[i].update({entry:self.probs[i][entry]/s for entry in self.probs[i]})
```

Haben Sie vergessen, Ihren Code nach der class-Anweisung einzurücken?
Paprika

Das ist nur die SE-Formatierung, die mich überrascht. Ich werde es zusammen mit dem
Problem

2

Alpha

Lesen Sie den Chat, bevor Sie abstimmen. Diese Bots verletzen keine Regeln. Das OP ermutigt sogar kooperierende Bots.

Alpha bildet zusammen mit Beta ein Team. Beide verwenden eine vordefinierte Reihe von Prüfungen, um sich gegenseitig beim Aufsteigen zu unterstützen. Beide nutzen auch die Vorteile von Bots, die immer wieder dieselben Prüfungen verwenden.

import numpy as np
import hashlib

class Alpha:
    def __init__(self, ID, n):
        self.alpha = hashlib.md5(b"Alpha")
        self.beta = hashlib.md5(b"Beta")
        self.asker = -1
        self.betas = set(range(n)).difference([ID])
        self.fixed = set(range(n)).difference([ID])
        self.fixedExams = [[]] * n

    def ask(self,n,ID):
        if ID in self.betas:
            return self.md5ToExam(self.alpha, n)
        else:
            return list(np.random.choice([True, False], n))

    def answer(self,n,ID):
        self.asker = ID
        if self.asker == -1:
            return [True] * n
        elif self.asker in self.fixed and len(self.fixedExams[self.asker]) > 0:
            return (self.fixedExams[self.asker] * n)[:n]
        elif self.asker in self.betas:
            return self.md5ToExam(self.beta, n)
        else:
            return list(np.random.choice([True, False], n))

    def update(self,rankList,ownExam,otherExams):
        if self.asker >= 0:
            if self.asker in self.betas and ownExam[0] != self.md5ToExam(self.beta, len(ownExam[0])):
                    self.betas.remove(self.asker)
            if self.asker in self.fixed:
                l = min(len(ownExam[0]), len(self.fixedExams[self.asker]))
                if ownExam[0][:l] != self.fixedExams[self.asker][:l]:
                    self.fixed.remove(self.asker)
                    self.fixedExams[self.asker] = []
                elif len(ownExam[0]) > len(self.fixedExams[self.asker]):
                    self.fixedExams[self.asker] = ownExam[0]
        self.alpha.update(b"Alpha")
        self.beta.update(b"Beta")

    def md5ToExam(self, md5, n):
        return [x == "0" for x in bin(int(md5.hexdigest(), 16))[2:].zfill(128)][:n]

Ich glaube, diese drei Bots verstoßen gegen die OP-Regeln, die sowohl in der Eingabeaufforderung als auch in den Kommentaren angegeben sind.
Don Thousand

@DonThousand Wenn Sie die Diskussion im Chat lesen, werden Sie feststellen, dass sie nicht gegen die Regeln verstößt. chat.stackexchange.com/rooms/98905/imperial-exams-office
Sleafar

Meinetwegen. Mein Fehler.
Don Thousand

@DonThousand Was bedeutete es also, sie alle abzustimmen?
Sleafar

Ich habe nur Alpha runtergestimmt. Ich kann die Abstimmung jedoch nicht rückgängig machen. Machen Sie eine überflüssige Bearbeitung und ich werde es beheben.
Don Thousand

1

Equalizer

Jeder sollte gleich sein (mit keinem dieser albernen Kaisersinn), also so viel soziale Mobilität wie möglich bieten. Machen Sie die Fragen wirklich einfach (die Antwort ist immer wahr), damit die Leute Erfolg haben können.

class Equalizer:
    def __init__(self, ID, n):
        self.previousAnswers = [[0, 0] for _ in range(n)]
        self.previousAsker = -1

    def ask(self, n, ID):
        return [True] * n

    def answer(self, n, ID):
        if ID == -1:
            return [True] * n

        # Assume that questions from the same bot will usually have the same answer.
        t, f = self.previousAnswers[ID]
        return [t >= f] * n

    def update(self, rankList, ownExam, otherExams):
        if self.previousAsker == -1:
            return

        # Keep track of what answer each bot prefers.
        counts = self.previousAnswers[self.previousAsker]
        counts[0] += ownExam[0].count(True)
        counts[1] += ownExam[0].count(False)

1

Beta

Lesen Sie den Chat, bevor Sie abstimmen. Diese Bots verletzen keine Regeln. Das OP ermutigt sogar kooperierende Bots.

Beta bildet zusammen mit Alpha ein Team. Beide verwenden eine vordefinierte Reihe von Prüfungen, um sich gegenseitig beim Aufsteigen zu unterstützen. Beide nutzen auch die Vorteile von Bots, die immer wieder dieselben Prüfungen verwenden.

import numpy as np
import hashlib

class Beta:
    def __init__(self,ID,n):
        self.alpha = hashlib.md5(b"Alpha")
        self.beta = hashlib.md5(b"Beta")
        self.asker = -1
        self.alphas = set(range(n)).difference([ID])
        self.fixed = set(range(n)).difference([ID])
        self.fixedExams = [[]] * n

    def ask(self,n,ID):
        if ID in self.alphas:
            return self.md5ToExam(self.beta, n)
        else:
            return list(np.random.choice([True, False], n))

    def answer(self,n,ID):
        self.asker = ID
        if self.asker == -1:
            return [True] * n
        elif self.asker in self.fixed and len(self.fixedExams[self.asker]) > 0:
            return (self.fixedExams[self.asker] * n)[:n]
        elif self.asker in self.alphas:
            return self.md5ToExam(self.alpha, n)
        else:
            return list(np.random.choice([True, False], n))

    def update(self,rankList,ownExam,otherExams):
        if self.asker >= 0:
            if self.asker in self.alphas and ownExam[0] != self.md5ToExam(self.alpha, len(ownExam[0])):
                    self.alphas.remove(self.asker)
            if self.asker in self.fixed:
                l = min(len(ownExam[0]), len(self.fixedExams[self.asker]))
                if ownExam[0][:l] != self.fixedExams[self.asker][:l]:
                    self.fixed.remove(self.asker)
                    self.fixedExams[self.asker] = []
                elif len(ownExam[0]) > len(self.fixedExams[self.asker]):
                    self.fixedExams[self.asker] = ownExam[0]
        self.alpha.update(b"Alpha")
        self.beta.update(b"Beta")

    def md5ToExam(self, md5, n):
        return [x == "0" for x in bin(int(md5.hexdigest(), 16))[2:].zfill(128)][:n]

1

Gamma

Lesen Sie den Chat, bevor Sie abstimmen. Diese Bots verletzen keine Regeln. Das OP ermutigt sogar kooperierende Bots.

Gamma hat die Pläne von Alpha und Beta entdeckt und versucht, beide auszunutzen, indem sie sich als einer von ihnen verkleidet.

import numpy as np
import hashlib

class Gamma:
    def __init__(self, ID, n):
        self.alpha = hashlib.md5(b"Alpha")
        self.beta = hashlib.md5(b"Beta")
        self.asker = -1
        self.alphas = set(range(n)).difference([ID])
        self.betas = set(range(n)).difference([ID])
        self.fixed = set(range(n)).difference([ID])
        self.fixedExams = [[]] * n

    def ask(self,n,ID):
        if ID in self.alphas:
            return self.md5ToExam(self.beta, n)
        elif ID in self.betas:
            return self.md5ToExam(self.alpha, n)
        else:
            return self.md5ToWrongExam(np.random.choice([self.alpha, self.beta], 1)[0], n)

    def answer(self,n,ID):
        self.asker = ID
        if self.asker == -1:
            return [True] * n
        elif self.asker in self.fixed and len(self.fixedExams[self.asker]) > 0:
            return (self.fixedExams[self.asker] * n)[:n]
        elif self.asker in self.alphas:
            return self.md5ToExam(self.alpha, n)
        elif self.asker in self.betas:
            return self.md5ToExam(self.beta, n)
        else:
            return list(np.random.choice([True, False], n))

    def update(self,rankList,ownExam,otherExams):
        if self.asker >= 0:
            if self.asker in self.alphas and ownExam[0] != self.md5ToExam(self.alpha, len(ownExam[0])):
                    self.alphas.remove(self.asker)
            if self.asker in self.betas and ownExam[0] != self.md5ToExam(self.beta, len(ownExam[0])):
                    self.betas.remove(self.asker)
            if self.asker in self.fixed:
                l = min(len(ownExam[0]), len(self.fixedExams[self.asker]))
                if ownExam[0][:l] != self.fixedExams[self.asker][:l]:
                    self.fixed.remove(self.asker)
                    self.fixedExams[self.asker] = []
                elif len(ownExam[0]) > len(self.fixedExams[self.asker]):
                    self.fixedExams[self.asker] = ownExam[0]
        self.alpha.update(b"Alpha")
        self.beta.update(b"Beta")

    def md5ToExam(self, md5, n):
        return [x == "0" for x in bin(int(md5.hexdigest(), 16))[2:].zfill(128)][:n]

    def md5ToWrongExam(self, md5, n):
        return [x == "1" for x in bin(int(md5.hexdigest(), 16))[2:].zfill(128)][:n]

1

Wie du mir so ich dir

Stellt Ihnen einfache Fragen, wenn Sie in der Vergangenheit einfache Fragen gestellt haben. Wenn Sie noch nie eine Prüfung abgelegt haben, werden standardmäßig einfache Fragen gestellt.

Darüber hinaus vertraut niemandem, der schwierige Fragen stellt, und gibt ihnen unvorhersehbare Antworten.

import numpy as np

class TitForTat:
    def __init__(self, ID, n):
        self.friendly = [True] * n
        self.asker = -1

    def make_answers(self, n, ID):
        if ID == -1 or self.friendly[ID]:
            return [False] * n
        else:
            return list(np.random.choice([True, False], n))

    def ask(self, n, ID):
        return self.make_answers(n, ID)

    def answer(self, n, ID):
        self.asker = ID
        return self.make_answers(n, ID)

    def update(self, rankList, ownExam, otherExams):
        if self.asker != -1:
            # You are friendly if and only if you gave me a simple exam
            self.friendly[self.asker] = all(ownExam[0])

Dieser Bot funktioniert gut, wenn andere Bots damit zusammenarbeiten. Derzeit kooperiert nur der Equalizer, dies sollte aber hoffentlich ausreichen.


Im Moment kann der Bot nicht mithalten, da er den Spezifikationen nicht entspricht. Stellen Sie sicher, dass listObjekte jederzeit zurückgegeben werden. Sowohl nach alten als auch nach aktualisierten Regeln sind perfekte Kopien eines Bots keine gültigen Einreichungen. Die zulässige Anzahl der ausgeführten Instanzen dieses Bots beträgt daher 1.
AlienAtSystem

Ich habe es bearbeitet, um Listen zurückzugeben. Was die perfekte Kopie angeht, so gibt es keinen aktuellen Bot, der ordnungsgemäß damit zusammenarbeitet. Die Anzahl der Carbon Copy Bots - das Minimum, das für eine erfolgreiche Umsetzung der Strategie erforderlich ist - beträgt mindestens 1 (dieser Bot und 1 Kopie davon werden benötigt) ).
Anonym

Sie argumentieren, dass Sie sich für eine Ausnahme nach Klausel 3 qualifizieren, während Sie versuchen, etwas einzureichen, das unter Klausel 1 fällt: Perfekte Kopien eines Bots sind niemals gültig, keine Ausnahmen. Und um sich für die Ausnahme von Klausel 3 zu qualifizieren, müssten Sie nachweisen, dass Ihre Strategie es unbedingt erfordert, dass alle diese Partner darauf reagieren, wie zum Beispiel ein Handshake-Signal, das in der Tat nutzlos ist, ohne dass jemand zuhört. Deiner nicht. Equalizer übergibt Ihnen Prüfungen, um die "freundliche" Klausel auszulösen, was widerlegt, dass eine Kopie Ihres Bots benötigt wird.
AlienAtSystem

Fein dann. Ich werde ein paar letzte Anpassungen vornehmen.
Anonym

0

Gegenteil

Der Jadekaiser hat immer Recht und implementiert die Fragefunktion des Jadekaisers als eigene Antwortfunktion, wenn er mehr als zwei Antworten benötigt. Für nur 1 Antwort wird geantwortet true(angemessene Wahrscheinlichkeit, korrekt zu sein) und für 2 wird geantwortettrue,false (diese Antwort besteht "mindestens die Hälfte" der Fragen, drei von vier möglichen Quizfragen, besser als zufällige Auswahl).

Verwendet eine ähnliche Logik in seinem Update hinsichtlich der Art und Weise, wie es sein Fragemuster ändert, aber seine Fragelogik ähnelt der des Jade-Kaisers, nur mit einem anderen Gewicht. Schwankt zwischen höheren Werten trueund höheren Werten, falsewenn zu viele Kandidaten hoch genug sind, um zu bestehen.

class Contrary:
    def __init__(self,ID,n):
        self.rank = 0
        self.ID = ID
        self.competitors = {}
        self.weight = -2
        pass

    def ask(self,n,ID):
        if self.weight > 0:
            num=min(np.random.exponential(scale=np.sqrt(np.power(self.weight,n))),np.power(2,n)-1)
            bi=list(np.binary_repr(int(num),width=n))
            return [x=='0' for x in bi]
        else:
            num=min(np.random.exponential(scale=np.sqrt(np.power(-self.weight,n))),np.power(2,n)-1)
            bi=list(np.binary_repr(int(num),width=n))
            return [x=='1' for x in bi]

    def answer(self,n,ID):
        if n == 1:
            return [True]
        if n == 2:
            return [True,False]
        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]

    def update(self,rankList,ownExam,otherExams):
        self.rank = rankList[self.ID];
        if len(otherExams) == 0:
            return
        correctCounts = [0 for i in otherExams[0][0]]
        for ourExam, response in otherExams:
            for i in range(len(response)):
                if ourExam[i] == response[i]:
                    correctCounts[i] += 1

        meanWhoAnsweredCorrectly = sum(correctCounts) / len(correctCounts)
        for i in range(len(correctCounts)):
            if correctCounts[i]+1 > meanWhoAnsweredCorrectly:
                self.weight = np.copysign(np.random.uniform(1,3),-self.weight)

1
Nicht true, falsescheitern, wenn die Prüfung ist false, true?
Paprika

Die ersten paar Zeilen in answerhaben Syntax- und Namensfehler - trueund falsesollten Trueund sein False, und die ifs fehlen :s am Ende
Sara J

Danke euch beiden; Ich habe Python nicht auf meinem Computer eingerichtet, da ich es nicht so oft verwende. Daher stelle ich die Syntax regelmäßig durcheinander.
Draco18s vertraut SE

newExam ist gesetzt aber nie eingelesen update. passist ein NOP-Befehl, den Sie löschen können. (Der Kommentar dahinter ist nur ein Wortspiel für den Drunkard, den Sie kopiert haben.) Außerdem verwenden Sie implizit die Module mathund random, haben aber nicht deklariert, dass Sie sie importiert haben. Ich habe es in meiner Wettbewerbsdatei mit umgeschrieben np.copysignund np.random.uniformdas sollte das gleiche tun.
AlienAtSystem

@AlienAtSystem Sollte jetzt behoben sein.
Draco18s vertraut SE

0

Marx

Dies ist der Marx-Bot. Er glaubt, dass wir anstelle einer Bürokratie ein kommunistisches System haben sollten. Um dieses Ziel zu erreichen, werden höherrangige Bots härter geprüft. Es gibt auch mehr zufällige Antworten auf Quizfragen von höheren Bots, weil sie wahrscheinlich schlauer sind, weil sie höher liegen.

import numpy as np

class Marx():
    def __init__(self, ID, n):
        self.ID = ID
        self.n = n
        self.ranks = [] # The bot rankings
        self.e = [] # Our quiz
        self.rank = 0 # Our rank
    def ask(self, n, ID):
        test = [True] * n
        # Get the rank of the bot being quizzed
        if self.ranks:
            rank = self.ranks[ID]
        else:
            rank = 0
        for i in range(len(test)):
            item = test[i]
            if np.random.uniform(0, rank / self.n) > 0.5:
                # If the bot is higher ranking, make the quiz harder
                item = np.random.choice([True, False], 1)[0]
            test[i] = item
        # IF the test is not long enough, add Falses to the end
        while len(test) < n - 1:
            test.append(False)
        return test
    def answer(self, n, ID):
        # Get the rank of the asking bot
        if self.ranks:
            rank = self.ranks[ID]
        else:
            rank = 0
        if self.e:
            # Pad our quiz with Falses so it will not throw IndexError
            while len(self.e) < n:
                self.e.append(False)
            for i in range(len(self.e)):
                item = self.e[i]
                if np.random.uniform(0, rank / self.n) > 0.5:
                    # Assume that higher ranking bots are cleverer, so add more random answers
                    item = np.random.choice([True, False], 1)[0]
                self.e[i] = item
            if len(self.e) > self.rank + 1:
                self.e = self.e[:self.rank + 1]
            return self.e
        else:
            # If it is the first round, return all Trues
            return [True] * n
    def update(self, rankList, ownExam, otherExams):
        # Update our list of ranks
        self.ranks = rankList
        # Store the quiz we were given, to give to the next bot
        self.e = ownExam[0]
        # Store our rank
        self.rank = rankList[self.ID]

Marx antwortet derzeit ein Byte zu viele, so dass er derzeit nicht antreten kann
AlienAtSystem

Was meinen Sie? Sind seine Prüfungen / Antworten zu lang?
Sugarfi

Seine Antwort ist ein Eintrag zu lang
AlienAtSystem

OK, das habe ich behoben. Es sollte jetzt gut sein.
Sugarfi

Sorry, ich habe dir falsches Feedback gegeben: Jetzt sind die Antworten ein Byte zu kurz. Das eigentliche Problem ist, dass Sie self.e verlängern, wenn es zu kurz ist (obwohl es im Moment nicht genug ist), aber es nicht kürzen, wenn Marx herabgestuft wird.
AlienAtSystem
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.