Kötülüğe karşı İyi


112

Sonuçlar - 19 Temmuz 2014

Tepenin şimdiki kralı, kullanıcı Fabigler tarafından Mercenary ! Giriş yapmaya devam et ve tahtından at!

Scoreboard görüntülemek için buraya tıklayın.

19 Temmuz 2014 tarihinde veya daha önce sunulan programlar dahil edildi. Diğer tüm başvurular gelecekteki çalışmalara dahil edilecektir. Yeni sonuçlar 9 Ağustos’ta yayınlanmalı, bu yüzden size bolca zaman kazandırın.


Kardeş tarafından çizilen illüstrasyon Kardeşim ve Savannah Sanat ve Tasarım Koleji'nden yeni mezun olan Chris Rainbolt tarafından resimli

Giriş

Melekler ve şeytanlar savaşıyor ve her zamanki gibi dünyayı savaş alanı olarak kullanıyorlar. İnsanlar ortasında sıkışıp kalıyor ve taraf tutmaya zorlanıyorlar. Bilinmeyen bir nötr güç, kaybedilen taraf için sürekli mücadele edenleri ödüllendirir.

Oyun

Her bir deneme, sözde çift eşleştirilecek ve daha sonra 20 ila 30 başvuru ile karıştırılacak. Her deneme 1000 turdan oluşacak. Her turda bir girdi geçecek ve çıktı üretmesi bekleniyor. Çıktınız kaydedilecek ve puanlanacak. Bu işlem 1000 kez tekrarlanacaktır.

Giriş

Her oyuncunun geçmiş oylarını temsil eden tek bir argüman alacaksınız. Yuvarlar virgül ile sınırlandırılmıştır. A 0, bu turda Evil ile birlikte oynayan bir oyuncuyu temsil eder. A 1, Good ile yüz yüze olan bir oyuncuyu temsil eder. Bir denemede, oyuncular her zaman aynı sırada olacaklar. Kendi oyunuz dahil edilecek, ancak açıkça tanımlanmayacak. Örneğin:

101100100

Bu örnekte, üç tur tamamlandı ve üç oyuncu yarışıyor. Oyuncu bir her zaman iyi ile taraflı. İkinci oyuncu her zaman Evil ile taraflı. Üçüncü oyuncu, 1. turdaki İyi'den 2. ve 3. turlarda Evil'e geçti.

Çıktı

Java Gönderimleri

  • goodGood ile yan yana gelmek istiyorsanız dizeyi döndürün.
  • evilEvil ile yan taraf olmak istiyorsan ipi geri getir.

Java Olmayan Gönderiler

  • goodGood ile yan olmak istiyorsanız dizeyi stdout'a çıktılayın.
  • evilEvil ile yan taraf olmak istiyorsanız dizeyi stdout'a çıkarın.

Programınız başka bir şey çıkarır veya verirse, bir istisna atar, derlemez veya bir makineden herhangi bir şey çıkarması bir saniyeden uzun sürerse , diskalifiye edilir.

puanlama

Tüm mevcut girişleri derleyebildiğimde, kolay görüntüleme için puanlar bir Google docs e-tabloda yayınlanacak. Endişelenmeyin - siz çocuklar program göndermeye devam ettiği sürece denemeler yapmaya devam edeceğim!

  • Bir tur sırasında çoğunluğu siding için 3 puan alırsınız.
  • Bir tur boyunca azınlık ile siding yapmak için n - 1 puan alırsınız; buradaki n, azınlık ile arka arkaya sürdüğünüz ardışık zaman sayısıdır.

Puanınız 5 denemenin ortancası olacaktır. Her deneme 1000 turdan oluşmaktadır.

Teslimat

Java Olmayan Gönderiler

Programınızı çalıştıracak benzersiz bir başlık, program ve Windows komut satırı dizesi göndermelisiniz. Bir dizgeye bir argüman eklenebileceğini unutmayın. Örneğin:

  • python Angel.py
    • Bunun argüman olmadığını unutmayın. Bu bir yuvarlak! Bunun için hazırlıklı olun.
  • python Angel.py 11011,00101,11101,11111,00001,11001,11001

Java Gönderimleri

Özgün bir başlık ve aşağıda yazılı soyut İnsan sınıfını genişleten bir Java sınıfı göndermelisiniz.

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

Test yapmak

Kendi gönderme test etmek istiyorsanız, talimatları takip buraya .

ek Notlar

İstediğiniz sayıda farklı gönderi gönderebilirsiniz. Gizli gözüken gönderimler diskalifiye edilecektir. Bu mücadelenin yazarı, bu konuda tek yargıç olacak.

Programınızın veya Java sınıfınızın yeni bir örneği, her çağrıldığında oluşturulur. Bilgileri bir dosyaya yazarak devam ettirebilirsiniz. Kendi sınıfınız dışındaki hiçbir şeyin yapısını veya davranışını değiştiremezsiniz.

Deneme başlamadan önce oyuncular karıştırılacaktır. İblis ve Melek her duruşmaya katılacak. Eğer oyuncu sayısı eşitse, Petyr Baelish de katılacak. Şeytan, Kötülük için savaşır, İyilik için Melek ve Petyr Baelish, sahte ve sahte bir taraf seçer.


2
Yorumlar, eski oldukları ve OP'nin talebi üzerine tasfiye edildi. Lütfen silinmemiş olması gereken yorumları bana bildirin.
Doorknob

7
Woah, OP kullanıcı adını değiştirdi. Tamam, sonuç ne zaman gösterilecek?
justhalf

6
@Rainbolt Bu zorlu işin acayip bir işi olmalı! Bu dikkatin nedeni, basit ve çalışan girişlere izin verirken, onu erişilebilir kılan protokol ve kuralların basitliğidir . TL; DR: Mücadeleniz çok iyi! : D
54'te tomsmeding

3
@dgel Ham verileri, üst, alt, ortalamalar ve belki bir çizgi grafik göndereceğim, böylece rekabetin sürüklediğini kimin daha iyi yaptığını görebiliriz.
Rainbolt

6
Bölmelerden biri, her seferinde aynı şekilde oy veren 10 girişle sonuçlandı. Sonuç olarak, iki kullanıcı yaklaşık 450.000 civarında mükemmel veya "bir tur kusursuz kısa" skoruyla sonuçlandı. Aynı girişimler diğer denemelerde 1900 civarında puan aldı. Ortalama puan 2000'e yakındır. Sonuçlardaki aşırı dengesizlik nedeniyle, daha anlamlı bir sayının ortanca olduğuna karar verdim. Mücadeleyi 5 denemeden sonra kazanan en yüksek ortancaya sahip olacak şekilde değiştirdim. Biri ortalamadan medyanlığa geçmenin haksız veya başka türlü kötü bir seçim olduğunu düşünüyorsa, lütfen yorum yapın.
Rainbolt

Yanıtlar:


11

Paralı asker

Her zaman en son parayı en çok ödeyenle yan yana.

İyi insanların istatistiksel olarak daha fazla kazandıklarını dikkate alarak.

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
Bu parayla ilgili bir şey söyleyen ikinci yazı . Referans veya başka bir şey eksik mi?
Rainbolt

Doğru, ama bu adam daha da kötü bir piç. Her dönüşte arkadaşlarını terk etmek, sadece para uğruna.
fabigler

Switch ifadenizde varsayılan durum için bir return ifadesi eksikti ve derlenmemesine neden oldu. Rastgele bir tane ekledim.
Rainbolt,

4
Tebrikler, Tepenin Kralı! Bu girişin nasıl kazandığını anlamıyorum. Bir açıklama eklemek ister misiniz, şimdi ona bağlı 300 itibar ödülü olduğu için?
Rainbolt

4
Muhtemelen bir hata, ya da yorum ve açıklama yanlış anladım, ancak Mercenary aslında yapması gerekeni yapmaz. İlk rastgele raunt haricinde, önceki rauntta 1/6 kişi kötülük için oy kullanmadıkça her zaman kötülükle karşı karşıya kalacaktır.
jaybz

39

Yenilikçi, Yakut

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

Sadece son turun azınlığı ile devam ediyor, çünkü her şey ana akım.

Gibi koş

ruby hipster.rb

30

Petyr Baelish

Petyr Baelish’in kimin tarafında olduğunu asla bilemezsin.

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";
    }
}

Bu giriş yalnızca oyuncu sayısı eşit olduğunda dahil edilecektir. Bu, daima çoğunluğun olacağını garanti eder.


28
Belli ki Petyr Baelish’in tarafında.
Cthulhu

2
@Kevin Sürekli botların çoğunu yener. Genellikle 27ish atar.
cjfaure

3
@Kevin Bu girdi mücadelenin yazarı tarafından gönderildi. İyi yapmak istemedi. Her zaman çoğunluğun olacağından emin olmak için var olur, çünkü eşit sayıda oyuncu ile beraberlik olabilir.
Rainbolt

4
Neden aman Tanrım, neden bu en çok oyu aldı? Bu adil değil .
14'te

3
@tomsmeding Hayır. Game of Thrones lol'den bir alıntı.
Rainbolt

29

C ++, Meta Bilimci

Bu, temel olarak The Scientist ile aynı şeyi yapar, ancak bir bütün olarak mermilerde değil, bireysel oyuncularda işlem yapar. Her oyuncuya bir dalgayı (veya sürekli bir işlevi) ayrı ayrı eşlemeye çalışır ve bir sonraki turdaki hamlelerini tahmin eder. Sonuçlanan yuvarlak tahminden Meta Bilimci hangi tarafın çoğunluğa sahip olduğunu düşünür.

#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;
}

Hata ayıklama ifadelerini açmak istiyorsanız, satır okumasını olarak #if 0değiştirin #if 1.

İle derleyin g++ -O3 -std=c++0x -o MetaScientist MetaScientist.cpp(uyarılara ihtiyacınız yoktur, yani hayır -Wall) ve birlikte koşun MetaScientist.exe(muhtemelen dersin argümanı dahil). Gerçekten güzel sorarsanız, size bir Windows çalıştırılabilir sağlayabilir.

EDIT: Görünüşe göre, önceki sürüm oyunda 600 tur civarında zaman tükendi. Bu yapmamalıydı. Zaman tüketimi #define WINDOW (...)hat tarafından kontrol edilir , daha yavaştır ancak daha geriye bakar.


2
Ben alçakgönüllü kaybeden taraf seçmeyi denemenizi öneririm. Sürekli olarak doğru bir şekilde tahmin edebiliyorsanız, tur başına 3 puandan fazlasını alırsınız.
Kevin,

1
@Kevin Doğru, ancak yanlış tarafın oldukça hızlı bir şekilde tahmin edilebileceğini ve her zaman çoğunluğu doğru yapma konusunda bir iyileşme elde etmek için kaybedilen tarafı arka arkaya yedi defadan fazla doğru tahmin etmeniz gerektiğini düşündüm. Yine de değiştirebilirim.
14'te,

1
@Kevin Ayrıca, ilk olarak Rusher bize bu hafta sonu bir puan tahtası aldığında, OP'ye yaptığı açıklamalarda belirtildiği gibi (Scientist ve Meta Scientist) nasıl yaptıklarını görmek isterdim. Rusher, üzgünüm, ama kendimi her şeyi derlemek için çok tembelim ... :)
20'de tomsmeding

3
Telaşa gerek yok! Bunları çalıştırmak muhtemelen güvenli değildir. Makinemi İnternetten 50 yabancı tarafından yazılan kodla bozmama izin ver.
Yağmurluk

1
@Kevin Ama bu çok KADAR ! Gerçekten yapabilirim ama hoşuma gitmiyor. Bu ücretlerin nasıl olduğunu göreceğim.
14'te

26

melek

Hepsinin en saf oyuncusu.

program

print "good"

komuta

python Angel.py

22
Python iyi bir dildir. Meleklerin onu kullanması doğal görünüyor.
jpmc26

23
İnsanlara bir Python'un bir Yılan olduğunu hatırlatabilir miyim. Bir yılan.
Bay Lister,

3
@ MrLister Size Lucifer'in Tanrı onu cennetten atmadan önce büyük bir Melek olduğunu hatırlatabilir miyim?
Zibbobz

1
@Zibbobz Evet ... gerçekten utanç, düştükleri için. Birlikte çok şey başarabilirlerdi.
Bay Lister,

24

Artemis Fowl

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";
           }
        }
    }
}

Kitap 7, Atlantis Kompleksi , Artemis Fowl , onu 5'in katları (konuşma, eylemler, vb.) İle her şeyi yapmaya zorlayan psikolojik bir hastalıkla (Atlantis kompleksi olarak adlandırıldı) sözleşme yaptı. Beşin birkaçında yapamadığı zaman panikledi. Temelde şunu yapıyorum: iyi veya kötünün (kasıtlı önyargı) 5'e bölünebilir olup olmadığına bakın, ikisi de değilse, o zaman panikleyin ve hangisinin daha büyük olduğunu ve bununla daha iyi çalışacağını ya da panik yapıp rastgele seçtiğini görüyorum.


4
Ortaokul’daki Artemis Fowl’i okuduğumda sadece iki kitap vardı. Şimdi yedi tane olduğunu ve Disney'in bir filme dönüştüğünü görmek güzel.
Rainbolt

1
Aslında 8 kitap var.
Kyle Kanos,


1
Ve unuttuğun break;Gözlerinde farklı switch.
johnchen902

1
@ johnchen902, @ Manu: Java'da çok deneyimli değilim (Fortran90 + kullanıyorum ve burada java'yı görüyorum), bu yüzden hatalarım var. Bir saat içinde ofise girdiğimde onları tamir edeceğim.
Kyle Kanos,

19

Disparnumerophobic

Tek sayılar çok korkutucu.

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
Yorum beni güldürdü / horladı.
phyrfox

17

Linus, Yakut

Her zaman kalıbı kırarak analistleri şaşırtmaya çalışır .

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

Farklı kaydet linus.rbve çalıştırruby linus.rb


16

Sırt Çantası

Eşleşen azınlığı en çok seçen ve son oyunu seçen bir oyuncu belirler.

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;
    }
}

Kalabalık Takipçisi

Eşleşen çoğunluğu en çok seçen ve son oyunu seçen bir oyuncu belirler.

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;
    }
}

Çok temiz program!
Rainbolt

Hata! Sanırım, programınızı farklı bir dilde kopyalamış olabilirim.
PyRulez

Ben kodu güncellenmiş ve iki girdinin yer aldığı biri olarak bu eklemek istiyorum @Rusher goWithMajority = trueve biri kendi false. Bu iyi mi, yoksa bunun için ikinci bir BackPacker eklemem mi gerekiyor?
Angelo Fuchs

@AngeloNeuschitzer Bu yazıyı düzenledim. Bu şekilde, her iki teslimi de eklemeyi unutmayacağım. Sana verdiğim yaratıcı olmayan ismi değiştirmeni öneririm ve istersen ikisine de bir açıklama ekleyebilirsin.
Rainbolt

1
@Rainbolt Aslında FrontPacker'ınızı daha çok seviyorum. Lol'd.
14'te

15

Falcı

Bu hala devam eden bir çalışma. Henüz test etmedim. OP'nin kurallara aykırı olduğunu düşünüyor mu, görmek istedim.

Buradaki amaç, sonucun olasılığını almak için diğer tüm katılımcıları birkaç kez uygulayarak bir sonraki turu simüle etmek ve buna göre hareket etmektir.

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();
}

}

Botunuz cevap vermeden önce her turda diğer botları çalıştırırsa, cevap 1'den daha fazla sürmez mi?
plannapus

@plannapus Bu botla ilgili varsayımı tahmin edeceğim, herkesin dikkatli olunca yanına kalacağı ve 1 saniye beklemeye değecek bir şeyden kaçınacağı yönünde. Ben sadece "onunla uğraşmak", "iyi" dönmeden önce 0.9 saniye beklemeden oluşan gönderme ve giriş değerli olabilir düşünüyorum. Aslında, SBoss beni dövdü: D
scragar

Yahhh! O zaman kodumdaki botu kara listeye almak zorunda kalacağım. Bu sinir bozucu olurdu ... Ayrıca Python veya Perl gibi farklı ortamlardaki farklı girişlerde tercümanın bildirilen yüklemesi bu kodu zaman sınırının üzerine getirmek için yeterli olabilir.
Andris

16
Başka biri de aynı şeyi yaparsa, sonsuz bir döngü elde edersiniz.
Brilliand

4
Gönderim zaman aşımına uğradı. Bir profil oluşturucuyu ekledim ve neredeyse yarım saniyelik bir süre için bazı gönderimler gönderiliyor. En azından olsa çalışır, bunun için tebrikler.
Rainbolt

15

C ++, Bilim Adamı

Bu, çoğunluğun tur başına neyi seçtiğinin wave(bir turdaki çoğunluğun seçimini majority()verir) tarihiyle birlikte dalga boyu 2*periodve faz verisine bir dalga uydurmaya çalışır phase. Böylece, 0,1,1,1,0,1,0,1,1,1,0,0,0,1,0selects period=3, phase=5( maxat=={3,5}) verildiğinde : puanları olur 9 3 11 5 5 3 5 7 9 7 7 7 7 7 7. Olası tüm periyotlar boyunca döngüler ve eğer o süre için puan mevcut olandan daha yüksekse, bunun gerçekleştiği yerde saklar {period,phase}.

Daha sonra bulunan dalgayı bir sonraki tura çıkarır ve öngörülen çoğunluğu alır.

#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;
}

İle derleyin g++ -O3 -std=c++0x -o Scientist Scientist.cpp(uyarılara ihtiyacınız yoktur, yani hayır -Wall) ve birlikte koşun Scientist.exe(muhtemelen dersin argümanı dahil). Gerçekten güzel sorarsanız, size bir Windows çalıştırılabilir sağlayabilir.

Oh, ve giriş formatını karıştırmaya cüret etme. Aksi takdirde garip şeyler yapar.

EDIT: Görünüşe göre, önceki sürüm oyunda 600 tur civarında zaman tükendi. Bu yapmamalıydı. Zaman tüketimi #define WINDOW (...)hat tarafından kontrol edilir , daha yavaştır ancak daha geriye bakar.


8
Altmış + yabancı tarafından internette yazılmış yürütülebilir dosyaları indirmek kötü bir fikir gibi görünüyor.
Rainbolt

@Rusher Kesinlikle katılıyorum. Sorun istiyorsan, bu "aptallar için" kılavuzundaki ilk adım. Teklifim yine de geçerli :)
14:14

2
Bunu derlemek (ve rekabet etmek) gayet iyi.
Rainbolt

14

Kod Çalıştırıcısı

Bu yüzden, ilginç şeyler yapmak için, gönderilen her cevaptan kodu otomatik olarak indirecek, gerektiğinde derleyeceğim ve sonra tüm çözümleri kurallara uygun olarak çalıştıracak bir komut dosyası oluşturdum. Bu şekilde insanlar nasıl olduklarını kontrol edebilir. Sadece bu betiği run_all.py dosyasına kaydedin (BeautifulSoup gerekir) ve sonra:

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

Bir kaç şey:

  1. Daha fazla dil için destek eklemek veya alternatif olarak bazılarını desteklemek istiyorsanız, bkz. def submission_type(lang) .
  2. Komut dosyasını genişletmek derleme gerektiren diller için bile oldukça kolay olmalıdır (bkz. CPPSubmission). Dil türü meta kod etiketinden alınmıştır < !-- language: lang-java -- >, bu nedenle kodunuzun çalışmasını istiyorsanız eklemeyi unutmayın (<> öncesi ve sonrası fazladan boşlukları kaldırın). GÜNCELLEME : Şimdi, eğer tanımlanmamışsa, dili denemek ve tespit etmek için bazı temel çıkarımlar var.
  3. Kodunuz hiç çalışamazsa veya belirtilen süre içinde bitiremezse, blacklist.textotomatik olarak gelecekteki denemelere eklenecek ve kaldırılacaktır. Kodunuzu düzeltirseniz, girişinizi kara listeden kaldırın ve yeniden çalıştırınget .

Şu anda desteklenen diller:

 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
}

Daha fazla uzatmadan:

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

Neden Fortran dili yok ?
Kyle kanos

@KyleKanos - Bunun için destek ekledim, kodu kısa bir süre içinde güncelleyeceğim.
WhatAWorld

Yuppi! Ben (sorta) Fortran'ın gönderiminde çok çalıştım ve Rusher işe yaramadı bu yüzden birinin çalışmasını istiyorum :)
Kyle Kanos

1
@Rusher: Bu konuda PeterTaylor ile aynı fikirdeyim: önerilen tek düzenlemenin reddedilmesi gerektiği gibi vurgulayan sözdizimi . Düzenlemeler küçük düzeltmeler için değil, önemli düzeltmeler için kullanılmalıdır .
Kyle Kanos

1
Bunun cevabını hak ediyorsun, ama bu tam olarak sorunun cevabı değil (ve muhtemelen diğer diller için bir şeyler ekleyerek topluluğun yararına olabilir) bunun teknik olarak bir topluluk wiki olması gerektiğini düşünüyorum.
Martin Ender,

13

Güzel Zihin, Yakut

Kararını, son turun bit gösteriminde sorgulanabilir öneme sahip kalıplara dayanarak verir.

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

Gibi koş

ruby beautiful-mind.rb

13

Yağışlı, Lua

İşaretler ve Harikalar'a inanan bir batıl inançlı program.

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

ile çalıştırın:

lua Piustitious.lua

ardından girdi.


11

Winchters

Sam ve Dean iyidir (çoğu zaman).

package Humans;

public class TheWinchesters extends Human {

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

}

9:1Doğru oran olduğundan emin misin ? Belki biraz veri madenciliği yapmalıyız ve daha kesin bir oran elde etmeliyiz ?
recursion.ninja

1
@awashburn 2 ay önce Supernatural'ı izlemeye başladım (şimdi sezon 9'da kalmış) ve 9:1bana uygun görünüyor;)
CommonGuy

10

İstatistikçi

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
Bu ikinci son çizgi çok harika
cjfaure

5
@Enerverveded you yerine Math.ceil(Math.random()-Math.random())sadece yapabilirsiniz Math.round(Math.random()).
08:04

10

R, biraz Bayesian botu

Her kullanıcı için sıklık tablosunu, diğer kullanıcıların çıktısının öncelikli olasılığı olarak kullanın.

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")
    }

Çağrılan kullanılarak Rscript BayesianBot.Rgiriş takip eder.

Düzenleme : Sadece bunun ne yaptığını netleştirmek için, örnek giriş ile adım adım:

> 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

Daha sonra, result<-her oyuncu için başlayan çizgi , bu son masayı ağırlık olarak kullanarak 0 veya 1'i rastgele seçer (örneğin, oyuncu 1 için 0 toplama olasılığı 1/7, vb. Toplama 2 / 7'dir). Her oyuncu / sütun için bir sonuç seçer ve en sonunda en sonunda sona eren sayıyı döndürür.


10

İsviçre

Daima tarafsızlığı sürdürür. Asla kazanamayacak mahkum.

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?
    }
}

Bunu ben yazmadım!
Rainbolt

Bu ironi. Tarafsızlık asla
kazanmaz

2
@Rusher ah şimdi anladım: D
fabigler

1
Derleme bile yok - eksik bir noktalı virgül var.
Paŭlo Ebermann

9

HAL 9000

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

Düzenleme: belki bu HAL 9000 için daha uygundur, ancak dikkatli olun! Bu çok kötü. cdÇalıştırmadan önce dizini boşaltmanızı öneririm .

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

Bu cwdher çağrı için bir dosyayı kaldırır !

Çok açık bir çağrı değil:

M $ cinsinden

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

D:>hal_9000.pl
evil

* Nix içinde

[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 ~]$

Programınızı çalıştırmak için kullanılabilecek bir komut vermeniz gerekir. Daha fazla bilgi için mücadelenin "Teslim Edilecekler" bölümüne bakın.
Rainbolt

@Rusher Done;)
core1024,

9

Çoğunluğun İradesi

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

Olarak kaydet WotM.py , farklı çalıştırpython3 WotM.py girdi izledi.

Basit bir program, sadece nasıl yapacağını görmek için. Çoğunluğun en son söylediği şeyle veya rastgele başka bir şeyle uyuşmuyor.


Programınızı çalıştırmak için kullanılabilecek bir komut vermeniz gerekir. Daha fazla bilgi için mücadelenin "Teslim Edilecekler" bölümüne bakın.
Rainbolt

Kahretsin, bu benim tekrarlamamı sağlıyor. : D Madeni azınlığa çevirdi.
Martin Ender

@Rusher Komutu eklendi. Aradığın şey bu mu?
isaacg,

@isaacg Mükemmel!
Rainbolt

1
Ortalama sıralamayı skor tablosundaki puanlardan hesapladım ve bu girdi o ölçütle kazanıyor.
Brilliand

9

Alan Shearer

Yanında oturduğu kişinin söylediklerini tekrar eder. Kişi yanlış olduğu ortaya çıkarsa, bir sonraki kişiye geçer ve söylediklerini tekrar eder.

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";
        }
    }
}

Bunu lastRoundilan etmeden önce denilen bir değişkene başvurursunuz. Ayrıca, hepsine parantez eklediniz, String.lengthancak bu bir işlev değil. Gönderinizi derleyeceği bir noktaya getirebilir misiniz?
Rainbolt

@Rusher - done :)
Algy Taylor

@Algy: lastRound.lengthhala erişilebilir (ilk önce ise) daha önce lastRoundbildirilmiş (bu durumda ise). Lütfen buraya göndermeden önce kodunuzu derlemeye (ve belki de çalıştırmaya) çalışın.
Paŭlo Ebermann

@ PaŭloEbermann - özür dilerim, çalıştırabileceğim bir ortamda değilim - değişiklik yapıldı, ancak
Algy Taylor

Şimdi kapsam dışı olduğunda "personToCopy" adlı bir değişkene başvuruyorsunuz. Ben sadece onu diğer bloğun içine taşıdım, derleyebilsin, ama istediğinin bu olup olmadığını bilmiyorum.
Rainbolt

8

Daha sonra Evil, JavaScript ( node.js )

İnfazlar arasındaki zaman miktarını ölçer. Zaman farkı, son zamandan daha büyükse, kötü olmalı. Aksi takdirde, iyi.

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');

Çalıştır: node laterisevil.js


8

Desen Bulucu, Python

Tekrarlayan bir kalıp arar ve eğer bir tane bulamazsa, sadece çoğunluğa gider.

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

koşmak

python3 pattern_finder.py

1
Bu kodu çok seviyorum, çalıştırdığımda her zaman bir şekilde 3000 puan alıyor.
Realdeo

8

Turncoat

Turncoat, şu ana kadarki diğer savaşçılar nedeniyle, çoğunluğun iyiyle kötülük arasındaki her turdan sonra aynı tarafta olduğundan daha sık değişeceğine inanıyor. Böylece ilk rauntta keyfi bir şekilde iyi siding ile başlar, daha sonra kazanan veya kaybeden takımda kalma çabasıyla her raundu değiştirmez.

package Humans;

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

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

Bunu yazdıktan sonra, istatistiksel analize dayalı girdiler nedeniyle momentumun çoğunluğun daha fazla tur tamamlandıkça daha az taraf değiştirmesine neden olacağını fark ettim. Bu nedenle, Lazy Turncoat.

Tembel Turncoat

Lazy Turncoat, Turncoat gibi başlıyor, ancak turlar geçtikçe diğer tarafa geçmek için lazier ve lazier alıyor.

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
Lazy Turncoat harika!
Angelo Fuchs

Sakıncası yoksa ikisini de dahil ediyorum.
Rainbolt,

Devam et. Her ikisinin de nasıl olacağını görmeyi merak ediyorum, özellikle oylama istatistiklerini derleyenlere karşı.
jaybz

@Rainbolt Turncoat ile ilgili aptal bir böcek fark ettim. Yine de düzeltmenize gerek yok. Hala çalışır, tamamen amaçlandığı gibi değildir ve düzeltmek için çok geç olmasa bile, düzeltilmesi tam olarak yeni girdilerden biri gibi davranmasını sağlayacaktır. İsterseniz eklemek / dışlamaktan çekinmeyin.
jaybz

8

Biyograf, Ruby

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]

Neredeyse akıllı bir girişteki girişimlerim (aslında zeki biri, sahaya karşı test gerektiriyor). Ruby'de yazılmış, bu yüzden çok yavaş olma ihtimali var, ama yine de makinemde 40 rastgele oyuncu varken son rauntu hesaplamak için 11 saniye sürüyor, bu yüzden umarım yeterince işe yarar.

olarak kaydetmek biographer.rbolarak yayınlanacağınıruby biographer.rb

Buradaki fikir, her oyuncu için, son on raunt için kendi seçimlerine ve genel sonuçlara bakarak hem de aynı koşulların (oyların + toplamın bulunduğu geçmişte örnekleri bularak "iyi" olma şanslarını tahmin ediyor olmasıdır. sonuç) ortaya çıktı. En uzun göz atma uzunluğunu, en fazla 10 mermi seçer, öyle ki herhangi bir emsal vardır ve bunu sıklık yaratmak için kullanır (Laplace'in Başarı Kanununa göre ayarlanmış, böylece hiç kimseye karşı asla% 100 güvenmiyoruz).

Daha sonra bazı simülasyonları çalıştırır ve Good'un ne sıklıkta kazandığını görür. Simülasyonlar çoğunlukla aynı şekilde ortaya çıkarsa, o zaman muhtemelen genel olarak iyi bir tahmin yapar, bu yüzden öngörülen azınlığı seçer. Kendinden emin değilse, öngörülen çoğunluğu seçer.


8

Yehuda

Yahuda gerçekten iyi bir insan. Birkaç kuruşa iyi adamlara ihanet etmesi üzücü.

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
Bu sadece, eğer yeterli sayıda katılımcı varsa kötülüğe oy ,verir history, Rusher'in oyunu gruplara ayırması için, daha da fazlasını çıkarmak isteyebilirsiniz .
Angelo Fuchs

Oyunu gruplara ayıracağını bilmiyordum. Aslında bu sorunun cevabını göndermeden önce string boyutundan dolayı yeterli başvuru yapmasını bekledim. Bilmeme izin verdiğin için teşekkürler.
William Barbosa,

60000 karakter argümanının Windows'taki bir işleme nasıl geçirileceğini biliyorsanız, bana bildirin. Aksi takdirde, girişinizi karıştırdığınız için üzgünüz ve düzeltdiğiniz için teşekkür ederiz! Çok fazla başvuru almayı beklemiyordum.
Rainbolt

7

Fallacious Gambler (Python)

Bir taraf arka arkaya birkaç kez çoğunluk kazandıysa, kumarbaz diğer tarafın gelecek turda çoğunlukta olamayacağının (sağ?) Daha fazla olduğunu fark eder ve bu oy hakkını etkiler. Azınlığı hedefliyor, çünkü azınlığa bir kez daha katılabiliyorsa (doğru mu?) Ve çok fazla puan kazanması muhtemel.

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  

kullanım

İlk tur için:

python gambler.py

ve sonra:

python gambler.py 101,100,001 etc.

4
Kodunuzdan nasıl emin göründüğünüzü seviyorum, değil mi? : P
IEatBagels

7

Hücresel Otomat

Bu, Conway'in Yaşam Oyunu için bir taraf seçmek için geleneksel kuralları kullanır. İlk önce, önceki oylardan bir 2D ızgara oluşturulur. Ardından, "dünya" bir aşamada öne çıkar ve kalan canlı hücre sayısı hesaplanır. Bu sayı, toplam hücre sayısının yarısından büyükse, "iyi" seçilir. Aksi takdirde, "kötülük" seçilir.

Lütfen herhangi bir hatayı affedin, öğle saatimde bu parçalandı. ;)

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
Test satırını test kodundan çıkardım. Java girişlerinin yalnızca iyi veya kötü geri dönmesi gerekir, yazdırmaz.
Rainbolt

7

Ridge Profesörü

İnşallah kütüphaneleri kullanmaya izin var, bunu bir olmadan yapmak istemiyorum =)

Temel fikir, her tur için her turdan önceki 30 sonucu özellik olarak kullanarak, her yarışmacı için son turda bir sırt regresyon sınıflandırıcısı yetiştirmektir. Başlangıçta, tüm oyuncuların her bir oyuncunun sonucunu tahmin etmesi için son sonuçları da içeriyordu, ancak bu katılımcıların sayısı arttıkça zaman için oldukça yakındı (örneğin, 50 ya da öylesine).

#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;
    }
}

Derlemek için

Adlı bir dosyada kaynak kodunu kaydet ridge_professor.cc, indir Eigen kütüphane ve kaynak dosyayla aynı klasöre içinde bulunan Eigen klasörü açmak. İle derleying++ -I. -O3 -ffast-math -o ridge_professor ridge_professor.cc .

Koşmak

ridge_professor.exe dosyasını arayın ve gerektiğinde argümanı girin.

Soru

Henüz hiçbir yerde yorum yapamadığım için buraya soracağım: pencerelerdeki argüman büyüklüğü sınırı, sonuçta ortaya çıkan ikili dosyaların tamamını tarihin tamamı ile birkaç yüz turda çağırmayı imkansız kılıyor mu? Tartışmada ~ 9000'den fazla karakter olamayacağınızı düşündüm ...


Benim dikkat çeken için teşekkür ederiz bu . Java'da zaten iyi çalışmıyorsa, çalışmasını sağlamanın bir yolunu bulacağım. Java bunu yapamazsa, araştırma bana C ++ 'ın yapabileceğini ve C ++' ı yeniden tanıma fırsatını bulacağımı söyledi. Test sonuçları ile kısa süre sonra döneceğim.
Rainbolt

Görünen o ki, Java komut isteminin sınırlamalarına tabi değildir. Sadece 32k'den büyük komutların bir soruna neden olduğu anlaşılıyor. İşte kanıtım (kendim yazdım): docs.google.com/document/d/… . Yarın denemeler başlamadan önce, bunu gündeme getirdiğiniz için tekrar teşekkür ederim.
Rainbolt

@Rusher Zaten 57 bot var ve her turda 1000 turdan oluşmasını planlıyorsun. Bu dize 57k karakter yapacaktır (bu nedenle> 32k), öyle değil mi?
plannapus

1
@Rusher Zaman çizelgesini başka bir haftaya kadar uzatmanın ve katılımcılardan bir argüman dizesi kullanmak yerine programlarını stdin okumalarını isteme konusunda daha iyi olabileceğini düşünüyorum. Çoğu programın değişmesi önemsizdir
dgel

@dgel Mücadelenin zaman çizelgesi sonsuz uzun, ama kuralları herkesin cevaplarını yeniden yazacak şekilde değiştirmek istemiyorum. Dün gece eklediğim kuralın sadece tek bir başvuruyu mahvedeceğinden eminim ve programını derleyeceği bir noktaya getirirse, o kişiye yardım etmeyi planlıyorum.
Rainbolt

6

Crowley

Çünkü Winchters bu adam olmadan çok daha az ilginç. Belli ki kötülükle yüzleşiyor ... daha büyük bir kötülükle ilgilenmesi gerekmediği sürece.

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";
    }
}}

Son iki dönüşe bakıyorum (şu ana kadar 0 virgül ve şu ana kadar 1 virgül) ve her ikisi de kötülüğün kazanmasına izin verirse, iyi oy kullanırım. Aksi takdirde kötülüğü oylarım.


Bunu doğru anladın mı? Son dönüşe bakıyorsunuz ve eğer% 50'den azı “iyi” oysa, kötülükle “iyi” ile karşı karşıya kalırsanız? (Merak etme: Kriptik değişken isimlerini mi tercih edersin, yoksa kaza mı?)
Angelo Fuchs

1
@AngeloNeuschitzer Son iki dönüşe baktım (şu ana kadar 0 virgül ve şu ana kadar 1 virgül) ve ikisi de kötülüğün kazanmasına izin verirse, iyi oy kullanırım. Aksi takdirde kötülüğü oylarım. Kod yeterince kısasa, kodun amacı karışmayacaksa kısa olan değişken isimleri tercih ediyorum. Profesyonel bir programcı değilim ve java ya da başka birinin kodunu 6.5 yıl içerisinde gördüğüm ilk programımdı. Bunu hafızamı tazelemek için yazdım. (TLDR bana şifreli değil ve genelde kodladığım tek kişi benim.)
kaine

Netlik için ... Crowley bir insan olarak başladı, bu yüzden iyi bir şekilde başladığı
kasıtlıydı
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.