ระบบราชการสวรรค์


14

ในจักรวรรดิจีนการจัดอันดับในสังคมไม่ได้เกิดจากการตัดสินใจหรือความมั่งคั่ง แต่เกิดจากความสามารถของบุคคลในการสอบจักรวรรดิ จักรพรรดิหยกผู้ปกครองสวรรค์แห่งสวรรค์ได้เรียกร้องให้อาสาสมัครทุกคนของเขาได้รับการตรวจสอบเพื่อกำหนดมูลค่าของพวกเขา

กฎของระบบราชการ:

  • Divine Bureaucracy ประกอบด้วยตำแหน่งที่ไม่เป็นลบจำนวนเต็มเริ่มต้นด้วย 0 สมาชิกแต่ละคน (bot) ของระบบราชการอยู่ในอันดับหนึ่ง แต่ละอันดับสามารถมีสมาชิกได้ตามอำเภอใจ แต่ไม่สามารถเว้นว่างไว้ได้เว้นแต่ว่าอันดับทั้งหมดข้างต้นว่างเปล่า
  • ในช่วงเริ่มต้นของเกมสมาชิกทุกคนมีอันดับ 0
  • ทุกเทิร์นสมาชิกของระบบราชการแต่ละคนจะต้องตอบข้อสอบ การสอบประกอบด้วยการเดาค่าบูลีนของรายการอย่างถูกต้อง ความยาวของรายการคือจำนวนของอันดับเหนือสมาชิก
  • คำถามการสอบจัดทำขึ้นโดยสมาชิกสุ่มของอันดับด้านบน สมาชิกระดับสูงสุดจะได้รับคำถามโดยตรงจากJadeEmperor(ดูด้านล่าง)
  • สมาชิกที่ทำคะแนนอย่างน้อย 50% จากการสอบของพวกเขามีสิทธิ์ได้รับโปรโมชั่น สมาชิกที่ได้คะแนนน้อยกว่า 50% จากการสอบของพวกเขามีสิทธิ์ได้รับ Demotion
  • สมาชิกที่มีสิทธิ์ได้รับ Demotion จะมีอันดับของพวกเขาลดลงหนึ่งรายเท่านั้นหากมีสมาชิกที่มีสิทธิ์ได้รับโปรโมชันในอันดับด้านล่างเพื่อเข้าร่วม
  • สมาชิกทุกคนที่มีสิทธิ์ได้รับการเลื่อนอันดับจะเพิ่มขึ้นหนึ่งคนตราบใดที่ไม่มีการเลื่อนอันดับ
  • หากไม่ใช่สมาชิกที่มีสิทธิ์ทั้งหมดสามารถถูกลดระดับหรือเลื่อนระดับการตั้งค่าจะไปที่การตอบสนองต่ำสุด (สำหรับการลดระดับ) คะแนนสูงสุด (สำหรับการส่งเสริมการขาย) ความสัมพันธ์จะถูกทำลายแบบสุ่ม
  • อันดับของสมาชิกสามารถเปลี่ยนได้ไม่เกิน 1 รอบในแต่ละรอบ

กฎของเกม:

  • บอทแต่ละตัวจะถูกสุ่มเลือก ID ในตอนเริ่มเกมซึ่งจะไม่เปลี่ยนไปตามเส้นทางของมัน The JadeEmperorมี ID -1 ส่วนอื่น ๆ ทั้งหมดมี ID ที่ไม่ใช่ลบติดกันเริ่มต้นด้วย 0
  • บอตทั้งหมดแข่งขันในเวลาเดียวกัน
  • เกมนี้วิ่งมา 100 รอบคะแนนของบอทนั้นอยู่ในระดับนั้นโดยเฉลี่ยในขณะนั้น
  • คะแนนรวมได้มาจากการรัน 1,000 เกมและเฉลี่ยผลลัพธ์
  • แต่ละ Bot เป็นคลาสPython 3 ที่ใช้สี่ฟังก์ชั่นต่อไปนี้:
    • ask(self,n,ID)ซึ่งทำการสอบโดยคืนค่าlistบูลีนที่มีความยาว n ID คือ ID ของบอตที่ต้องเดารายการนั้น ask()สามารถเรียกได้หลายครั้งในระหว่างรอบเดียวสำหรับบอทใด ๆ แต่ก็ไม่ได้เลย
    • answer(self,n,ID)ซึ่งเป็นความพยายามในการตอบข้อสอบโดยส่งคืนlistBooleans ที่มีความยาว n ID คือ ID ของบอตที่ask()สร้างการทดสอบ answer()เรียกว่าหนึ่งครั้งต่อรอบสำหรับแต่ละบอท
    • update(self,rankList,ownExam,otherExams)ถูกเรียกเมื่อผู้ควบคุมได้ดำเนินการทั้งหมดและการสาธิต อาร์กิวเมนต์ของมันคือ: รายการเลขจำนวนเต็ม, แสดงลำดับทั้งหมดตาม ID ของบอตทั้งหมด; tuple ประกอบด้วยสองรายการก่อนคำถามสอบจากนั้นคำตอบบอทให้ (ในกรณีที่มันลืม); จากนั้นรายการของ tuples ประกอบไปด้วยคู่สอบ - คำตอบคราวนี้สำหรับการสอบทั้งหมดที่บอทยื่นออกมา
    • __init__(self, ID, n) ผ่านบอท ID ของตัวเองและจำนวนของบอทที่แข่งขัน
  • คลาสได้รับอนุญาตให้ใช้งานฟังก์ชั่นอื่น ๆ สำหรับการใช้งานส่วนตัว
  • การกำหนดตัวแปรเพิ่มเติมและใช้เพื่อจัดเก็บข้อมูลเกี่ยวกับการสอบที่ผ่านมาได้รับอนุญาตอย่างชัดเจน
  • ห้ามใช้เมตาเอฟเฟกต์การเขียนโปรแกรมหมายถึงความพยายามใด ๆ ในการเข้าถึงรหัสของบอทโดยตรงรหัสของคอนโทรลเลอร์ทำให้เกิดข้อยกเว้นหรือคล้ายกัน นี่คือการประกวดกลยุทธ์สำหรับการสอบไม่ใช่การแฮ็ครหัส
  • บอตที่พยายามช่วยเหลือซึ่งกันและกันได้รับอนุญาตอย่างชัดเจนตราบใดที่พวกเขาไม่ทำผ่านเมตาเอฟเฟ็กต์ แต่ข้อมูลล้วนผ่าน update()
  • อนุญาตให้ใช้ภาษาอื่นในกรณีที่สามารถแปลงเป็น Python 3 ได้อย่างง่ายดาย
  • numpy npห้องสมุดจะถูกนำเข้าเป็น เวอร์ชันคือ 1.6.5 หมายถึงใช้ไลบรารีแบบสุ่มเก่า หากคุณมี 1.7 numpy ฟังก์ชั่นเก่าที่มีอยู่ภายใต้numpy.random.mtrandการทดสอบได้ โปรดอย่าลืมลบ mtrand เพื่อส่ง
  • หากบอททำให้เกิดข้อยกเว้นระหว่างรันไทม์จะทำให้ไม่มีคุณสมบัติ บอทใด ๆ ที่มีรหัสงงงวยจนเป็นไปไม่ได้ที่จะบอกได้ว่ามันสร้างรายการความยาว n เมื่อask()หรือanswer()ถูกเรียกว่าจะถูกตัดสิทธิ์ด้วยการจองชิง บอทบังคับให้ฉันไปที่ผลลัพธ์การทำสำเนาแบบลึกจะได้รับ -1 จากคะแนน
  • ชื่อคลาสจะต้องไม่ซ้ำกัน
  • อนุญาตให้บอตหลายคนต่อคน แต่จะมีเฉพาะเวอร์ชันล่าสุดเท่านั้นที่จะได้รับการปรับปรุงซ้ำบอท
  • เนื่องจากดูเหมือนจะมีความสับสนเกี่ยวกับความคล้ายคลึงกันของบอท:
    • คุณไม่ได้รับอนุญาตให้โพสต์สำเนาของบอตอื่น นี่คือช่องโหว่มาตรฐานเท่านั้น ที่ใช้กับความท้าทายนี้
    • คุณได้รับอนุญาตให้มีรหัสที่ใช้ร่วมกันกับบอทอื่นรวมถึงบอทของคนอื่น
    • คุณไม่ได้รับอนุญาตให้ส่งบอทซึ่งแตกต่างจากการเปลี่ยนแปลงเล็กน้อยของกลยุทธ์ (เช่นการเปลี่ยนเมล็ดพันธุ์สำหรับการสร้างคำถาม) เว้นแต่คุณจะสามารถพิสูจน์ได้ว่าจำนวนบอตการคัดลอกคาร์บอนนั้นเป็นขั้นต่ำที่จำเป็นสำหรับการประสบความสำเร็จ ตรากฎหมายของพวกเขา (ซึ่งมักจะเป็นสองบอทสำหรับความร่วมมือ)

บอทตัวอย่าง:

เกมJadeEmperorนี้เป็นส่วนหนึ่งของเกมเสมอ แต่ไม่แข่งขัน เขาทำหน้าที่เป็นเครื่องกำเนิดไฟฟ้าสำหรับการสอบบอทระดับสูงสุด การสอบของเขาเป็นแบบสุ่ม แต่ไม่เหมือนกันเพื่อให้สมาร์ทบอทสามารถก้าวหน้าได้

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สร้างข้อสอบและคำตอบแบบสุ่มสมบูรณ์ เขาจะเป็นส่วนหนึ่งของเกม

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

นักลอกเลียนแบบคัดลอกการสอบก่อนหน้านี้ เขาจะเป็นส่วนหนึ่งของเกมด้วย

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]

มีรหัสคอนโทรลเลอร์ ที่นี่ สำหรับการทดสอบคุณสามารถใส่ชั้นเรียนของคุณเองลงในไฟล์ Contestants.py ในโฟลเดอร์เดียวกันและพวกเขาจะถูกนำเข้า

สามารถพบห้องสนทนาได้ ที่นี่

การสอบเริ่มต้นขึ้น!

คะแนนปัจจุบันด้วยความแม่นยำสูงกว่า (วิ่ง 10,000 ครั้ง) ในวันที่ 20 ตุลาคม:

สมาชิกใหม่ผู้เขียนคะแนนแอลฟาSleafar9.669691แกมมาSleafar9.301362เบต้าSleafar9.164597WiQeLuม่วง P7.870821StudiousBotDignissimus - สแปม7.538537แซนซาร่าเจ7.095528ผู้ขโมยความคิด6.522047CountOracularIFcoltransG5.881175โทมัสคนต่างด้าว @ ระบบ5.880041ตรงกันข้ามDraco18s5.529652มาร์กซ์sugarfi5.433808คนขี้เหล้า5.328178YinYangม่วง P5.102519ควอไลเซอร์ช่วยในการจำ4.820996TitForTatไม่ระบุชื่อ3.35801

การแข่งขันจะดำเนินการกับรายการใหม่แต่ละรายการในอนาคตอันใกล้


1
สำเนาของบอตคือช่องโหว่มาตรฐานดังนั้นไม่ หากคุณพยายามที่จะละเมิดกฎหลายบอทต่อผู้แต่งโดยการส่งสำเนาเกือบ - แต่ไม่ได้ค่อนข้างสวยฉันจะลบออก
AlienAtSystem

1
@AlienAtSystem ทำไมคุณถึงอนุญาตให้บอทช่วยเหลือซึ่งกันและกัน? ดูเหมือนว่าความสับสนและการสุ่มจับต้องมากขึ้น
Don Thousand

2
ทำไมจึงมีข้อโต้แย้งคอนสตรัคID, nแต่ข้อโต้แย้งวิธีการอื่นn, ID?
สีม่วง P

1
@ DonThousand เพราะฉันเชื่อว่าภายใต้ข้อ จำกัด ที่ได้รับมันเป็นความสำเร็จที่จะทำให้สองบอทที่ A) จับมือสำเร็จ (โปรดทราบว่า Plagiarizer อาจเล่นโดยบังเอิญคนที่อยู่ตรงกลาง) และ B) จากนั้นใช้กลยุทธ์ที่ช่วยบอทนั้น แต่ไม่มีอื่นใดที่จะเพิ่มขึ้น
AlienAtSystem

1
@someone อันดับขึ้นไป คุณเริ่มต้นที่ 0 และทำงานตามจำนวนที่สูงขึ้น
AlienAtSystem

คำตอบ:


4

แซน

คนที่จำอดีตไม่ได้ถูกประณามให้ทำซ้ำ ดังนั้นเราจึงตัดสินใจโดยใช้วิธีการที่คนอื่นทำในอดีตการตอบตามสิ่งที่ผู้ถามมักจะคาดหวังจากเราที่ดัชนีที่กำหนดและขอคำตอบที่พวกเขาให้เราอย่างน้อยบ่อยครั้งที่ดัชนี .

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

บอทขยัน

บอทนี้ทำการทดสอบ! มันพยายามที่จะหารูปแบบในการทดสอบที่ได้รับจากบอตต่างๆและทำหน้าที่สอดคล้องกัน

ในตอนท้ายของฉันจนถึงบอทนี้มีประสิทธิภาพที่ดีกว่าบอทอื่น ๆ ทั้งหมดที่ฉันสามารถทำงานบนคอมพิวเตอร์ของฉันยกเว้นจาก Alpha, Beta และ Gamma (ที่ได้รับการตั้งโปรแกรมให้ทำงานร่วมกัน) บอทไม่ได้ใช้ประโยชน์จากความจริงที่ว่าการทำงานเป็นทีมนั้นได้รับอนุญาตเพราะฉันรู้สึกว่ามันเหมือนโกงและสกปรกเล็กน้อย มองไปที่มันดูเหมือนว่าการร่วมทีมดูเหมือนจะค่อนข้างมีประสิทธิภาพ

ธ ปท. พยายามที่จะรับรู้เมื่อคำตอบของการทดสอบเป็นแบบสุ่มและตอบสนองการจับคู่ที่หวังว่าจะได้ค่าเฉลี่ย 50% ในการทดสอบ

ธ ปท. ยังพยายามที่จะรับรู้เมื่อบอทเพิ่งพลิกคำตอบเพื่อกำจัดบ็อตอื่น ๆ ที่คาดเดาพฤติกรรมของพวกเขา แต่ฉันยังไม่ได้ตั้งโปรแกรมให้ทำสิ่งนี้โดยเฉพาะ

ฉันได้ใส่คำอธิบายประกอบไว้ด้วยข้อคิดเห็นบางประการเพื่อให้อ่านง่ายขึ้น

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]

ตัดสินโดยประสิทธิภาพของเราคุณมีอัลกอริทึมที่ดีที่สุดสำหรับการตอบและ Wi Qe Lu มีอัลกอริทึมที่ดีที่สุดสำหรับการถาม ฉันเสนอให้เรารวมบอทของเราเป็นบอทเดียวที่เรียกว่าXuézhě (ภาษาจีนสำหรับ "นักวิชาการ") ซึ่งฟังดูเหมือน "switcher" โดยบังเอิญ
Purple P

ฉันแฮ็คมันและวิ่งการตรวจสอบในเครื่องของฉัน อยากรู้อยากเห็นมันยอดเยี่ยม Studious Bot แต่ไม่ใช่ Wi Qe Lu
Purple P

@PurpleP ฮ่าฮ่า! ฟังดูน่าสนใจมากฉันไม่คิดว่าจะมีเวลามากพอสำหรับฉันที่จะพัฒนาบอทของฉัน แต่คุณสามารถโพสต์ได้ที่นี่
Dignissimus - Spammy

3

นับจำนวนออโรราติก

บอทนี้ใช้อัลกอริธึมที่เฉลี่ยการสอบของบอททำงานอื่น ๆ ทั้งหมด (ตามจำนวนรอบและฮิวริสติกที่น่ากลัวบางอย่าง) สำหรับการตัดสินใจว่าบอทตัวอื่นจะตั้งค่าอย่างไรในการสอบ
The Count ขอให้การสอบใช้แฮช md5 ทั้งคำถามและคำตอบของมันจะถูกกำหนดไว้ มันไม่สนใจอินพุตส่วนใหญ่การถามและตอบลำดับที่เหมือนกันอย่างแน่นอนของบูลีนฝนหรือเงางามรวมถึง 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

เป็นแนวคิดที่ดีในทางทฤษฎี แต่ในการประกวดครั้งแรก Count Oracular ทำผลงานได้แย่กว่า YinYang แม้ว่าจะพยายามเลียนแบบ YinYang ก็ตาม
สีม่วง P

1
@ PurpleP ใช่มันไม่ดีมาก เหตุผลก็คือพยายามที่จะเลือกกลยุทธ์ที่ 'เหมาะสมที่สุด' โดยการหาค่าเฉลี่ยของกลยุทธ์เฉพาะทั้งหมดด้วยกัน ตัวอย่างเช่นไม่ใช้กลยุทธ์ที่ออกแบบมาเพื่อเอาชนะหยินหยางเมื่อเจอหยินหยาง มันไม่ได้ใช้กลยุทธ์เฉพาะกับ Jade Emporer: มันแค่เพิ่มกลยุทธ์ Jade Emporer เป็นค่าเฉลี่ย มันจะดีกว่าการสุ่ม แต่ไม่มากนัก
IFcoltransG

แก้ไข Marx แล้ว คุณควรอัปเดต Count Oracular เพื่อคาดการณ์
สีม่วง P

@PurpleP Marx ควรได้รับการสนับสนุนทันที มันเหมือนเป็นปี 1917 อีกครั้ง
IFcoltransG

2

YinYang

คำตอบทั้งหมดTrueหรือทั้งหมดFalseยกเว้นดัชนีหนึ่งเลือกสุ่มให้เป็นตรงกันข้าม ถามตรงข้ามกับคำตอบ สลับแบบสุ่มเพื่อสลัดคู่แข่ง

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)

คำตอบและถามแบบสุ่มในรอบแรก หลังจากนั้นเขาจะใช้คำตอบจากการสอบก่อนหน้านี้และเปลี่ยนคำถามหากคู่แข่งที่มีจำนวนสูงกว่าค่าเฉลี่ยถูกต้อง

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
อ้างอิงจาก Google Translate "wi qe lu" แปลว่า "I am penguin road"
สีม่วง P

2

บอทตัวหนึ่งของฉัน:

โทมัส

นักเดินทางจากดินแดนที่ห่างไกลมีความคิดที่เป็นอันตรายเกี่ยวกับผลลัพธ์ที่ผ่านมาซึ่งบ่งบอกถึงประสิทธิภาพในอนาคต เขาใช้สิ่งเหล่านี้เพื่อป้องกันบอทอื่น ๆ ยกเว้นว่าจะยับยั้งความก้าวหน้าของตัวเอง

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]})
```

คุณลืมที่จะเยื้องรหัสของคุณหลังจากคำสั่งชั้น?
pppery

นั่นเป็นเพียงการจัดรูปแบบ SE ที่ดึงดูดฉันโดยไม่รู้ตัว ฉันจะแก้ไขมันพร้อมกับสิ่งที่ทำให้เกิดข้อผิดพลาดในการทดสอบของใครบางคนเมื่อใช้บอตนี้
AlienAtSystem

2

แอลฟา

อ่านการแชทก่อนลงคะแนน บอทเหล่านี้ไม่ได้ละเมิดกฎใด ๆ OP ยังสนับสนุนให้บอทร่วมมือ

อัลฟ่ากำลังจัดตั้งทีมพร้อมกับเบต้า ทั้งคู่กำลังใช้ชุดการสอบที่กำหนดไว้ล่วงหน้าเพื่อช่วยให้อันดับของแต่ละคนดีขึ้น นอกจากนี้ทั้งคู่ยังใช้ประโยชน์จากบอตโดยใช้การสอบเดียวกันซ้ำไปซ้ำมา

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]

ฉันเชื่อว่าบอททั้งสามนี้ละเมิดกฎ OPs ตามที่ระบุในทั้งพรอมต์และความคิดเห็น
Don Thousand

@ DonThousand หากคุณอ่านการสนทนาในการแชทคุณจะเห็นว่าพวกเขาไม่ได้ละเมิดกฎ chat.stackexchange.com/rooms/98905/imperial-exams-office
Sleafar

ยุติธรรมพอสมควร ความผิดฉันเอง.
Don Thousand

@ DonThousand ดังนั้นอะไรคือจุดสำคัญในการลดระดับพวกเขาทั้งหมด?
Sleafar

ฉันลงคะแนนอัลฟ่าเท่านั้น แม้ว่าฉันจะไม่สามารถยกเลิกการลงคะแนนได้ ทำการแก้ไขฟุ่มเฟือยและฉันจะแก้ไข
Don Thousand

1

ควอไลเซอร์

ทุกคนควรมีความเท่าเทียมกัน (โดยไม่มีเรื่องไร้สาระของจักรพรรดิที่โง่เขลา) ดังนั้นจงเตรียมความพร้อมทางสังคมให้มากที่สุดเท่าที่จะทำได้ ทำให้คำถามง่ายมาก (คำตอบนั้นเสมอจริง) เพื่อให้ผู้คนสามารถประสบความสำเร็จได้

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

เบต้า

อ่านการแชทก่อนลงคะแนน บอทเหล่านี้ไม่ได้ละเมิดกฎใด ๆ OP ยังสนับสนุนให้บอทร่วมมือ

เบต้ากำลังรวมตัวกันเป็นทีมกับอัลฟ่า ทั้งคู่กำลังใช้ชุดการสอบที่กำหนดไว้ล่วงหน้าเพื่อช่วยให้อันดับของพวกเขาดีขึ้น นอกจากนี้ทั้งคู่ยังใช้ประโยชน์จากบอตโดยใช้การสอบเดียวกันซ้ำไปซ้ำมา

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

แกมมา

อ่านการแชทก่อนลงคะแนน บอทเหล่านี้ไม่ได้ละเมิดกฎใด ๆ OP ยังสนับสนุนให้บอทร่วมมือ

แกมม่าค้นพบแผนการของอัลฟ่าและเบต้าและพยายามใช้ประโยชน์จากทั้งคู่โดยการปลอมตัวเป็นหนึ่งในนั้น

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

TitForTat

ถามคำถามง่าย ๆ ถ้าคุณถามคำถามง่าย ๆ ในอดีต หากคุณไม่เคยได้รับการสอบก็เป็นคำถามเริ่มต้นที่ง่าย

นอกจากนี้ไม่เชื่อถือใครก็ตามที่ถามคำถามที่ยากและจะให้คำตอบที่ไม่สามารถคาดเดาได้

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])

บอทนี้ทำงานได้ดีถ้าบอตอื่นร่วมมือกับมัน ขณะนี้มีอีควอไลเซอร์เท่านั้นที่ให้ความร่วมมือ แต่หวังว่ามันน่าจะเพียงพอแล้ว


ในขณะนี้บ็อตไม่สามารถแข่งขันได้เนื่องจากไม่เป็นไปตามข้อกำหนด ตรวจสอบให้แน่ใจว่ามันส่งคืนlistวัตถุตลอดเวลา นอกจากนี้ภายใต้กฎทั้งเก่าและที่ได้รับการปรับปรุงสำเนาที่สมบูรณ์แบบของบ็อตไม่ใช่การส่งที่ถูกต้องดังนั้นจำนวนอินสแตนซ์ที่อนุญาตของบอทนี้ที่ทำงานคือ 1
AlienAtSystem

ฉันแก้ไขเพื่อส่งคืนรายการ สำหรับสิ่งที่สมบูรณ์แบบในการคัดลอกไม่มีบอทในปัจจุบันที่ให้ความร่วมมือกับมันอย่างเหมาะสมดังนั้นจำนวนบ็อตการคัดลอกคาร์บอน - ขั้นต่ำที่จำเป็นสำหรับการออกกฎหมายที่ประสบความสำเร็จ - อย่างน้อย 1 (บอทนี้และ 1 สำเนา )
ไม่เปิดเผยตัว

คุณกำลังโต้แย้งว่าคุณมีสิทธิ์ได้รับการยกเว้นภายใต้ข้อ 3 ในขณะที่พยายามส่งสิ่งที่อยู่ภายใต้ข้อ 1: สำเนาบอทที่สมบูรณ์แบบนั้นจะไม่ถูกต้องไม่มีข้อยกเว้น และเพื่อให้มีคุณสมบัติยกเว้นข้อ 3 คุณจะต้องพิสูจน์ว่ากลยุทธ์ของคุณต้องการพันธมิตรทั้งหมดที่ตอบโต้อย่างเข้มงวดตัวอย่างเช่นสัญญาณจับมือซึ่งไม่มีประโยชน์จริง ๆ โดยไม่มีใครฟัง ของคุณไม่ได้ อีควอไลเซอร์จะมอบการสอบให้คุณเพื่อเรียกประโยค "เป็นมิตร" ดังนั้นจึงพิสูจน์ได้ว่าจำเป็นต้องมีสำเนาบอทของคุณ
AlienAtSystem

สบายดีแล้ว ฉันจะทำการปรับเปลี่ยนครั้งสุดท้าย
ไม่เปิดเผยตัว

0

ตรงกันข้าม

จักรพรรดิหยกถูกต้องเสมอดังนั้นจึงใช้ฟังก์ชั่นการถามของจักรพรรดิหยกเป็นฟังก์ชั่นตอบของมันเองเมื่อต้องการมากกว่า 2 คำตอบ สำหรับ 1 คำตอบเท่านั้นคำตอบtrue(อัตราต่อรองที่ถูกต้องของการถูกต้อง) และสำหรับ 2 คำตอบtrue,false (นี้ผ่าน "อย่างน้อยครึ่งหนึ่ง" ของคำถามสามในสี่ข้อสอบที่เป็นไปได้ดีกว่าการสุ่มเลือก)

ใช้ตรรกะที่คล้ายกันในการอัปเดตโดยคำนึงถึงวิธีการเปลี่ยนแปลงรูปแบบการถาม แต่ตรรกะการถามนั้นคล้ายกับจักรพรรดิหยกเพียงน้ำหนักที่แตกต่างกัน ผันผวนระหว่างค่าที่สูงขึ้นของtrueกับค่าที่สูงขึ้นของfalseเมื่อผู้สมัครจำนวนมากเกินไปให้คะแนนสูงพอที่จะผ่าน

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
ไม่true, falseสอบล้มเหลวถ้าการสอบเป็นfalse, true?
pppery

สองสามบรรทัดแรกanswerมีข้อผิดพลาดทางไวยากรณ์และชื่อ - trueและfalseควรเป็นTrueและFalseและifs หายไป:ในตอนท้าย
Sara J

ขอบคุณสอง ฉันไม่ได้ติดตั้ง Python บนเครื่องของฉันเพราะฉันไม่ได้ใช้งานบ่อยดังนั้นฉันจึงทำให้ไวยากรณ์สับสน
Draco18 ไม่ไว้วางใจ SE

newExam มีการตั้งค่า updateแต่ไม่เคยอ่านใน passเป็นคำสั่ง NOP คุณสามารถลบได้ (ความคิดเห็นที่อยู่เบื้องหลังมันเป็นเพียงแค่คำสั่งสำหรับ Drunkard ที่คุณคัดลอกมา) นอกจากนี้คุณกำลังใช้mathและrandomโมดูลโดยปริยายแต่ไม่ได้ประกาศว่าคุณนำเข้ามัน ฉันได้เขียนมันใหม่ในไฟล์ประกวดด้วยnp.copysignและnp.random.uniformควรทำสิ่งเดียวกัน
AlienAtSystem

@AlienAtSystem ควรได้รับการแก้ไขแล้ว
Draco18 ไม่ไว้วางใจ SE

0

มาร์กซ์

นี่คือบ็อตมาร์กซ์ เขาเชื่อว่าแทนที่จะเป็นระบบราชการเราควรมีระบบคอมมิวนิสต์ เพื่อช่วยให้บรรลุเป้าหมายนี้จะให้แบบทดสอบที่ยากขึ้นไปถึงบอทระดับสูง นอกจากนี้ยังให้คำตอบแบบสุ่มมากขึ้นสำหรับการทดสอบจากบอตที่สูงขึ้นเพราะพวกเขาอาจฉลาดกว่าเพราะสูงกว่า

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]

ปัจจุบันมาร์กซ์ตอบไบต์จำนวนมากเกินไปดังนั้นเขาจึงไม่สามารถแข่งขันได้
AlienAtSystem

คุณหมายถึงอะไร การสอบ / คำตอบของเขานานเกินไปไหม
sugarfi

คำตอบของเขาคือหนึ่งรายการยาวเกินไป
AlienAtSystem

ตกลงฉันคงที่ มันควรจะดีตอนนี้
sugarfi

ขออภัยฉันให้ข้อเสนอแนะกับคุณผิด: ตอนนี้คำตอบนั้นสั้นเกินไป ปัญหาที่แท้จริงคือคุณขยายตัวเองเมื่อมันสั้นเกินไป (แม้ว่าจะไม่เพียงพอในตอนนี้) แต่อย่าตัดมันเมื่อ Marx ลดระดับลง
AlienAtSystem
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.