गुड वर्सस इविल


112

परिणाम - 19 जुलाई 2014

उपयोगकर्ता फैब्लर द्वारा हिल के वर्तमान राजा भाड़े के हैं ! प्रविष्टियां जमा करते रहें और उसे अपने सिंहासन से हटा दें!

स्कोरबोर्ड देखने के लिए यहां क्लिक करें।

19 जुलाई 2014 को या उससे पहले प्रस्तुत कार्यक्रम शामिल किए गए थे। अन्य सभी प्रस्तुतियाँ भविष्य के परीक्षणों में शामिल की जाएंगी। नए परिणाम 9 अगस्त के आसपास पोस्ट किए जाने चाहिए, जिससे आपको काफी समय मिल सके।


भाई द्वारा चित्रित चित्रण क्रिस रेनबोल्ट, मेरे भाई और सवाना कॉलेज ऑफ आर्ट एंड डिज़ाइन से एक ताजा स्नातक द्वारा प्रकाशित

परिचय

स्वर्गदूतों और दानवों ने हमेशा की तरह धरती को अपने युद्धभूमि के रूप में इस्तेमाल करते हुए लड़ रहे हैं। मनुष्य बीच में फंस गए हैं और पक्ष लेने के लिए मजबूर हो रहे हैं। एक अज्ञात तटस्थ बल उन लोगों को पुरस्कृत करता है जो लगातार हारने वाले पक्ष के लिए लड़ते हैं।

खेल

प्रत्येक परीक्षण, आपको छद्म रूप से जोड़ा जाएगा और फिर 20 और 30 अन्य सबमिशन के बीच फेरबदल किया जाएगा। प्रत्येक ट्रायल में 1000 राउंड शामिल होंगे। प्रत्येक दौर में, आपको एक इनपुट दिया जाएगा और आउटपुट के उत्पादन की उम्मीद की जाएगी। आपका आउटपुट रिकॉर्ड किया जाएगा और स्कोर किया जाएगा। इस प्रक्रिया को 1000 बार दोहराया जाएगा।

इनपुट

आपको एक तर्क मिलेगा जो प्रत्येक खिलाड़ी के पिछले वोटों का प्रतिनिधित्व करता है। अल्पविराम द्वारा सीमा को सीमांकित किया जाता है। एक 0खिलाड़ी एक खिलाड़ी का प्रतिनिधित्व करता है जो उस दौर में ईविल के साथ पक्षधर था। एक 1खिलाड़ी एक खिलाड़ी का प्रतिनिधित्व करता है जो गुड के साथ पक्ष रखता है। एक परीक्षण के भीतर, खिलाड़ी हमेशा उसी क्रम में रहेंगे। आपका अपना वोट शामिल होगा, लेकिन स्पष्ट रूप से पहचाना नहीं गया। उदाहरण के लिए:

101,100,100

इस उदाहरण में, तीन राउंड पूरे हो चुके हैं और तीन खिलाड़ी प्रतिस्पर्धा कर रहे हैं। खिलाड़ी एक हमेशा अच्छा के साथ पक्षीय। खिलाड़ी दो हमेशा ईविल के साथ पक्षीय। राउंड 1 में गुड से राउंड 1 में खिलाड़ी तीन स्वैप किए गए और राउंड 2 में 3. उन खिलाड़ियों में से एक आप थे।

उत्पादन

जावा सबमिशन

  • goodयदि आप गुड के साथ पक्ष रखना चाहते हैं, तो स्ट्रिंग वापस करें ।
  • evilयदि आप बुराई के साथ पक्ष करना चाहते हैं तो स्ट्रिंग वापस करें ।

गैर-जावा सबमिशन

  • goodयदि आप गुड के साथ साइड करना चाहते हैं तो स्ट्रिंग को स्टडआउट में आउटपुट करें ।
  • evilयदि आप ईविल के साथ साइड करना चाहते हैं तो स्ट्रिंग को स्टडआउट में आउटपुट करें ।

यदि आपका प्रोग्राम आउटपुट करता है या कुछ और रिटर्न करता है, तो एक अपवाद फेंकता है, संकलन नहीं करता है, या इस सटीक मशीन पर कुछ भी आउटपुट करने में एक सेकंड से अधिक समय लगता है , तो यह अयोग्य हो जाएगा।

स्कोरिंग

जैसे ही मैं सभी वर्तमान प्रविष्टियों को संकलित कर सकता हूं, स्कोर को आसानी से देखने के लिए Google डॉक्स स्प्रेडशीट में पोस्ट किया जाएगा। चिंता न करें - जब तक आप लोग कार्यक्रम प्रस्तुत करते रहेंगे, तब तक मैं परीक्षण करता रहूँगा!

  • आप एक दौर के दौरान बहुमत के साथ साइडिंग के लिए 3 अंक प्राप्त करते हैं।
  • आपको एक राउंड के दौरान अल्पसंख्यक के साथ साइडिंग के लिए n - 1 अंक प्राप्त होता है, जहाँ n आप अल्पसंख्यक के साथ पक्षपात करने वाले लगातार समय की संख्या है।

आपका स्कोर 5 परीक्षणों का मध्यक्रम होगा। प्रत्येक परीक्षण में 1000 राउंड होते हैं।

वितरणयोग्य

गैर-जावा सबमिशन

आपको एक अद्वितीय शीर्षक, एक कार्यक्रम और एक विंडोज कमांड लाइन स्ट्रिंग जमा करना होगा जो आपके कार्यक्रम को चलाएगा। याद रखें कि उस स्ट्रिंग में एक तर्क जोड़ा जा सकता है। उदाहरण के लिए:

  • python Angel.py
    • ध्यान दें कि यह कोई भी नहीं है। यह एक दौर है! इसके लिए तैयार रहें।
  • python Angel.py 11011,00101,11101,11111,00001,11001,11001

जावा सबमिशन

आपको एक विशिष्ट शीर्षक और एक जावा वर्ग प्रस्तुत करना होगा जो नीचे लिखे गए सार मानव वर्ग का विस्तार करता है।

public abstract class Human {
    public abstract String takeSides(String history) throws Exception;
}

परिक्षण

यदि आप अपने स्वयं के सबमिशन का परीक्षण करना चाहते हैं, तो यहां दिए गए निर्देशों का पालन करें

अतिरिक्त नोट्स

आप जितने चाहें उतने अलग प्रस्तुतियाँ प्रस्तुत कर सकते हैं। टकराहट दिखाई देने वाले सबमिशन को अयोग्य घोषित किया जाएगा। इस चुनौती के लेखक उस मामले पर एकमात्र न्यायाधीश होंगे।

आपके प्रोग्राम या जावा क्लास का एक नया उदाहरण हर बार जब इसे बनाया जाता है, बनाया जाएगा। आप किसी फ़ाइल पर लिखकर जानकारी को बनाए रख सकते हैं। आप अपनी कक्षा को छोड़कर किसी भी संरचना या व्यवहार को संशोधित नहीं कर सकते।

ट्रायल शुरू होने से पहले खिलाड़ियों से किनारा कर लिया जाएगा। दानव और एन्जिल हर परीक्षण में भाग लेंगे। अगर खिलाड़ियों की संख्या समान है, तो पीटर बेलीश भी शामिल होंगे। दानव बुराई के लिए लड़ता है, एंजेल फॉर गुड, और पेटियर बेलिश एक छद्म आयामी पक्ष चुनता है।


2
टिप्पणियाँ अप्रचलित हैं, क्योंकि वे अप्रचलित थे और ओपी के अनुरोध पर। कृपया मुझे ऐसी किसी भी टिप्पणी के बारे में सूचित करें, जिसकी आवश्यकता नहीं है।
दरवाज़े

7
वाह, ओपी अपना उपयोगकर्ता नाम बदलता है। ठीक है, तो परिणाम कब प्रदर्शित किया जाएगा?
जस्टफुल

6
@Rainbolt इस काम का एक सनकी नरक होना चाहिए, इस चुनौती को चलाने वाला! ध्यान की इस राशि का कारण प्रोटोकॉल और नियमों की सादगी है, यह सरल, काम कर रहे प्रविष्टियों की अनुमति देते हुए इसे सुलभ बनाता है । TL; DR: आपकी चुनौती बहुत अच्छी है! : D
tomsmeding'

3
@ डीजीएल मैं कच्चे डेटा को ऊपरी, निचले, औसत और शायद एक लाइन चार्ट पर पोस्ट करूँगा ताकि हम देख सकें कि प्रतियोगिता को खींचने के दौरान किसने बेहतर किया।
रेनबोल्ट

6
पॉड्स में से एक 10 प्रविष्टियों के साथ समाप्त हुआ, जिसने हर बार उसी तरह से मतदान किया। नतीजतन, दो उपयोगकर्ता लगभग 450,000 के स्कोर के साथ पूर्ण या "एक राउंड शॉर्ट ऑफ परफेक्ट" समाप्त हो गए। अन्य प्रविष्टियों में समान प्रविष्टियों ने लगभग 1900 स्कोर किया। औसत स्कोर 2000 के करीब है। परिणामों में अत्यधिक असंतुलन के कारण, मैंने फैसला किया कि एक अधिक सार्थक संख्या एक औसत होगी। मैंने चुनौती को संपादित किया, ताकि 5 परीक्षणों के बाद, विजेता सर्वोच्च पदक के साथ प्रस्तुत होगा। अगर किसी को लगता है कि माध्य से मध्य तक चलना अनुचित है या अन्यथा खराब विकल्प है, तो कृपया टिप्पणी करें।
रेनबोल्ट

जवाबों:


11

दी मर्सिनरी

हमेशा उन लोगों के साथ, जिन्होंने पिछले दौर में सबसे अधिक पैसा दिया था।

इस बात को ध्यान में रखते हुए कि अच्छे लोग सांख्यिकीय रूप से अधिक कमाते हैं।

package Humans;
public class Mercenary extends Human {
    public String takeSides(String history) {
        // first round random!
        if (history.length() == 0) {
            return Math.random() >= 0.5 ? "good" : "evil";
        }

        String[] rounds = history.split(",");
        String lastRound = rounds[rounds.length - 1];

        double goodMoneyPaid = 0;
        double evilMoneyPaid = 0;
        for (char c : lastRound.toCharArray()) {
                switch (c) {
                case '0':
                    goodMoneyPaid = goodMoneyPaid + 0.2; //statistically proven: good people have more reliable incomes
                    break;
                case '1':
                    evilMoneyPaid++; 
                    break;
                default:
                    break;
                }
        }

        if (goodMoneyPaid > evilMoneyPaid)
        {
            return "good";
        } else {
            return "evil";
        }
    }
}

2
पैसे के बारे में कुछ कहने के लिए यह दूसरी पोस्ट है। क्या मुझे एक संदर्भ या कुछ याद आ रहा है?
रेनबोल्ट

सच है, लेकिन यह आदमी और भी बुरा कमीने है। केवल पैसे की खातिर, हर मोड़ पर अपनी इच्छा का वर्णन करता है।
फैब्लर

आपका स्विच स्टेटमेंट डिफॉल्ट केस के लिए एक रिटर्न स्टेटमेंट याद कर रहा है, जिससे यह कंपाइल नहीं होता। मैंने एक यादृच्छिक जोड़ा।
रेनबोल्ट

4
बधाई हो, हिल के राजा! मुझे समझ नहीं आता कि यह प्रविष्टि कैसे जीतती है। एक विवरण जोड़ने के लिए ध्यान दें, अब जब इसमें 300 प्रतिष्ठा जुड़ी हुई है?
रेनबोल्ट

4
संभवतः एक बग, या मैंने टिप्पणियों और विवरण को गलत समझा, लेकिन भाड़े वास्तव में वह नहीं करते हैं जो यह करना था। पहले यादृच्छिक दौर को छोड़कर, वह हमेशा बुराई का साथ देगा जब तक कि पिछले दौर में 1/6 से कम लोगों ने बुराई के लिए मतदान नहीं किया।
जाबेज

39

हिप्स्टर, रूबी

if ARGV.length == 0
    puts ["good", "evil"].sample
else
    last_round = ARGV[0].split(',').last
    n_players = last_round.length
    puts last_round.count('1') > n_players/2 ? "evil" : "good"
end

बस अंतिम दौर के अल्पसंख्यक के साथ चला जाता है, सिर्फ इसलिए कि बाकी सब मुख्यधारा है।

जैसे दौड़ो

ruby hipster.rb

30

पीटर बेलीश

आपको कभी नहीं पता होगा कि पेटिर बेलिश किसका पक्ष है।

package Humans;

/**
 * Always keep your foes confused. If they are never certain who you are or 
 * what you want, they cannot know what you are likely to do next.
 * @author Rusher
 */
public class PetyrBaelish extends Human {

    /**
     * Randomly take the side of good or evil.
     * @param history The past votes of every player
     * @return A String "good" or "evil
     */
    public String takeSides(String history) {
        return Math.random() < 0.5 ? "good" : "evil";
    }
}

यह प्रविष्टि केवल तभी शामिल की जाएगी जब खिलाड़ियों की संख्या सम हो। यह सुनिश्चित करता है कि हमेशा बहुमत रहेगा।


28
जाहिर तौर पर पीटर बेलीश की तरफ।
Cthulhu

2
@ केविन यह लगातार अधिकांश बॉट्स को पीटता है। यह आमतौर पर 27ish स्कोर करता है।
cjfaure

3
@ केविन इस प्रविष्टि को चुनौती के लेखक द्वारा प्रस्तुत किया गया था। यह अच्छी तरह से करने के लिए नहीं था। यह सुनिश्चित करने के लिए मौजूद है कि हमेशा एक बहुमत होगा, क्योंकि खिलाड़ियों की संख्या के साथ भी एक टाई हो सकती है।
रेनबोल्ट

4
हे भगवान क्यों इस एक को सबसे ज्यादा वोट मिले हैं? यह उचित नहीं है
टॉमस

3
@tomsmeding नहीं। यह गेम ऑफ थ्रोन्स लोल का एक उद्धरण है।
रेनबोल्ट

29

सी ++, द मेटा साइंटिस्ट

यह अनिवार्य रूप से द साइंटिस्ट के रूप में एक ही करता है, लेकिन एक पूरे के रूप में नहीं बल्कि व्यक्तिगत खिलाड़ियों पर काम करता है। यह प्रत्येक खिलाड़ी को अलग से एक लहर (या एक स्थिर फ़ंक्शन) मैप करने की कोशिश करता है और अगले दौर में उनकी चाल की भविष्यवाणी करता है। परिणामी दौर की भविष्यवाणी से, मेटा साइंटिस्ट चुनता है कि कोई भी पक्ष बहुमत की तरह दिखता है।

#include <iostream>
#include <utility>
#include <cstdlib>
#include <cstring>
#if 0
#define DBG(st) {st}
#else
#define DBG(st)
#endif

#define WINDOW (200)

using namespace std;

int main(int argc,char **argv){
    if(argc==1){
        cout<<(rand()%2?"good":"evil")<<endl;
        return 0;
    }
    DBG(cerr<<"WINDOW="<<WINDOW<<endl;)
    int nump,numr;
    nump=strchr(argv[1],',')-argv[1];
    numr=(strlen(argv[1])+1)/(nump+1);
    int period,r,p;
    int score,*scores=new int[WINDOW];
    int max; //some score will always get above 0, because if some score<0, the inverted wave will be >0.
    int phase,phasemax;
    int predicted=0; //The predicted number of goods for the next round
    int fromround=numr-WINDOW;
    if(fromround<0)fromround=0;
    pair<int,int> maxat; //period, phase
    DBG(cerr<<"Players:"<<endl;)
    for(p=0;p<nump;p++){
        DBG(cerr<<" p"<<p<<": ";)
        for(r=fromround;r<numr;r++)if(argv[1][r*(nump+1)+p]!=argv[1][p])break;
        if(r==numr){
            DBG(cerr<<"All equal! prediction="<<argv[1][p]<<endl;)
            predicted+=argv[1][(numr-1)*(nump+1)+p]-'0';
            continue;
        }
        max=0;
        maxat={-1,-1};
        for(period=1;period<=WINDOW;period++){
            scores[period-1]=0;
            phasemax=-1;
            for(phase=0;phase<2*period;phase++){
                score=0;
                for(r=fromround;r<numr;r++){
                    if(argv[1][r*(nump+1)+p]-'0'==1-(r+phase)%(2*period)/period)score++;
                    else score--;
                }
                if(score>scores[period-1]){
                    scores[period-1]=score;
                    phasemax=phase;
                }
            }
            if(scores[period-1]>max){
                max=scores[period-1];
                maxat.first=period;
                maxat.second=phasemax;
            }
            DBG(cerr<<scores[period-1]<<" ";)
        }
        DBG(cerr<<"(max="<<max<<" at {"<<maxat.first<<","<<maxat.second<<"})"<<endl;)
        DBG(cerr<<"     prediction: 1-("<<numr<<"+"<<maxat.second<<")%(2*"<<maxat.first<<")/"<<maxat.first<<"="<<(1-(numr+maxat.second)%(2*maxat.first)/maxat.first)<<endl;)
        predicted+=(1-(numr+maxat.second)%(2*maxat.first)/maxat.first);
    }
    DBG(cerr<<"Predicted outcome: "<<predicted<<" good + "<<(nump-predicted)<<" evil"<<endl;)
    if(predicted>nump/2)cout<<"evil"<<endl; //pick minority
    else cout<<"good"<<endl;
    delete[] scores;
    return 0;
}

यदि आप डिबग स्टेटमेंट चालू करना चाहते हैं, तो पढ़ने के #if 0लिए लाइन बदलें #if 1

के साथ संकलित करें g++ -O3 -std=c++0x -o MetaScientist MetaScientist.cpp(आपको चेतावनियों की आवश्यकता नहीं है, इसलिए नहीं -Wall) और साथ चलें MetaScientist.exe(संभवतः पाठ्यक्रम के तर्क सहित)। यदि आप वास्तव में अच्छी तरह से पूछते हैं तो मैं आपको एक विंडोज निष्पादन योग्य प्रदान कर सकता हूं।

संपादित करें: जाहिरा तौर पर, पिछला संस्करण खेल में लगभग 600 राउंड के समय से बाहर चला गया था। ऐसा नहीं करना चाहिए। इसके समय की खपत #define WINDOW (...)लाइन द्वारा नियंत्रित होती है , अधिक धीमी होती है लेकिन आगे पीछे दिखती है।


2
मैं विनम्रतापूर्वक सुझाव देता हूं कि आप हारने वाले पक्ष को चुनने का प्रयास करें। यदि आप लगातार सही अनुमान लगा सकते हैं, तो आपको प्रति राउंड 3 से अधिक अंक मिलेंगे।
केविन

1
@ केविन यह सच है, लेकिन मुझे लगा कि यह गलत पक्ष का बहुत जल्दी अनुमान लगा सकता है, और आपको बहुमत को हमेशा सही पाने के लिए सुधार करने के लिए लगातार सात बार से अधिक बार खोने वाले पक्ष का सही अनुमान लगाने की आवश्यकता है। मैं इसे बदल सकता हूं।
टॉमस

1
@ केविन इसके अलावा, मैं सबसे पहले यह देखना चाहता हूं कि ये कैसे (साइंटिस्ट और मेटा साइंटिस्ट) करते हैं जब रशर हमें इस सप्ताह के अंत में स्कोरबोर्ड मिलता है, जैसा कि उन्होंने ओपी को टिप्पणियों में संकेत दिया था। जल्दी करो, माफ करना, लेकिन मैं खुद सारा सामान
समेटने के

3
कोई चिंता नहीं! यह शायद वैसे भी चलाने के लिए सुरक्षित नहीं है। बस मुझे इंटरनेट पर 50 अजनबियों द्वारा लिखे गए कोड के साथ अपनी मशीन को खराब करने दें।
रेनबोल्ट

1
@ केविन लेकिन ऐसा बहुत है ! मैं कर सकता हूँ, वास्तव में, लेकिन मुझे यह पसंद नहीं है। मैं देखूंगा कि ये किराया कैसा है।
२०:४३ में

26

देवदूत

सब से शुद्ध खिलाड़ी।

कार्यक्रम

print "good"

आदेश

python Angel.py

22
अजगर एक अच्छी भाषा है। यह केवल प्राकृतिक लगता है कि एंजेल को इसका उपयोग करना चाहिए।
jpmc26

23
मई मैं लोगों को याद दिलाता हूं कि एक अजगर सांप है। एक सर्प।
श्री लिस्टर

3
@ मिस्टर लिस्टर मैं आपको याद दिलाऊं कि भगवान के स्वर्ग से बाहर निकालने से पहले लूसिफ़ेर एक महान दूत था।
ज़िब्बोज़

1
@Zibbobz हाँ ... वास्तव में शर्म की बात है, कि वे बाहर गिर गए। वे एक साथ इतना कुछ हासिल कर सकते थे।
मिस्टर लिस्टर

24

आर्टेमिस फोवेल

package Humans;

public class ArtemisFowl extends Human {
    public final String takeSides(String history) {
        int good = 0, evil = 0;
        for(int i = 0; i < history.length(); i++)   {
            switch(history.charAt(i))   {
                case '0': evil++; break;
                case '1': good++; break;
            }
        }
        if(good % 5 == 0){
           return "good";
        } else if (evil % 5 == 0){
           return "evil";
        } else {
           if(good > evil){
              return "good";
           } else if(evil > good){
              return "evil";
           } else {
              return Math.random() >= 0.5 ? "good" : "evil";
           }
        }
    }
}

बुक 7 में, द अटलांटिस कॉम्प्लेक्स , आर्टेमिस फॉवेल ने एक मनोवैज्ञानिक बीमारी (अटलांटिस कॉम्प्लेक्स कहा जाता है) को अनुबंधित किया, जिसने उन्हें 5 के गुणकों में सब कुछ करने के लिए मजबूर किया (बोलना, क्रियाएं, आदि)। जब वह 5 में से कई में ऐसा नहीं कर सका, तो वह घबरा गया। मैं मूल रूप से ऐसा करता हूं: यह देखें कि क्या अच्छा या बुरा (जानबूझकर पूर्वाग्रह) 5 से विभाज्य है, यदि न तो है, तो मैं घबराता हूं और देखता हूं कि जो अधिक था और उस के साथ भाग गया या आतंक और आगे और यादृच्छिक रूप से चुनें।


4
जब मैंने Artemis Fowl को जूनियर हाई में पढ़ा, तो केवल दो किताबें मौजूद थीं। यह देखकर अच्छा लगा कि अब सात हैं, और यह डिज्नी एक फिल्म में बना रहा है।
रेनबोल्ट

1
वास्तव में 8 किताबें हैं।
काइल कानोस

7
अधिक मर्जर (जब तक आप समय का पहिया पढ़ रहे हैं)
मर्जर

1
और तुम break;अपने में भूल गए switch
जॉनचेन 902

1
@ johnchen902, @ Manu: मैं जावा में बहुत अनुभवी नहीं हूं (मैं फोरट्रान 90 + का उपयोग करता हूं और केवल जावा को यहां देखता हूं), इसलिए मेरी त्रुटियां हैं। एक घंटे में कार्यालय में आने पर मैं उन्हें ठीक कर दूँगा।
काइल कानोस

19

Disparnumerophobic

विषम संख्याएँ भयानक हैं।

package Humans;

public class Disparnumerophobic extends Human {
    public final String takeSides(String history) {
        int good = 0, evil = 0;
        for(int i = 0; i < history.length(); i++)   {
            switch(history.charAt(i))   {
                case '0': evil++; break;
                case '1': good++;
            }
        }
        if(good%2 == 1 && evil%2 == 0)  return "evil";
        if(evil%2 == 1 && good%2 == 0)  return "good";
        // well shit.... 
        return Math.random() >= 0.5 ? "good" : "evil";
    }
}

17
टिप्पणी ने मुझे हंसाया / फंसाया।
फेयरफॉक्स

17

लिनस, रूबी

हमेशा पैटर्न को तोड़कर विश्लेषकों को भ्रमित करना चाहता है ।

num_rounds = ARGV[0].to_s.count(',')
LINUS_SEQ = 0xcb13b2d3734ecb4dc8cb134b232c4d3b2dcd3b2d3734ec4d2c8cb134b234dcd3b2d3734ec4d2c8cb134b23734ecb4dcd3b2c4d232c4d2c8cb13b2d3734ecb4dcb232c4d2c8cb13b2d3734ecb4dc8cb134b232c4d3b2dcd3b2d3734ec4d2c8cb134b234dcd3b2d3734ec4d2c8cb134b23734ecb4dcd3b2c4d2c8cb134b2
puts %w[good evil][LINUS_SEQ[num_rounds]]

के रूप में सहेजें linus.rbऔर साथ चलाएंruby linus.rb


16

बैकपैकर

एक खिलाड़ी को निर्धारित करता है जिसने मिलान अल्पसंख्यक को अभी तक चुना है और अपना अंतिम वोट चुनता है।

package Humans;

public class BackPacker extends Human {
    // toggles weather the BackPacker thinks majority is better vs. minority is better
    private static final boolean goWithMajority = false;

    @Override
    public final String takeSides(String history)  {
        if (history == null || history.equals(""))
            return "evil";
        String[] roundVotes = history.split(",");
        int players = roundVotes[0].length();
        int[] winningPlayers = new int[players];
        for (String nextRound : roundVotes) {
            boolean didGoodWin = didGoodWin(nextRound, players);
            for (int player = 0; player < nextRound.length(); player++) {
                boolean playerVotedGood = nextRound.charAt(player) == '1';
                winningPlayers[player] += didPlayerWin(didGoodWin, playerVotedGood);
            }
        }
        int bestScore = -1;
        for (int nextPlayer : winningPlayers)
            if (bestScore < nextPlayer)
                bestScore = nextPlayer;
        int bestPlayer = 0;
        for (int ii = 0; ii < players; ii++) {
            if (winningPlayers[ii] == bestScore) {
                bestPlayer = ii;
                break;
            }
        }
        if (roundVotes[roundVotes.length - 1].charAt(bestPlayer) == '1')
            return "good";
        return "evil";
    }

    private int didPlayerWin(boolean didGoodWin, boolean playerVotedGood) {
        if(goWithMajority) {
            return ((didGoodWin && playerVotedGood) || (!didGoodWin && !playerVotedGood)) ? 1 : 0;
        } else {
            return ((!didGoodWin && playerVotedGood) || (didGoodWin && !playerVotedGood)) ? 1 : 0;
        }
    }

    private boolean didGoodWin(String round, int players) {
        int good = 0;
        for (char next : round.toCharArray())
            good += next == '1' ? 1 : 0;
        return (good * 2) > players;
    }
}

क्राउडफॉलोअर

एक खिलाड़ी को निर्धारित करता है जिसने मिलान बहुमत को अभी तक चुना है और अपना अंतिम वोट चुनता है।

package Humans;

public class CrowdFollower extends Human {
    // toggles weather the FrontPacker thinks majority is better vs. minority is better
    private static final boolean goWithMajority = true;

    @Override
    public final String takeSides(String history)  {
        if (history == null || history.equals(""))
            return "evil";
        String[] roundVotes = history.split(",");
        int players = roundVotes[0].length();
        int[] winningPlayers = new int[players];
        for (String nextRound : roundVotes) {
            boolean didGoodWin = didGoodWin(nextRound, players);
            for (int player = 0; player < nextRound.length(); player++) {
                boolean playerVotedGood = nextRound.charAt(player) == '1';
                winningPlayers[player] += didPlayerWin(didGoodWin, playerVotedGood);
            }
        }
        int bestScore = -1;
        for (int nextPlayer : winningPlayers)
            if (bestScore < nextPlayer)
                bestScore = nextPlayer;
        int bestPlayer = 0;
        for (int ii = 0; ii < players; ii++) {
            if (winningPlayers[ii] == bestScore) {
                bestPlayer = ii;
                break;
            }
        }
        if (roundVotes[roundVotes.length - 1].charAt(bestPlayer) == '1')
            return "good";
        return "evil";
    }

    private int didPlayerWin(boolean didGoodWin, boolean playerVotedGood) {
        if(goWithMajority) {
            return ((didGoodWin && playerVotedGood) || (!didGoodWin && !playerVotedGood)) ? 1 : 0;
        } else playerVotedGood                return ((!didGoodWin && good) || (didGoodWin && !playerVotedGood)) ? 1 : 0;
        }
    }

    private boolean didGoodWin(String round, int players) {
        int good = 0;
        for (char next : round.toCharArray())
            good += next == '1' ? 1 : 0;
        return (good * 2) > players;
    }
}

बहुत ही स्वच्छ कार्यक्रम!
रेनबोल्ट

वूप्स, मुझे लगता है कि मैंने आपके प्रोग्राम को एक अलग भाषा में कॉपी किया होगा।
प्युर्लेज़

@Rusher मैंने कोड को अपडेट किया और इसे दो प्रविष्टियों के रूप में जोड़ना चाहूंगा, एक के साथ goWithMajority = trueऔर एक जहां इसकी false। क्या यह ठीक है, या क्या मुझे इसके लिए दूसरा बैकपैकर जोड़ने की आवश्यकता है?
एंजेलो फुच

@AngeloNeuschitzer मैंने इस पोस्ट को संपादित किया। इस तरह, मैं दोनों प्रस्तुतियाँ जोड़ना नहीं भूलूंगा। मेरा सुझाव है कि आपने मेरे द्वारा दिए गए वास्तव में बिना नाम के नाम को बदल दिया है, और यदि आप चाहें तो शायद दोनों में एक विवरण जोड़ें।
रेनबोल्ट

1
@Rainbolt मुझे आपके FrontPacker बेहतर पसंद हैं, वास्तव में। Lol'd।
tomsmeding

15

ज्योतिषी

यह अभी भी प्रगति पर है। मैंने अभी तक इसका परीक्षण नहीं किया है। मैं सिर्फ यह देखना चाहता था कि ओपी को लगता है कि वह नियमों को तोड़ता है या नहीं।

यह विचार अगले दौर में सभी अन्य प्रतिभागियों को निष्पादित करके परिणाम की संभावना प्राप्त करने और तदनुसार कार्य करने के लिए अनुकरण करने का है।

package Humans;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import sun.net.www.protocol.file.FileURLConnection;

public class FortuneTeller extends Human {

/**
 * Code from http://stackoverflow.com/a/22462785 Private helper method
 *
 * @param directory The directory to start with
 * @param pckgname The package name to search for. Will be needed for
 * getting the Class object.
 * @param classes if a file isn't loaded but still is in the directory
 * @throws ClassNotFoundException
 */
private static void checkDirectory(File directory, String pckgname,
        ArrayList<Class<?>> classes) throws ClassNotFoundException {
    File tmpDirectory;

    if (directory.exists() && directory.isDirectory()) {
        final String[] files = directory.list();

        for (final String file : files) {
            if (file.endsWith(".class")) {
                try {
                    classes.add(Class.forName(pckgname + '.'
                            + file.substring(0, file.length() - 6)));
                } catch (final NoClassDefFoundError e) {
                // do nothing. this class hasn't been found by the
                    // loader, and we don't care.
                }
            } else if ((tmpDirectory = new File(directory, file))
                    .isDirectory()) {
                checkDirectory(tmpDirectory, pckgname + "." + file, classes);
            }
        }
    }
}

/**
 * Private helper method.
 *
 * @param connection the connection to the jar
 * @param pckgname the package name to search for
 * @param classes the current ArrayList of all classes. This method will
 * simply add new classes.
 * @throws ClassNotFoundException if a file isn't loaded but still is in the
 * jar file
 * @throws IOException if it can't correctly read from the jar file.
 */
private static void checkJarFile(JarURLConnection connection,
        String pckgname, ArrayList<Class<?>> classes)
        throws ClassNotFoundException, IOException {
    final JarFile jarFile = connection.getJarFile();
    final Enumeration<JarEntry> entries = jarFile.entries();
    String name;

    for (JarEntry jarEntry = null; entries.hasMoreElements()
            && ((jarEntry = entries.nextElement()) != null);) {
        name = jarEntry.getName();

        if (name.contains(".class")) {
            name = name.substring(0, name.length() - 6).replace('/', '.');

            if (name.contains(pckgname)) {
                classes.add(Class.forName(name));
            }
        }
    }
}

/**
 * Attempts to list all the classes in the specified package as determined
 * by the context class loader
 *
 * @param pckgname the package name to search
 * @return a list of classes that exist within that package
 * @throws ClassNotFoundException if something went wrong
 */
private static ArrayList<Class<?>> getClassesForPackage(String pckgname)
        throws ClassNotFoundException {
    final ArrayList<Class<?>> classes = new ArrayList<Class<?>>();

    try {
        final ClassLoader cld = Thread.currentThread()
                .getContextClassLoader();

        if (cld == null) {
            throw new ClassNotFoundException("Can't get class loader.");
        }

        final Enumeration<URL> resources = cld.getResources(pckgname
                .replace('.', '/'));
        URLConnection connection;

        for (URL url = null; resources.hasMoreElements()
                && ((url = resources.nextElement()) != null);) {
            try {
                connection = url.openConnection();

                if (connection instanceof JarURLConnection) {
                    checkJarFile((JarURLConnection) connection, pckgname,
                            classes);
                } else if (connection instanceof FileURLConnection) {
                    try {
                        checkDirectory(
                                new File(URLDecoder.decode(url.getPath(),
                                                "UTF-8")), pckgname, classes);
                    } catch (final UnsupportedEncodingException ex) {
                        throw new ClassNotFoundException(
                                pckgname
                                + " does not appear to be a valid package (Unsupported encoding)",
                                ex);
                    }
                } else {
                    throw new ClassNotFoundException(pckgname + " ("
                            + url.getPath()
                            + ") does not appear to be a valid package");
                }
            } catch (final IOException ioex) {
                throw new ClassNotFoundException(
                        "IOException was thrown when trying to get all resources for "
                        + pckgname, ioex);
            }
        }
    } catch (final NullPointerException ex) {
        throw new ClassNotFoundException(
                pckgname
                + " does not appear to be a valid package (Null pointer exception)",
                ex);
    } catch (final IOException ioex) {
        throw new ClassNotFoundException(
                "IOException was thrown when trying to get all resources for "
                + pckgname, ioex);
    }

    return classes;
}

private static boolean isRecursiveCall = false;
private static ArrayList<Class<?>> classes;

static {
    if (classes == null) {
        try {
            classes = getClassesForPackage("Humans");
        } catch (ClassNotFoundException ex) {

        }
    }    
}

private String doThePetyrBaelish() {
    return Math.random() >= 0.5 ? "good" : "evil";
}

@Override
public String takeSides(String history) {
    if (isRecursiveCall) {
        return doThePetyrBaelish();
    }
    isRecursiveCall = true;

    int currentRoundGoodCount = 0;
    float probabilityOfGood = 0;
    int roundCount = 0;
    int voteCount = 0;



    do {
        for (int i = 0; i < classes.size(); i++) {
            try {
                if (classes.get(i).getName() == "Humans.FortuneTeller") {
                    continue;
                }

                Human human = (Human) classes.get(i).newInstance();
                String response = human.takeSides(history);
                switch (response) {
                    case "good":
                        currentRoundGoodCount++;
                        voteCount++;
                        break;
                    case "evil":
                        voteCount++;
                        break;
                    default:
                        break;
                }
            } catch (Exception e) {
            }
        }

        probabilityOfGood = (probabilityOfGood * roundCount
                + (float) currentRoundGoodCount / voteCount) / (roundCount + 1);

        roundCount++;
        currentRoundGoodCount = 0;
        voteCount = 0;

    } while (roundCount < 11);

    isRecursiveCall = false;
    if (probabilityOfGood > .7) {
        return "evil";
    }
    if (probabilityOfGood < .3) {
        return "good";
    }

    return doThePetyrBaelish();
}

}

यदि आपका बॉट उत्तर देने से पहले प्रत्येक अन्य बॉट चलाता है, तो क्या इसका उत्तर देने में 1s से अधिक नहीं लगेगा?
प्लेनैपस जूल

@plannapus मैं इस बॉट के साथ धारणा का अनुमान लगाने जा रहा हूं, यह है कि हर कोई सावधानी के साथ गलती करने जा रहा है और प्रतीक्षा के करीब 1 सेकंड के करीब कुछ भी नहीं बचा है। मैं सोच रहा हूँ कि यह सार्थक और प्रविष्टि हो सकती है जिसमें 0.9 सेकंड की प्रतीक्षा शामिल है, "अच्छा" लौटने से पहले, बस उसके साथ गड़बड़ करने के लिए। वास्तव में, एसबॉस ने मुझे इसके लिए हराया: डी
स्क्रगर

Yahhh! फिर मुझे अपने कोड में उस बॉट को ब्लैकलिस्ट करना होगा। यह निराशाजनक होगा ... इसके अलावा पायथन या पर्ल जैसे विभिन्न वातावरणों में विभिन्न प्रविष्टियों के साथ दुभाषिया की पुनः लोड की गई लोडिंग इस कोड को समय सीमा से ऊपर लाने के लिए पर्याप्त हो सकती है।
एंड्रीस

16
यदि कोई दूसरा ऐसा करता है, तो आपको एक अनंत लूप मिलता है।
ब्रिलियनड

4
प्रस्तुत समय समाप्त हो गया। मैंने एक प्रोफाइलर को संलग्न किया, और कुछ सबमिशन को बुलाते हुए लगभग आधा सेकंड बिताया जाता है। यह कम से कम काम करता है, लेकिन इसके लिए बधाई देता हूं।
रेनबोल्ट

15

सी ++, वैज्ञानिक

यह उस इतिहास के साथ की कोशिश करता है, जिसमें बहुमत ने प्रति राउंड को चुना था wave( majority()एक दौर में बहुमत की पसंद देता है), तरंगदैर्ध्य 2*periodऔर चरण के डेटा के लिए एक लहर फिट phase। इस प्रकार, 0,1,1,1,0,1,0,1,1,1,0,0,0,1,0इसे देखते हुए period=3, phase=5( maxat=={3,5}): इसके स्कोर बन जाते हैं 9 3 11 5 5 3 5 7 9 7 7 7 7 7 7। यह सभी संभावित अवधियों पर लूप करता है और यदि, उस अवधि के लिए, स्कोर वर्तमान अधिकतम की तुलना में अधिक है, तो यह स्टोर करता है{period,phase} है जिसके लिए यह हुआ।

यह तब मिली हुई लहर को अगले दौर में ले जाता है और अनुमानित बहुमत लेता है।

#include <iostream>
#include <utility>
#include <cstdlib>
#include <cstring>
#if 0
#define DBG(st) {st}
#else
#define DBG(st)
#endif

#define WINDOW (700)

using namespace std;

int majority(const char *r){
    int p=0,a=0,b=0;
    while(true){
        if(r[p]=='1')a++;
        else if(r[p]=='0')b++;
        else break;
        p++;
    }
    return a>b;
}

int main(int argc,char **argv){
    if(argc==1){
        cout<<(rand()%2?"good":"evil")<<endl;
        return 0;
    }
    DBG(cerr<<"WINDOW="<<WINDOW<<endl;)
    int nump,numr;
    nump=strchr(argv[1],',')-argv[1];
    numr=(strlen(argv[1])+1)/(nump+1);
    int fromround=numr-30;
    if(fromround<0)fromround=0;
    int period,r;
    int *wave=new int[WINDOW];
    bool allequal=true;
    DBG(cerr<<"wave: ";)
    for(r=fromround;r<numr;r++){
        wave[r-fromround]=majority(argv[1]+r*(nump+1));
        if(wave[r-fromround]!=wave[0])allequal=false;
        DBG(cerr<<wave[r]<<" ";)
    }
    DBG(cerr<<endl;)
    if(allequal){
        DBG(cerr<<"All equal!"<<endl;)
        if(wave[numr-1]==1)cout<<"evil"<<endl; //choose for minority
        else cout<<"good"<<endl;
        return 0;
    }
    int score,*scores=new int[WINDOW];
    int max=0; //some score will always get above 0, because if some score<0, the inverted wave will be >0.
    int phase,phasemax;
    pair<int,int> maxat(-1,-1); //period, phase
    DBG(cerr<<"scores: ";)
    for(period=1;period<=WINDOW;period++){
        scores[period-1]=0;
        phasemax=-1;
        for(phase=0;phase<2*period;phase++){
            score=0;
            for(r=fromround;r<numr;r++){
                if(wave[r]==1-(r+phase)%(2*period)/period)score++;
                else score--;
            }
            if(score>scores[period-1]){
                scores[period-1]=score;
                phasemax=phase;
            }
        }
        if(scores[period-1]>max){
            max=scores[period-1];
            maxat.first=period;
            maxat.second=phasemax;
        }
        DBG(cerr<<scores[period-1]<<" ";)
    }
    DBG(cerr<<"(max="<<max<<" at {"<<maxat.first<<","<<maxat.second<<"})"<<endl;)
    DBG(cerr<<" max: ("<<numr<<"+"<<maxat.second<<")%(2*"<<maxat.first<<")/"<<maxat.first<<"=="<<((numr+maxat.second)%(2*maxat.first)/maxat.first)<<endl;)
    if(1-(numr+maxat.second)%(2*maxat.first)/maxat.first==1)cout<<"evil"<<endl; //choose for minority
    else cout<<"good"<<endl;
    delete[] wave;
    delete[] scores;
    return 0;
}

के साथ संकलित करें g++ -O3 -std=c++0x -o Scientist Scientist.cpp(आपको चेतावनियों की आवश्यकता नहीं है, इसलिए नहीं -Wall) और साथ चलाएंScientist.exe(संभवतः पाठ्यक्रम के तर्क सहित)। यदि आप वास्तव में अच्छी तरह से पूछते हैं तो मैं आपको एक विंडोज निष्पादन योग्य प्रदान कर सकता हूं।

ओह, और इनपुट प्रारूप के साथ खिलवाड़ करने की हिम्मत मत करो। यह अजीब बातें करेंगे अन्यथा।

संपादित करें: जाहिरा तौर पर, पिछला संस्करण खेल में लगभग 600 राउंड के समय से बाहर चला गया था। ऐसा नहीं करना चाहिए। इसके समय की खपत #define WINDOW (...)लाइन द्वारा नियंत्रित होती है , अधिक धीमी होती है लेकिन आगे पीछे दिखती है।


8
इंटरनेट पर साठ + अजनबियों द्वारा लिखी गई फांसी को डाउनलोड करना एक बुरे विचार की तरह लगता है।
रेनबोल्ड

@Rusher मैं पूरी तरह से सहमत हूँ। यदि आप समस्याएं चाहते हैं, तो वह "डमीज़ के लिए" गाइड में एक कदम है। मेरा प्रस्ताव हालांकि खड़ा है :)
tomsmeding

2
यह संकलन करने के लिए मिला (और प्रतिस्पर्धा) ठीक है।
रेनबोल्ट

14

कोड रनर

इसलिए, चीजों को दिलचस्प बनाने के लिए, मैंने प्रत्येक पोस्ट किए गए उत्तर से कोड को स्वचालित रूप से डाउनलोड करने के लिए एक स्क्रिप्ट बनाई, यदि आवश्यक हो, तो इसे संकलित करें और फिर सभी समाधान नियमों के अनुसार चलाएं। इस तरह, लोग जांच कर सकते हैं कि वे कैसे कर रहे हैं। बस इस स्क्रिप्ट को run_all.py में सेव करें (BeautifulSoup की आवश्यकता है) और फिर:

usage:
To get the latest code: 'python run_all.py get'
To run the submissions: 'python run_all.py run <optional num_runs>'

कुछ बातें:

  1. यदि आप अधिक भाषाओं के लिए समर्थन जोड़ना चाहते हैं, या वैकल्पिक रूप से कुछ के लिए समर्थन निकालना चाहते हैं, तो देखें def submission_type(lang)
  2. स्क्रिप्ट का विस्तार काफी आसान होना चाहिए, यहां तक ​​कि उन भाषाओं के लिए भी जिन्हें संकलन की आवश्यकता होती है (देखें CPPSubmission )। भाषा का प्रकार मेटा कोड टैग से पकड़ा गया है < !-- language: lang-java -- >, इसलिए यदि आप चाहते हैं कि आपका कोड चलाया जाए तो इसे जोड़ना सुनिश्चित करें (<> से पहले और बाद में अतिरिक्त रिक्त स्थान निकालें)। अद्यतन : यदि भाषा परिभाषित नहीं है, तो उसे खोजने और जानने की कोशिश करने के लिए अब कुछ अत्यंत बुनियादी अनुमान हैं।
  3. यदि आपका कोड बिल्कुल नहीं चल पाता है, या आवंटित समय के भीतर समाप्त होने में विफल रहता है, तो इसे जोड़ा जाएगा blacklist.text दिया जाएगा और भविष्य में स्वचालित रूप से हटा दिया जाएगा। यदि आप अपना कोड ठीक करते हैं, तो अपनी प्रविष्टि को ब्लैकलिस्ट से हटा दें और फिर से चलाएँ get,

वर्तमान में समर्थित भाषाएँ:

 submission_types =  {
    'lang-ruby': RubySubmission,
    'lang-python': PythonSubmission,
    'lang-py': PythonSubmission,
    'lang-java': JavaSubmission,
    'lang-Java': JavaSubmission,
    'lang-javascript': NodeSubmission,
    'lang-cpp': CPPSubmission,
    'lang-c': CSubmission,
    'lang-lua': LuaSubmission,
    'lang-r': RSubmission,
    'lang-fortran': FortranSubmission,
    'lang-bash': BashSubmission
}

बिना और देरी के:

import urllib2
import hashlib
import os
import re
import subprocess
import shutil
import time
import multiprocessing
import tempfile
import sys
from bs4 import BeautifulSoup

__run_java__ = """
public class Run {
    public static void main(String[] args) {
        String input = "";
        Human h = new __REPLACE_ME__();
        if(args.length == 1)
            input = args[0];
        try {
            System.out.println(h.takeSides(input));
        }
        catch(Exception e) {
        }
    }
}
"""

__human_java__ = """
public abstract class Human {
    public abstract String takeSides(String history) throws Exception;
}
"""

class Submission():
    def __init__(self, name, code):
        self.name = name
        self.code = code

    def submissions_dir(self):
        return 'submission'

    def base_name(self):
        return 'run'

    def submission_path(self):
        return os.path.join(self.submissions_dir(), self.name)

    def extension(self):
        return ""

    def save_submission(self):
        self.save_code()

    def full_command(self, input):
        return []

    def full_path(self):
        file_name = "%s.%s" % (self.base_name(), self.extension())
        full_path = os.path.join(self.submission_path(), file_name)
        return full_path

    def save_code(self):    
        if not os.path.exists(self.submission_path()):
            os.makedirs(self.submission_path())

        with open(self.full_path(), 'w') as f:
            f.write(self.code)

    def write_err(self, err):
        with open(self.error_log(), 'w') as f:
            f.write(err)

    def error_log(self):
        return os.path.join(self.submission_path(), 'error.txt')

    def run_submission(self, input):
        command = self.full_command()
        if input is not None:
            command.append(input)
        try:
            output,err,exit_code = run(command,timeout=1)
            if len(err) > 0:
                self.write_err(err)
            return output
        except Exception as e:
            self.write_err(str(e))
            return ""

class CPPSubmission(Submission):
    def bin_path(self):
        return os.path.join(self.submission_path(), self.base_name())

    def save_submission(self):
        self.save_code()
        compile_cmd = ['g++', '-O3', '-std=c++0x', '-o', self.bin_path(), self.full_path()]
        errout = open(self.error_log(), 'w')
        subprocess.call(compile_cmd, stdout=errout, stderr=subprocess.STDOUT)

    def extension(self):
        return 'cpp'

    def full_command(self):
        return [self.bin_path()]

class CSubmission(Submission):
    def bin_path(self):
        return os.path.join(self.submission_path(), self.base_name())

    def save_submission(self):
        self.save_code()
        compile_cmd = ['gcc', '-o', self.bin_path(), self.full_path()]
        errout = open(self.error_log(), 'w')
        subprocess.call(compile_cmd, stdout=errout, stderr=subprocess.STDOUT)

    def extension(self):
        return 'c'

    def full_command(self):
        return [self.bin_path()]

class FortranSubmission(Submission):
    def bin_path(self):
        return os.path.join(self.submission_path(), self.base_name())

    def save_submission(self):
        self.save_code()
        compile_cmd = ['gfortran', '-fno-range-check', '-o', self.bin_path(), self.full_path()]
        errout = open(self.error_log(), 'w')
        subprocess.call(compile_cmd, stdout=errout, stderr=subprocess.STDOUT)

    def extension(self):
        return 'f90'

    def full_command(self):
        return [self.bin_path()]

class JavaSubmission(Submission):   
    def base_name(self):
        class_name = re.search(r'class (\w+) extends', self.code)
        file_name = class_name.group(1)
        return file_name

    def human_base_name(self):
        return 'Human'

    def run_base_name(self):
        return 'Run'

    def full_name(self, base_name):
        return '%s.%s' % (base_name, self.extension())

    def human_path(self):
        return os.path.join(self.submission_path(), self.full_name(self.human_base_name()))

    def run_path(self):
        return os.path.join(self.submission_path(), self.full_name(self.run_base_name()))

    def replace_in_file(self, file_name, str_orig, str_new):
        old_data = open(file_name).read()
        new_data = old_data.replace(str_orig, str_new)

        with open(file_name, 'w') as f:
            f.write(new_data)

    def write_code_to_file(self, code_str, file_name):
        with open(file_name, 'w') as f:
            f.write(code_str)

    def save_submission(self):
        self.save_code()
        self.write_code_to_file(__human_java__, self.human_path())
        self.write_code_to_file(__run_java__, self.run_path())

        self.replace_in_file(self.run_path(), '__REPLACE_ME__', self.base_name())
        self.replace_in_file(self.full_path(), 'package Humans;', '')

        compile_cmd = ['javac', '-cp', self.submission_path(), self.run_path()]
        errout = open(self.error_log(), 'w')
        subprocess.call(compile_cmd, stdout=errout, stderr=subprocess.STDOUT)

    def extension(self):
        return 'java'

    def full_command(self):
        return ['java', '-cp', self.submission_path(), self.run_base_name()]

class PythonSubmission(Submission):
    def full_command(self):
        return ['python', self.full_path()]

    def extension(self):
        return 'py'

class RubySubmission(Submission):
    def full_command(self):
        return ['ruby', self.full_path()]

    def extension(self):
        return 'rb'

class NodeSubmission(Submission):
    def full_command(self):
        return ['node', self.full_path()]

    def extension(self):
        return 'js'

class LuaSubmission(Submission):
    def full_command(self):
        return ['lua', self.full_path()]

    def extension(self):
        return 'lua'

class RSubmission(Submission):
    def full_command(self):
        return ['Rscript', self.full_path()]

    def extension(self):
        return 'R'

class BashSubmission(Submission):
    def full_command(self):
        return [self.full_path()]

    def extension(self):
        return '.sh'

class Scraper():
    def download_page(self, url, use_cache = True, force_cache_update = False):
        file_name = hashlib.sha1(url).hexdigest()

        if not os.path.exists('cache'):
            os.makedirs('cache')

        full_path = os.path.join('cache', file_name)
        file_exists = os.path.isfile(full_path)

        if use_cache and file_exists and not force_cache_update:
            html = open(full_path, 'r').read()
            return html

        opener = urllib2.build_opener()
        opener.addheaders = [('User-agent', 'Mozilla/5.0')]
        response = opener.open(url)
        html = response.read()

        if use_cache:
            f = open(full_path, 'w')
            f.write(html)
            f.close()

        return html

    def parse_post(self, post):
        name = post.find(text=lambda t: len(t.strip()) > 0)
        pre = post.find('pre')
        lang = pre.attrs['class'][0] if pre.has_attr('class') else None
        code = pre.find('code').text
        user = post.find(class_='user-details').find(text=True)
        return {'name':name,'lang':lang,'code':code,'user':user}

    def parse_posts(self, html):
        soup = BeautifulSoup(html)
        # Skip the first post
        posts = soup.find_all(class_ = 'answercell')
        return [self.parse_post(post) for post in posts]

    def get_submissions(self,  page = 1, force_cache_update = False):
        url = "http://codegolf.stackexchange.com/questions/33137/good-versus-evil?page=%i&tab=votes#tab-top" % page
        html = self.download_page(url, use_cache = True, force_cache_update = force_cache_update)
        submissions = self.parse_posts(html)
        return submissions

class Timeout(Exception):
    pass

def run(command, timeout=10):
    proc = subprocess.Popen(command, bufsize=0, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    poll_seconds = .250
    deadline = time.time()+timeout
    while time.time() < deadline and proc.poll() == None:
        time.sleep(poll_seconds)

    if proc.poll() == None:
        if float(sys.version[:3]) >= 2.6:
            proc.terminate()
        raise Timeout()

    stdout, stderr = proc.communicate()
    return stdout, stderr, proc.returncode


def guess_lang(code):
    if re.search(r'class .* extends Human', code):
        return 'lang-java'
    if re.search(r'import sys', code):
        return 'lang-python'
    if re.search(r'puts', code) and (re.search(r'ARGV', code) or re.search(r'\%w', code)):
        return 'lang-ruby'
    if re.search(r'console\.log', code):
        return 'lang-javascript'
    if re.search(r'program', code) and re.search(r'subroutine', code):
        return 'lang-fortran'
    if re.search(r'@echo off', code):
        return 'lang-bash'
    return None


def submission_type(lang, code):
    submission_types =  {
        'lang-ruby': RubySubmission,
        'lang-python': PythonSubmission,
        'lang-py': PythonSubmission,
        'lang-java': JavaSubmission,
        'lang-Java': JavaSubmission,
        'lang-javascript': NodeSubmission,
        'lang-cpp': CPPSubmission,
        'lang-c': CSubmission,
        'lang-lua': LuaSubmission,
        'lang-r': RSubmission,
        'lang-fortran': FortranSubmission,
        'lang-bash': BashSubmission
    }

    klass = submission_types.get(lang)

    if klass is None:
        lang = guess_lang(code)
        klass = submission_types.get(lang)

    return klass

def instantiate(submission):
    lang = submission['lang']
    code = submission['code']
    name = submission['name']

    klass = submission_type(lang, code)
    if klass is not None:
        instance = klass(name, code)
        return instance
    print "Entry %s invalid - lang not supported: %s" % (name, lang)
    return None

def get_all_instances(force_update):
    scraper = Scraper()

    print 'Scraping Submissions..'

    pages = [1,2,3]
    submissions_by_page = [scraper.get_submissions(page=i, force_cache_update=force_update) for i in pages]
    submissions = [item for sublist in submissions_by_page for item in sublist]

    # Get instances
    raw_instances = [instantiate(s) for s in submissions]
    instances = [i for i in raw_instances if i]

    print "Using %i/%i Submissions" % (len(instances), len(submissions))

    return instances

def save_submissions(instances):
    print 'Saving Submissions..'

    for instance in instances:
        instance.save_submission()

def init_game(save=True, force_update=False):
    instances = get_all_instances(force_update)
    if save:
        save_submissions(instances)
    return instances

def one_run(instances, input):
    valid = {
        'good': 1,
        'evil': 0
    }

    disqualified = []
    results = []

    for instance in instances:
        out = instance.run_submission(input)
        res = out.strip().lower()
        if res not in valid:
            disqualified.append(instance)
        else:
            results.append(valid[res])

    return (results, disqualified)

def get_winner(scores, instances):
    max_value = max(scores)
    max_index = scores.index(max_value)
    instance = instances[max_index]
    return (instance.name, max_value)

def update_scores(results, scores, minority_counts, minority_num):
    for i in range(len(results)):
        if results[i] == minority_num:
            minority_counts[i] += 1
            scores[i] += (minority_counts[i] - 1)
        else:
            minority_counts[i] = 0
            scores[i] += 3

def try_run_game(instances, num_runs = 1000, blacklist = None):
    current_input = None
    minority_str = None
    num_instances = len(instances)
    scores = [0] * num_instances
    minority_counts = [0] * num_instances

    print "Running with %i instances..." % num_instances

    for i in range(num_runs):
        print "Round: %i - Last minority was %s" % (i, minority_str)
        results, disqualified = one_run(instances, current_input)

        if len(disqualified) > 0:
            for instance in disqualified:
                print "Removing %s!" % instance.name
                instances.remove(instance)

                if blacklist is not None:
                    with open(blacklist, 'a') as f:
                        f.write("%s\n" % instance.name)

            return False

        latest_result = "".join(map(str,results))
        current_input = "%s,%s" % (current_input, latest_result)

        minority_num = 1 if results.count(1) < results.count(0) else 0
        minority_str = 'good' if minority_num == 1 else 'evil'

        update_scores(results, scores, minority_counts, minority_num)
        name, score = get_winner(scores, instances)
        print "%s is currently winning with a score of %i" % (name, score)

    print "The winner is %s with a score of %i!!!" % (name, score)
    return True

def find_instance_by_name(instances, name):
    for instance in instances:
        if instance.name == name:
            return instance
    return None

def maybe_add_or_remove_baelish(instances, baelish):
    num_instances = len(instances)

    if num_instances % 2 == 0:
        print 'There are %i instances.' % num_instances
        try:
            instances.remove(baelish)
            print 'Baelish Removed!'
        except:
            instances.append(baelish)
            print 'Baelish Added!'

def remove_blacklisted(blacklist, instances):
    blacklisted = []

    try:
        blacklisted = open(blacklist).readlines()
    except:
        return

    print 'Removing blacklisted entries...'

    for name in blacklisted:
        name = name.strip()
        instance = find_instance_by_name(instances, name)
        if instance is not None:
            print 'Removing %s' % name
            instances.remove(instance)

def run_game(instances, num_runs):
    blacklist = 'blacklist.txt'
    remove_blacklisted(blacklist, instances)

    baelish = find_instance_by_name(instances, 'Petyr Baelish') 
    maybe_add_or_remove_baelish(instances, baelish)

    while not try_run_game(instances, num_runs = num_runs, blacklist = blacklist):
        print "Restarting!"
        maybe_add_or_remove_baelish(instances, baelish)

    print "Done!"

if __name__ == '__main__':
    param = sys.argv[1] if len(sys.argv) >= 2 else None

    if param == 'get':
        instances = init_game(save=True, force_update=True)
    elif param == 'run':
        instances = init_game(save=False, force_update=False)
        num_runs = 50
        if len(sys.argv) == 3:
            num_runs = int(sys.argv[2])
        run_game(instances, num_runs)
    else:
        self_name = os.path.basename(__file__)
        print "usage:"
        print "To get the latest code: 'python %s get'" % self_name
        print "To run the submissions: 'python %s run <optional num_runs>'" % self_name


@KyleKanos - मैंने इसके लिए समर्थन जोड़ा है, शीघ्र ही कोड को अपडेट कर देगा।
WhatWorld

वाह! मैं (सॉर्टा) ने अपने फोरट्रान सबमिशन पर कड़ी मेहनत की और रशियर को यह काम करने के लिए नहीं मिला, इसलिए मैं चाहूंगा कि कोई इसे प्राप्त करे :)
काइल कानोस

1
@Rusher: मैं इस पर पीटरटायलर से सहमत हूं: केवल सुझाए गए संपादन को हाइलाइट करते हुए सिंटैक्स को अस्वीकार कर दिया जाना चाहिए। संपादन का उपयोग पर्याप्त सुधार के लिए किया जाना चाहिए , ना कि मामूली सामान के लिए।
काइल कानोस

1
आप इसके लिए प्रतिनिधि के लायक हैं, लेकिन चूंकि यह सवाल का जवाब नहीं है (और शायद समुदाय को अन्य भाषाओं के लिए सामान जोड़ने से फायदा हो सकता है) मुझे लगता है कि यह तकनीकी रूप से एक समुदाय विकि होना चाहिए।
मार्टिन एंडर

13

द ब्यूटीफुल माइंड, रूबी

अंतिम दौर के बिट प्रतिनिधित्व में संदिग्ध महत्व के पैटर्न के आधार पर अपना निर्णय लेता है

require 'prime'

if ARGV.length == 0
    puts ["good", "evil"].sample
else
    last_round = ARGV[0].split(',').last
    puts Prime.prime?(last_round.to_i(2)) ? "good" : "evil"
end

जैसे दौड़ो

ruby beautiful-mind.rb

13

प्यूस्टिटियस, लुआ

एक अंधविश्वासी कार्यक्रम जो संकेत और चमत्कार में विश्वास करता है।

history = arg[1]

if history == nil then
    print("good")
else
    local EvilSigns, GoodSigns = 0,0
    local SoulSpace = ""

    for i in string.gmatch(history, "%d+") do
         SoulSpace = SoulSpace .. i 
    end

    if string.match(SoulSpace, "1010011010")  then -- THE NUBMER OF THE BEAST!
        local r = math.random(1000)
        if r <= 666 then print("evil") else print("good") end
    else
        for i in string.gmatch(SoulSpace, "10100") do -- "I'M COMING" - DEVIL
            EvilSigns = EvilSigns + 1
        end
        for i in string.gmatch(SoulSpace, "11010") do -- "ALL IS WELL" - GOD
            GoodSigns = GoodSigns + 1
        end

        if EvilSigns > GoodSigns then 
            print("evil")
        elseif GoodSigns > EvilSigns then
            print("good")
        elseif GoodSigns == EvilSigns then
            local r = math.random(1000)
            if r <= 666 then print("good") else print("evil") end
        end
    end
end

इसे चलाएं:

lua Piustitious.lua

इनपुट के बाद।


11

विजेता

सैम और डीन अच्छे हैं (ज्यादातर समय)।

package Humans;

public class TheWinchesters extends Human {

    @Override
    public String takeSides(String history) throws Exception {
        return Math.random() < 0.1 ? "evil" : "good";
    }

}

क्या आप सुनिश्चित हैं कि 9:1सही अनुपात है? शायद हमें कुछ डेटा खनन करना चाहिए और अधिक सटीक अनुपात प्राप्त करना चाहिए ?
पुनरावृत्ति.निंजा

1
@ वाशबर्न मैं अलौकिक 2 महीने पहले देखना शुरू कर दिया (अब सीजन 9 में फंस गया) और 9:1मेरे लिए ठीक लगता है;)
कॉमनग्य

10

सांख्यिकीविद

public class Statistician extends Human{
    public final String takeSides(String history) { 
        int side = 0;
        String[] hist = history.split(",");
        for(int i=0;i<hist.length;i++){
            for(char c:hist[i].toCharArray()){
                side += c == '1' ? (i + 1) : -(i + 1);
            }
        }
        if(side == 0) side += Math.round(Math.random());
        return side > 0 ? "good" : "evil";
    }
}

5
वह दूसरी अंतिम पंक्ति इतनी भयानक है
cjfaure

5
@ इसके बजाय Math.ceil(Math.random()-Math.random())आप सिर्फ कर सकते हैं Math.round(Math.random())
tomsmeding

10

आर, कुछ हद तक बायेसियन बॉट

प्रत्येक उपयोगकर्ता के लिए अन्य उपयोगकर्ता आउटपुट की पूर्व संभावना के रूप में आवृत्ति तालिका का उपयोग करें।

args <- commandArgs(TRUE)
if(length(args)!=0){
    history <- do.call(rbind,strsplit(args,","))
    history <- do.call(rbind,strsplit(history,""))
    tabulated <- apply(history,2,function(x)table(factor(x,0:1)))
    result <- names(which.max(table(apply(tabulated, 2, function(x)sample(0:1,1, prob=x)))))
    if(result=="1"){cat("good")}else{cat("evil")}
}else{
    cat("good")
    }

Rscript BayesianBot.Rइनपुट के बाद उपयोग में लाया गया।

संपादित करें : यह स्पष्ट करने के लिए कि यह क्या कर रहा है, यहां उदाहरण इनपुट के साथ कदम से कदम है:

> args
[1] "11011,00101,11101,11111,00001,11001,11001"
> history #Each player is a column, each round a row
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    1    0    1    1
[2,]    0    0    1    0    1
[3,]    1    1    1    0    1
[4,]    1    1    1    1    1
[5,]    0    0    0    0    1
[6,]    1    1    0    0    1
[7,]    1    1    0    0    1

> tabulated #Tally of each player previous decisions.
  [,1] [,2] [,3] [,4] [,5]
0    2    2    4    5    0
1    5    5    3    2    7

फिर result<-प्रत्येक खिलाड़ी के लिए शुरू होने वाली रेखा , बेतरतीब ढंग से या तो 0 या 1 को इस अंतिम तालिका को वज़न के रूप में चुनती है (अर्थात खिलाड़ी 1 के लिए 0 चुनने की संभावना 2/7 वाँ है, जो कि 1 5/7 वें स्थान पर है)। यह प्रत्येक खिलाड़ी / स्तंभ के लिए एक परिणाम चुनता है और अंत में वह संख्या लौटाता है जो सबसे आम होती है।


10

स्विस

सदैव तटस्थता का निर्वाह करता है। कभी नहीं जीतने के लिए बर्बाद।

package Humans;

/**
 * Never choosing a side, sustaining neutrality
 * @author Fabian
 */
public class Swiss extends Human {   
    public String takeSides(String history) {
        return "neutral"; // wtf, how boring is that?
    }
}

मैंने यह नहीं लिखा!
रेनबोल्ट

यही विडंबना है। तटस्थता कभी नहीं जीतती है
फैबीगलर

2
@ रशर आह मुझे अब मिल गया: डी
फैब्लर

1
यह संकलन भी नहीं करता है - एक लापता अर्धविराम है।
पाओलो एबरमन जू

9

एचएएल 9000

#!/usr/bin/env perl
print eval("evil")

संपादित करें: शायद यह एचएएल 9000 के लिए अधिक उपयुक्त है, लेकिन सावधान रहें! यह बहुत बुराई है। मैं cdइसे चलाने से पहले निर्देशिका को खाली करने की सलाह देता हूं ।

#!/usr/bin/env perl
print eval {
    ($_) = grep { -f and !/$0$/ } glob('./*');
    unlink;
    evil
}

यह cwdप्रत्येक आह्वान के लिए एक फ़ाइल निकालता है !

इतना स्पष्ट आह्वान नहीं:

म $

D:\>copy con hal_9000.pl
#!/usr/bin/env perl
print eval("evil")
^Z
        1 file(s) copied.

D:>hal_9000.pl
evil

में * निक्स

[core1024@testing_pc ~]$ tee hal_9000.pl
#!/usr/bin/env perl
print eval("evil")
# Press C-D here
[core1024@testing_pc ~]$ chmod +x $_
[core1024@testing_pc ~]$ ./$_
evil[core1024@testing_pc ~]$

आपको एक कमांड प्रदान करने की आवश्यकता है जिसका उपयोग आपके प्रोग्राम को चलाने के लिए किया जा सकता है। अधिक जानकारी के लिए चुनौती का "वितरण" खंड देखें।
रेनबोल्ट

@ रशीर पूरा;)
कोर 1024

9

मेजरिटी का होगा

import sys
import random

if len(sys.argv)==1:
    print(random.choice(['good','evil']))
else:
    rounds=sys.argv[1].split(',')
    last_round=rounds[-1]
    zeroes=last_round.count('0')
    ones=last_round.count('1')
    if ones>zeroes:
        print('good')
    elif zeroes>ones:
        print('evil')
    elif ones==zeroes:
        print(random.choice(['good','evil']))

इसे इस रूप में सहेजें WotM.py , python3 WotM.pyइनपुट के बाद चलाएं ।

एक साधारण कार्यक्रम, बस यह देखना है कि यह कैसे होगा। बहुमत ने पिछली बार जो कुछ भी कहा, उसके साथ जाता है, या फिर यादृच्छिक।


आपको एक कमांड प्रदान करने की आवश्यकता है जिसका उपयोग आपके प्रोग्राम को चलाने के लिए किया जा सकता है। अधिक जानकारी के लिए चुनौती का "वितरण" खंड देखें।
रेनबोल्ट

लानत है, कि मुझे एक नकली बनाता है। : D ने अल्पसंख्यक को बदल दिया।
मार्टिन एंडर

@Rusher ने कमांड जोड़ी। कि तुम क्या देख रहे थे?
isaacg

@isaacg बिल्कुल सही!
रेनबोल्ट

1
मैंने स्कोरबोर्ड में स्कोर से औसत रैंकिंग की गणना की, और यह प्रविष्टि उस माप से जीतती है।
ब्रिलियनड

9

एलन शीयर

आगे जो भी व्यक्ति बैठा है उसे सिर्फ कहने के लिए दोहराता है। यदि व्यक्ति गलत हो जाता है, तो वह अगले व्यक्ति के लिए आगे बढ़ता है और इसके बजाय वे जो कहते हैं उसे दोहराते हैं।

package Humans;

/**
 * Alan Shearer copies someone whilst they're right; if they get predict
 * wrongly then he moves to the next person and copies whatever they say.
 *
 * @author Algy
 * @url http://codegolf.stackexchange.com/questions/33137/good-versus-evil
 */
public class AlanShearer extends Human {

    private char calculateWinner(String round) {
        int good = 0, evil = 0;

        for (int i = 0, L = round.length(); i < L; i++) {
            if (round.charAt(i) == '1') {
                good++;
            } else {
                evil++;
            }
        }

        return (good >= evil) ? '1' : '0';
    }

    /**
     * Take the side of good or evil.
     * @param history The past votes of every player
     * @return A String "good" or "evil
     */
    public String takeSides(String history) {
        String[] parts = history.split(",");
        String lastRound = parts[parts.length() - 1];

        if (parts.length() == 0 || lastRound.length() == 0) {
            return "good";
        } else {
            if (parts.length() == 1) {
                return lastRound.charAt(0) == '1' ? "good" : "evil";
            } else {
                int personToCopy = 0;

                for (int i = 0, L = parts.length(); i < L; i++) {
                    if (parts[i].charAt(personToCopy) != calculateWinner(parts[i])) {
                        personToCopy++;

                        if (personToCopy >= L) {
                            personToCopy = 0;
                        }
                    }
                }
            }

            return lastRound.charAt(personToCopy) == '1' ? "good" : "evil";
        }
    }
}

आप lastRoundइसे घोषित करने से पहले एक चर का संदर्भ देते हैं। साथ ही, आपने अपने सभी के लिए कोष्ठक जोड़े हैं, String.lengthलेकिन यह एक फ़ंक्शन नहीं है। क्या आप अपने बिंदु को एक ऐसे स्थान पर जमा कर सकते हैं जहाँ वह संकलन करेगा?
रेनबोल्ट

@ रशीर - किया :)
Algy टेलर

@Algy: lastRound.lengthअभी भी (पहले अगर में) एक्सेस किया गया है तो lastRoundघोषित किया गया है (यदि वह है तो)। कृपया यहां सबमिट करने से पहले अपना कोड संकलित करने का प्रयास करें (और शायद चलाएं)।
पाओलो एबरमन जुएल

@ Pa @loEbermann - क्षमायाचना, मैं ऐसे वातावरण में नहीं हूँ जहाँ मैं इसे चला
सकूँ

जब आप कार्यक्षेत्र से बाहर हो जाते हैं तो अब आप "personToCopy" नामक एक चर का संदर्भ दे रहे हैं। मैंने अभी इसे दूसरे ब्लॉक के अंदर स्थानांतरित किया है ताकि यह संकलित हो जाए, लेकिन मुझे नहीं पता कि क्या आप चाहते हैं।
रेनबोल्ट

8

बाद में ईविल, जावास्क्रिप्ट ( नोड.जेएस) है ) है

निष्पादन के बीच समय की मात्रा को मापता है। यदि समय का अंतर पिछली बार से अधिक है, तो यह बुराई होना चाहिए। नहीं तो अच्छा।

var fs = require('fs'),
currentTime = (new Date).getTime();

try {
    var data = fs.readFileSync('./laterisevil.txt', 'utf8');
} catch (e) { data = '0 0'; } // no file? no problem, let's start out evil at epoch

var parsed = data.match(/(\d+) (\d+)/),
lastTime = +parsed[1],
lastDifference = +parsed[2],
currentDifference = currentTime - lastTime;

fs.writeFileSync('./laterisevil.txt', currentTime + ' ' + currentDifference, 'utf8');
console.log(currentDifference > lastDifference? 'evil' : 'good');

साथ दौड़ो: node laterisevil.js


8

पैटर्न खोजक, पायथन

एक आवर्ती पैटर्न की तलाश करता है, और अगर यह एक नहीं मिल सकता है, तो बस बहुमत के साथ जाता है।

import sys

if len(sys.argv) == 1: 
    print('good')
    quit()

wins = ''.join(
    map(lambda s: str(int(s.count('1') > s.count('0'))),
        sys.argv[1].split(',')
    )
)

# look for a repeating pattern
accuracy = []

for n in range(1, len(wins)//2+1):
    predicted = wins[:n]*(len(wins)//n)
    actual    = wins[:len(predicted)]
    n_right = 0
    for p, a in zip(predicted, actual):
        n_right += (p == a)
    accuracy.append(n_right/len(predicted))

# if there's a good repeating pattern, use it
if accuracy:
    best = max(accuracy)
    if best > 0.8:
        n = accuracy.index(best)+1
        prediction = wins[:n][(len(wins))%n]
        # good chance of success by going with minority
        if prediction == '1':
            print('evil')
        else:
            print('good')
        quit()

# if there's no good pattern, just go with the majority
if wins.count('1') > wins.count('0'):
    print('good')
else:
    print('evil')

साथ दौड़ो

python3 pattern_finder.py

1
मुझे यह कोड बहुत पसंद है, जब मैं इसे चलाता हूं, तो इसे हमेशा 3000 पीटी मिलता है, किसी तरह।
रिएल्डो

8

टर्नकोट

टर्नकोट का मानना ​​है कि अब तक अन्य लड़ाकों के कारण, बहुसंख्यक अच्छे और बुरे के बीच प्रत्येक दौर के बाद वैकल्पिक रूप से एक ही पक्ष में रहने की तुलना में अधिक होगा। इस प्रकार वह पहले दौर की शुरुआत अच्छे से मनमानी करके करता है, फिर जीतने या हारने वाली टीम पर अधिक से अधिक बार नहीं रहने की कोशिश में हर दौर को वैकल्पिक बनाता है।

package Humans;

public class Turncoat extends Human {
    public final String takeSides(String history) {
        String[] hist = history.split(",");

        return (hist.length % 2) == 0 ? "good" : "evil";
    }
}

इसे लिखने के बाद, मुझे एहसास हुआ कि सांख्यिकीय विश्लेषण के आधार पर प्रविष्टियों के कारण, अधिकांश पक्षों को कम स्विच करने का कारण होगा क्योंकि अधिक राउंड पूरा हो चुका है। इसलिए, आलसी टर्नकोट।

आलसी टर्नकोट

आलसी टर्नकोट टर्नकोट की तरह शुरू होता है, लेकिन जैसे-जैसे दौर बीतता है, वह दूसरी तरफ जाने के लिए आलसी और आलसी हो जाता है।

package Humans;

public class LazyTurncoat extends Human {
    public final String takeSides(String history) {
        int round = history.length() == 0 ? 0 : history.split(",").length;
        int momentum = 2 + ((round / 100) * 6);
        int choice = round % momentum;
        int between = momentum / 2;

        return choice < between ? "good" : "evil";
    }
}

2
आलसी टर्नकोट महान है!
एंजेलो फुच्स

अगर आपको कोई आपत्ति नहीं है तो मैं भी इसमें शामिल हूं।
रेनबोल्ट

आगे बढ़ें। मैं यह देखने के लिए उत्सुक हूं कि दोनों कैसे करेंगे, विशेष रूप से बनाम जो मतदान के आंकड़े संकलित करते हैं।
जाबेज

@Rainbolt मैंने टर्नकोट के साथ एक बेवकूफ बग देखा। हालांकि इसे सही करने की कोई जरूरत नहीं है। यह अभी भी काम करता है, बस पूरी तरह से इरादा नहीं है, और यहां तक ​​कि अगर इसे ठीक करने में बहुत देर नहीं हुई है, तो इसे ठीक करने से यह ठीक वैसे ही होगा जैसे कि नई प्रविष्टियों में से एक जैसा। यदि आप चाहते हैं तो शामिल / बहिष्कृत करने के लिए स्वतंत्र महसूस करें।
जेजेब

8

जीवनीकार, रूबी

rounds = ARGV[0].split(',') rescue []

if rounds.length < 10
  choice = 1
else
  outcome_history = ['x',*rounds.map{|r|['0','1'].max_by{|s|r.count s}.tr('01','ab')}]
  player_histories = rounds.map{|r|r.chars.to_a}.transpose.map{ |hist| outcome_history.zip(hist).join }
  predictions = player_histories.map do |history|
    (10).downto(0) do |i|
      i*=2
      lookbehind = history[-i,i]
      @identical_previous_behavior = history.scan(/(?<=#{lookbehind})[10]/)
      break if @identical_previous_behavior.any?
    end
    if @identical_previous_behavior.any?
      (@identical_previous_behavior.count('1')+1).fdiv(@identical_previous_behavior.size+2)
    else
      0.5
    end
  end
  simulations = (1..1000).map do
    votes = predictions.map{ |chance| rand < chance ? 1 : 0 }
    [0,1].max_by { |i| votes.count(i) }
  end
  choice = case simulations.count(1)/10
    when 0..15
      1
    when 16..50
      0
    when 51..84
      1
    when 85..100
      0
  end
end

puts %w[evil good][choice]

लगभग एक बुद्धिमान प्रविष्टि पर मेरा प्रयास (वास्तव में बुद्धिमान व्यक्ति को क्षेत्र के खिलाफ परीक्षण की आवश्यकता होगी)। रूबी में लिखा है, इसलिए एक मौका है यह बहुत धीमा होगा, लेकिन मेरी मशीन पर वैसे भी .11 सेकंड अंतिम राउंड की गणना करने के लिए होता है जब 40 यादृच्छिक खिलाड़ी होते हैं, इसलिए मुझे आशा है कि यह काफी अच्छा काम करेगा।

के रूप में सहेजें biographer.rb, भागोruby biographer.rb

विचार यह है कि प्रत्येक खिलाड़ी के लिए, यह पिछले दस राउंड और समग्र परिणामों के लिए अपनी-अपनी पसंद को देखते हुए, "अच्छा" चुनने की उनकी संभावनाओं का अनुमान लगाता है, और अतीत में ऐसे उदाहरणों को खोजता है जहां समान परिस्थितियों (उनके वोट + कुल मिलाकर) परिणाम) हुए। यह सबसे लंबे समय तक दिखने वाली लंबाई को 10 राउंड तक बढ़ाता है, जैसे कि कोई मिसाल है, और इसका उपयोग करता है एक आवृत्ति बनाने के लिए (लाप्लास के उत्तराधिकार के नियम के अनुसार समायोजित किया जाता है, ताकि हम किसी के बारे में 100% आश्वस्त न हों)।

यह तब कुछ सिमुलेशन चलाता है और देखता है कि कितनी बार गुड जीतता है। यदि सिमुलेशन ज्यादातर एक ही तरह से निकला, तो यह संभवतः सामान्य रूप से अच्छी तरह से भविष्यवाणी करने वाला है इसलिए यह अनुमानित अल्पसंख्यक को चुनता है। यदि यह आश्वस्त नहीं है, तो यह पूर्वानुमानित बहुमत को चुनता है।


8

यहूदा

जूडस वास्तव में एक अच्छा इंसान है। यह एक दया है कि वह कुछ पैसे के लिए अच्छे लोगों को धोखा देगा।

package Humans;

public class Judas extends Human {

    private static final String MONEY = ".*?0100110101101111011011100110010101111001.*?";

    public String takeSides(String history) {
       return history != null && history.replace(",","").matches(MONEY) ? "evil" : "good";
    }
}

1
यह केवल कभी-कभी बुराई को वोट करता है यदि पर्याप्त प्रतिभागी हैं, तो आप इसे ,बाहर निकालना चाह सकते हैं history, और भी अधिक क्योंकि रशर समूहों में खेल को विभाजित करने वाला है।
एंजेलो फुच्स

मुझे नहीं पता था कि वह खेल को समूहों में विभाजित करने जा रहा था। मैं वास्तव में इस सवाल का इंतजार कर रहा था कि स्ट्रिंग के आकार के कारण मेरे उत्तर को पोस्ट करने से पहले पर्याप्त प्रस्तुतियाँ हों। मुझे बताने के लिए धन्यवाद।
विलियम बारबोसा

यदि आप जानते हैं कि विंडोज में एक प्रक्रिया के लिए 60000 चरित्र तर्क कैसे पारित किया जाए, तो मुझे बताएं। अन्यथा, अपनी प्रविष्टि को गड़बड़ाने के लिए खेद है, और इसे ठीक करने के लिए धन्यवाद! मुझे इतनी सारी प्रस्तुतियाँ प्राप्त होने का अनुमान नहीं था।
रेनबोल्ट

7

द फॉलिबल गैम्बलर (पायथन)

यदि एक पक्ष ने लगातार कई बार बहुमत जीता है, तो जुआरी को पता चलता है कि दूसरे पक्ष के अगले दौर (दाएं?) के बहुमत होने की संभावना है और यह उसके वोट को प्रभावित करता है। वह अल्पसंख्यक के लिए लक्ष्य बनाता है, क्योंकि यदि वह एक बार अल्पसंख्यक बन जाता है, तो वह इसे कई बार (सही?) बना सकता है और बहुत सारे अंक प्राप्त कर सकता है।

import sys
import random

def whoWon(round):
    return "good" if round.count("1") > round.count("0") else "evil"

if len(sys.argv) == 1:
    print random.choice(["good", "evil"])
else:
    history = sys.argv[1]
    rounds = history.split(",")
    lastWin = whoWon(rounds[-1])
    streakLength = 1
    while streakLength < len(rounds) and whoWon(rounds[-streakLength]) == lastWin:
        streakLength += 1
    lastLoss = ["good", "evil"]
    lastLoss.remove(lastWin)
    lastLoss = lastLoss[0] 
    print lastWin if random.randint(0, streakLength) > 1 else lastLoss  

प्रयोग

पहले दौर के लिए:

python gambler.py

और बाद में:

python gambler.py 101,100,001 etc.

4
मुझे पसंद है कि आप अपने कोड के बारे में कैसे सुनिश्चित करते हैं, है ना? : पी
IEatBagels

7

सेलुलर ऑटोमेटन

यह पक्ष लेने के लिए कॉनवे के गेम ऑफ लाइफ के लिए पारंपरिक नियमों का उपयोग करता है। सबसे पहले, पिछले वोटों से एक 2D ग्रिड बनाया जाता है। फिर, "दुनिया" को एक चरण में आगे बढ़ाया जाता है, और शेष जीवित कोशिकाओं की कुल संख्या की गणना की जाती है। यदि यह संख्या कुल कोशिकाओं की संख्या के आधे से अधिक है, तो "अच्छा" चुना जाता है। अन्यथा, "बुराई" चुना जाता है।

कृपया किसी भी गलती को माफ़ करें, यह मेरे दोपहर के भोजन के समय तोड़ दिया गया था। ;)

package Humans;

public class CellularAutomaton extends Human {

    private static final String GOOD_TEXT = "good";

    private static final String EVIL_TEXT = "evil";

    private int numRows;

    private int numColumns;

    private int[][] world;

    @Override
    public String takeSides(String history) {
        String side = GOOD_TEXT;

        if (history.isEmpty()) {
            side = Math.random() <= 0.5 ? GOOD_TEXT : EVIL_TEXT;
        }

        else {
            String[] prevVotes = history.split(",");

            numRows = prevVotes.length;

            numColumns = prevVotes[0].length();

            world = new int[numRows][numColumns];

            for (int i = 0; i < numColumns; i++) {
                for (int j = 0; j < numRows; j++) {
                    world[j][i] =
                        Integer.parseInt(Character.toString(prevVotes[j].charAt(i)));
                }
            }

            int totalAlive = 0;
            int total = numRows * numColumns;
            for (int i = 0; i < numColumns; i++) {
                for (int j = 0; j < numRows; j++) {
                    totalAlive += getAlive(world, i, j);
                }
            }
            if (totalAlive < total / 2) {
                side = EVIL_TEXT;
            }
        }

        return side;
    }

    private int getAlive(int[][] world, int i, int j) {
        int livingNeighbors = 0;

        if (i - 1 >= 0) {
            if (j - 1 >= 0) {
                livingNeighbors += world[j - 1][i - 1];
            }
            livingNeighbors += world[j][i - 1];
            if (j + 1 < numRows) {
                livingNeighbors += world[j + 1][i - 1];
            }
        }
        if (j - 1 >= 0) {
            livingNeighbors += world[j - 1][i];
        }
        if (j + 1 < numRows) {
            livingNeighbors += world[j + 1][i];
        }
        if (i + 1 < numColumns) {
            if (j - 1 >= 0) {
                livingNeighbors += world[j - 1][i + 1];
            }
            livingNeighbors += world[j][i + 1];
            if (j + 1 < numRows) {
                livingNeighbors += world[j + 1][i + 1];
            }
        }

        return livingNeighbors > 1 && livingNeighbors < 4 ? 1 : 0;
    }
}

1
मैंने परीक्षण के लिए कोड से प्रिंट लाइन को हटा दिया .. जावा प्रविष्टियों को केवल अच्छा या बुरा वापस करने की आवश्यकता है, इसे प्रिंट नहीं करना।
रेनबोल्ड

7

द रिज प्रोफेसर

मुझे आशा है कि पुस्तकालयों का उपयोग करने की अनुमति है, ऐसा करने के बिना महसूस न करें =)

मूल विचार प्रत्येक दौर के प्रत्येक प्रतिभागी के लिए रिज रिग्रेशन क्लासिफायर को प्रशिक्षित करना है, प्रत्येक राउंड से पहले के फीचर्स के रूप में 30 परिणामों का उपयोग करना। मूल रूप से प्रत्येक खिलाड़ी के परिणाम के बारे में भविष्यवाणी करने के लिए सभी खिलाड़ियों के लिए परिणामों के अंतिम दौर में शामिल थे, लेकिन जब प्रतिभागियों की संख्या बड़ी हो जाती है, तो इसे समय के करीब बंद कर दिया जाता था (जैसे, 50 या तो)।

#include <iostream>
#include <string>
#include <algorithm>
#include "Eigen/Dense"

using Eigen::MatrixXf;
using Eigen::VectorXf;
using Eigen::IOFormat;
using std::max;

void regress(MatrixXf &feats, VectorXf &classes, VectorXf &out, float alpha = 1) {
    MatrixXf featstrans = feats.transpose();
    MatrixXf AtA = featstrans * feats;

    out = (AtA + (MatrixXf::Identity(feats.cols(), feats.cols()) * alpha)).inverse() * featstrans * classes;
}

float classify(VectorXf &weights, VectorXf &feats) {
    return weights.transpose() * feats;
}

size_t predict(MatrixXf &train_data, VectorXf &labels, VectorXf &testitem) {
    VectorXf weights;
    regress(train_data, labels, weights);
    return (classify(weights, testitem) > 0 ? 1 : 0);
}

static const int N = 30;
static const int M = 10;
// use up to N previous rounds worth of data to predict next round
// train on all previous rounds available
size_t predict(MatrixXf &data, size_t prev_iters, size_t n_participants) {
    MatrixXf newdata(data.rows(), data.cols() + max(N, M));
    newdata << MatrixXf::Zero(data.rows(), max(N, M)), data;

    size_t n_samples = std::min(500ul, prev_iters);
    if (n_samples > (8 * max(N, M))) {
        n_samples -= max(N,M);
    }
    size_t oldest_sample = prev_iters - n_samples;
    MatrixXf train_data(n_samples, N + M + 1);
    VectorXf testitem(N + M + 1);
    VectorXf labels(n_samples);
    VectorXf averages = newdata.colwise().mean();
    size_t n_expected_good = 0;
    for (size_t i = 0; i < n_participants; ++i) {
        for (size_t iter = oldest_sample; iter < prev_iters; ++iter) {
            train_data.row(iter - oldest_sample) << newdata.row(i).segment<N>(iter + max(N, M) - N)
                                  , averages.segment<M>(iter + max(N, M) - M).transpose()
                                  , 1; 
        }
        testitem.transpose() << newdata.row(i).segment<N>(prev_iters + max(N, M) - N)
                  , averages.segment<M>(prev_iters + max(N, M) - M).transpose()
                  , 1;
        labels = data.row(i).segment(oldest_sample, n_samples);
        n_expected_good += predict(train_data, labels, testitem);
    }
    return n_expected_good;
}


void fill(MatrixXf &data, std::string &params) {
    size_t pos = 0, end = params.size();
    size_t i = 0, j = 0;
    while (pos < end) {
        switch (params[pos]) {
            case ',':
                i = 0;
                ++j;
                break;
            case '1':
                data(i,j) = 1;
                ++i;
                break;
            case '0':
                data(i,j) = -1;
                ++i;
                break;
            default:
                std::cerr << "Error in input string, unexpected " << params[pos] << " found." << std::endl;
                std::exit(1);
                break;
        }
        ++pos;
    }
}

int main(int argc, char **argv) {
    using namespace std;

    if (argc == 1) {
        cout << "evil" << endl;
        std::exit(0);
    }

    string params(argv[1]);
    size_t n_prev_iters = count(params.begin(), params.end(), ',') + 1;
    size_t n_participants = find(params.begin(), params.end(), ',') - params.begin();

    MatrixXf data(n_participants, n_prev_iters);
    fill(data, params);

    size_t n_expected_good = predict(data, n_prev_iters, n_participants);

    if (n_expected_good > n_participants/2) {
        cout << "evil" << endl;
    } else {
        cout << "good" << endl;
    }
}

संकलन करना

नामक फ़ाइल में स्रोत कोड को सहेजें ridge_professor.cc, Eigen लाइब्रेरी को डाउनलोड करें और स्रोत फ़ाइल के समान फ़ोल्डर में पाए गए Eigen फ़ोल्डर को अनज़िप करें। के साथ संकलित करें g++ -I. -O3 -ffast-math -o ridge_professor ridge_professor.cc

चलाने के लिए

आवश्यकतानुसार r रिज_प्रोसेसर.exe और आपूर्ति तर्क को कॉल करें।

सवाल

चूंकि मैं अभी तक कहीं भी टिप्पणी नहीं कर सकता, मैं यहां पूछूंगा: क्या खिड़कियों पर तर्क आकार की सीमा पूरी तरह से कुछ सौ मोड़ पर परिणामी बायनेरिज़ को कॉल करना असंभव है? मुझे लगा कि आपके पास तर्क में ~ 9000 से अधिक अक्षर नहीं हो सकते ...


इस ओर मेरा ध्यान आकर्षित करने के लिए धन्यवाद । यदि यह जावा में पहले से ही ठीक काम नहीं करता है, तो मैं इसे काम करने के लिए कुछ तरीके बताऊंगा। यदि जावा ऐसा नहीं कर सकता है, तो शोध मुझे बताता है कि C ++ कर सकता है, और मैं C ++ को फिर से जारी करने का अवसर लूंगा। मैं परीक्षा परिणाम के साथ शीघ्र ही वापस आऊंगा।
रेनबोल्ट 19

जैसा कि यह पता चला है, जावा कमांड प्रॉम्प्ट की सीमाओं के अधीन नहीं है। ऐसा प्रतीत होता है कि केवल 32k से बड़ा कमांड समस्या का कारण बनता है। यहाँ मेरा प्रमाण है (मैंने इसे स्वयं लिखा है): docs.google.com/document/d/… । फिर से, मैं वास्तव में कल से शुरू होने से पहले इसे लाने की सराहना करता हूं।
रेनबोल्ट

@Rusher पहले से ही 57 बॉट हैं और आप प्रत्येक राउंड पर 1000 राउंड से बना रहे हैं। यह आपके स्ट्रिंग को 57k अक्षर (इसलिए> 32k) बना देगा, है ना?
प्लेनैपस जूल

1
@Rusher मुझे लगता है कि समय को एक और सप्ताह तक बढ़ाना बेहतर हो सकता है और प्रतिभागियों से तर्क स्ट्रिंग का उपयोग करने के बजाय स्टडिन पढ़ने के लिए अपने कार्यक्रमों को बदलने के लिए कहें। अधिकांश कार्यक्रमों को बदलने के लिए तुच्छ होगा
9

@ डीजीएल चुनौती के लिए समय बहुत लंबा है, लेकिन मैं नियमों को इस तरह से बदलना नहीं चाहता कि हर किसी को अपना जवाब फिर से लिखना पड़े। मुझे पूरा यकीन है कि मैंने कल रात जो नियम जोड़ा है, वह केवल एक सबमिशन पर पेंच होगा, और मैं उस व्यक्ति की मदद करने की योजना बनाता हूं यदि वह कभी भी अपने कार्यक्रम को उस बिंदु पर ले जाता है जहां वह संकलित करता है।
रेनबोल्ट

6

क्राउले

क्योंकि इस साथी के बिना विंचेस्टर बहुत कम दिलचस्प हैं। वह स्पष्ट रूप से बुराई का पक्ष लेता है ... जब तक कि बड़े बुराई की देखभाल करने की आवश्यकता न हो।

package Humans;

public class Crowley extends Human {
public String takeSides(String history) {
    int gd = 0, j=history.length(), comma=0, c=0, z=0;
    while(comma < 2 && j>0)   {
        j--;
        z++;
        if (history.charAt(j) == ',') {
            comma++;
            if(c> z/2) {gd++;}
            z=0;
            c=0;
        } else if (history.charAt(j)=='1') {
            c++;
        } else {
        }
    }
    if(gd == 0){
        return "good";
    } else {
        return "evil";
    }
}}

मैं पिछले दो मोड़ (0 कॉमा अब तक और 1 कॉमा अब तक) को देखता हूं और अगर दोनों ने बुराई को जीतने दिया, तो मैं अच्छा वोट देता हूं। नहीं तो मैं बुराई करता हूं।


क्या मुझे यह अधिकार प्राप्त है? आप अंतिम मोड़ को देखते हैं और यदि 50% से कम "अच्छे" वोट हैं तो आप "अच्छा" के साथ बुराई करते हैं? (जिज्ञासा से बाहर: क्या आप क्रिप्टिक वैरिएबल नामों को पसंद करते हैं या यह एक दुर्घटना है?)
एंजेलो फुच्स

1
@AngeloNeuschitzer मैं पिछले दो मोड़ (अब तक 0 अल्पविराम और अब तक 1 अल्पविराम) को देखता हूं और अगर वे दोनों बुराई को जीतने देते हैं, तो मैं अच्छा वोट देता हूं। नहीं तो मैं बुराई करता हूं। मैं चर नामों को पसंद करता हूं जो टाइप करने के लिए कम हैं यदि कोड काफी कम है तो कोड का उद्देश्य भ्रमित नहीं होगा। मैं एक पेशेवर प्रोग्रामर नहीं हूं और यह पहली बार है जब मैंने जावा में प्रोग्राम किया है या किसी और ने 6.5 वर्षों में कोड देखा है। मैंने अपनी स्मृति को ताज़ा करने के लिए यह लिखा था। (TLDR वे मेरे लिए गुप्त नहीं हैं और मैं केवल एक ही हूं जिसके लिए मैं आमतौर पर कोड करता हूं।)
kail

स्पष्टता के लिए ... क्रॉले एक मानव के रूप में शुरू हुआ था इसलिए यह जानबूझकर शुरू किया गया था कि वह अच्छा है ... क्या उसे सभी दौरों के लिए अच्छे रहने की उम्मीद नहीं थी ... लानत है
19:14
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.