Добре проти зла


112

Результати - 19 липня 2014 року

Нинішній король Хілл Найманець користувачем Fabigler ! Продовжуйте подавати записи і збивайте його зі свого трону!

Клацніть тут, щоб переглянути табло.

Були включені програми, подані 19 липня 2014 року або раніше. Усі інші матеріали будуть включені до майбутніх випробувань. Нові результати мають бути опубліковані близько 9 серпня, щоб ви мали багато часу.


Ілюстрація намальовані братом Ілюстрував Кріс Рейнбольт, мій брат і свіжий випускник коледжу мистецтва та дизайну Саванни

Вступ

Ангели та демони воюють і, як завжди, використовують землю як своє поле битви. Люди застрягли в середині і змушені стати на бік. Невідома нейтральна сила винагороджує тих, хто послідовно бореться за програшну сторону.

Гра

У кожному пробному періоді ви будете псевдовипадковими парними, а потім перемішати з 20 та 30 іншими поданнями. Кожна пробна версія буде складатися з 1000 патронів. Кожен раунд вам буде передано вхід і очікується, що він отримає результат. Ваш результат буде записаний та занесений. Цей процес повториться 1000 разів.

Вхідні дані

Ви отримаєте єдиний аргумент, який відображає минулі голоси кожного гравця. Круги розмежовані комою. А 0являє собою гравця, який зіграв зі Злом цього раунду. A 1являє собою гравця, який перейшов на сторону Good. Під час випробування гравці завжди будуть в одному порядку. Ваш власний голос буде включений, але не буде чітко визначений. Наприклад:

101,100,100

У цьому прикладі три раунди завершено і три гравці змагаються. Гравець завжди виступав на стороні Доброго. Гравець два завжди стояв на стороні Зла. Гравець три змінився з "Доброго" в 1 раунді на "Зло" в 2 та 3. раундах. Одним із таких гравців був ти.

Вихідні дані

Представлення Java

  • Поверніть рядок, goodякщо ви хочете встати на сторінку Good.
  • Поверніть рядок, evilякщо ви хочете озвучити Evil.

Подання, що не належить Java

  • Виведіть рядок goodу stdout, якщо ви хочете поставити сторону з Good.
  • Виведіть рядок evilв stdout, якщо ви хочете озвучити Evil.

Якщо ваша програма виводить або повертає що-небудь інше, кидає виняток, не компілює або не вимагає більше однієї секунди, щоб вивести щось на цій точній машині , тоді вона буде дискваліфікована.

Оцінка балів

Оцінки будуть розміщені в таблиці Google Документів для зручного перегляду, як тільки я можу зібрати всі поточні записи. Не хвилюйтесь - я продовжуватиму проводити випробування до тих пір, поки ви, хлопці, продовжуєте подавати програми!

  • Ви отримуєте 3 бали за сайдинг з більшістю під час раунду.
  • Ви отримуєте n - 1 бали за розміщення стороною меншини під час раунду, де n - кількість підряд, які ви перейшли на бік меншини.

Ваша оцінка буде медіаною 5 випробувань. Кожна пробна версія складається з 1000 патронів.

Продукти

Подання, що не належить Java

Ви повинні подати унікальну назву, програму та рядок командного рядка Windows, який запустить вашу програму. Пам'ятайте, що до цього рядка може бути доданий аргумент. Наприклад:

  • python Angel.py
    • Зауважте, що у цього немає аргументів. Це перший тур! Будьте готові до цього.
  • python Angel.py 11011,00101,11101,11111,00001,11001,11001

Представлення Java

Ви повинні подати унікальний заголовок і клас Java, який розширює написаний нижче абстрактний клас людини.

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

Тестування

Якщо ви хочете перевірити власне подання, дотримуйтесь інструкцій тут .

додаткові нотатки

Ви можете надіслати стільки різних матеріалів, скільки вам потрібно. Подані матеріали, які здаються змовами, будуть дискваліфіковані. Автор цього виклику буде єдиним суддею з цього питання.

Новий екземпляр вашої програми або Java-класу буде створюватися кожного разу, коли він буде викликаний. Ви можете зберігати інформацію, записавши у файл. Ви не можете змінювати структуру чи поведінку нічого, крім вашого власного класу.

Гравці будуть переміщені до початку судового розгляду. Демон та Ангел братимуть участь у кожному випробуванні. Якщо кількість гравців буде парною, також приєднається Петро Баеліш. Демон бореться за зло, Ангел за добро, а Петр Бееліш обирає псевдовипадкову сторону.


2
Зауваження чистили, оскільки вони застаріли та на вимогу ОП. Будь ласка, повідомте мене про будь-які коментарі, які потрібно відмінити.
Doorknob

7
Вуа, ОП змінює своє ім'я користувача. Гаразд, і коли буде відображатися результат?
justhalf

6
@Rainbolt Це, мабуть, одна жахлива робота, виконуючи це завдання! Причиною такої уваги є простота протоколу та правил, що робить його доступним, а також дозволяє прості, робочі записи. TL; DR: Твій виклик занадто хороший! : D
tomsmeding

3
@dgel Я опублікую необроблені дані, верхні, нижні, середні показники та, можливо, лінійну діаграму, щоб ми могли побачити, хто зробив краще, коли змагання затягувалася.
Rainbolt

6
Один із підопічних закінчився 10-ма записами, які голосували однаково кожен раз. Отже, двоє користувачів закінчилися із ідеальними або «на один круглий від ідеальних» балів у розмірі близько 450 000. Ці ж записи набрали близько 1900 року в інших випробуваннях. Середня оцінка близька до 2000 р. Через надзвичайний дисбаланс результатів я вирішив, що більш значущим числом буде медіана. Я змінив виклик так, що після 5 випробувань переможцем стане подання з найвищою медіаною. Якщо хтось вважає, що перехід від середнього значення до медіани є несправедливим або інакше поганим вибором, будь ласка, прокоментуйте його.
Rainbolt

Відповіді:


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
Це другий пост, щоб сказати щось про гроші. Я пропускаю посилання чи щось таке?
Rainbolt

Правда, але цей хлопець ще більше злий сволот. Дезертируючи друзів на кожному кроці, лише заради грошей.
fabigler

У вашому операторі перемикання відсутній оператор повернення для випадку за замовчуванням, через що він не компілюється. Я додав випадковий.
Rainbolt

4
Вітаю, Король пагорба! Я не розумію, як перемагає цей запис. Хочете додати пояснення, тепер, коли до нього додається щедрий репутація 300?
Rainbolt

4
Можливо, помилка, або я неправильно зрозумів коментарі та опис, але найманець насправді не робить того, що мав робити. За винятком першого випадкового раунду, він завжди буде зі злом, якщо менше, ніж 1/6 людей проголосували за зло в попередньому раунді.
jaybz

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
@Kevin Постійно б'є більшість ботів. Зазвичай він набирає 27 баш.
cjfaure

3
@Kevin Цей запис подав автор виклику. Це не означало робити добре. Існує, щоб впевнитись у тому, що завжди буде більшість, тому що при парній кількості гравців може бути нічия.
Rainbolt

4
Чому о Боже, чому саме цей отримав найбільше голосів? Це просто не чесно .
tomsmeding

3
@tomsmeding Ні. Це цитата з гри престолів lol.
Rainbolt

29

C ++, The Meta Scientist

Цей по суті робить те саме, що і The Scientist, але працює не в цілому, а на окремих гравців. Він намагається відобразити хвилю (або постійну функцію) для кожного гравця окремо і прогнозує їх перехід у наступний раунд. З отриманого круглого прогнозування, The Meta Scientist вибирає ту сторону, яка виглядає як більшість.

#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(можливо, включаючи аргумент звичайно). Якщо ви дуже красиво запитаєте, я можу надати вам виконуваний файл Windows.

EDIT: Мабуть, у попередній версії не вистачало часу в грі близько 600 раундів. Це не повинно робити цього. Його витрата часу контролюється #define WINDOW (...)лінією, більше повільніше, але дивиться далі назад.


2
Я смиренно пропоную спробувати вибрати програшну сторону. Якщо ви зможете правильно вгадати правильно, ви отримаєте більше 3 балів за раунд.
Кевін

1
@Kevin Це правда, але я зрозумів, що вона може досить швидко вгадати неправильну сторону, і вам потрібно правильно вгадати програшну сторону більше семи разів поспіль, щоб отримати поліпшення, ніж завжди отримувати право більшості. Я можу це змінити.
tomsmeding

1
@Kevin Також я спершу хотів би побачити, як це роблять (вчений та мета-вчений), коли Рашер отримує нам табло у ці вихідні, як він зазначив у коментарях до ОП. Rusher, вибачте, але я лінивий сам збирати всі речі ... :)
tomsmeding

3
Не хвилюйтесь! Це, мабуть, не безпечно запустити. Дозвольте мені накрутити машину з кодом, написаним 50 незнайомцями в Інтернеті.
Rainbolt

1
@Kevin Але це так БАГАТО ! Я, справді, можу, але мені це не подобається. Я побачу, як ці тарифи.
tomsmeding

26

Ангел

Найчистіший гравець з усіх.

Програма

print "good"

Командування

python Angel.py

22
Python - це гарна мова. Мабуть, природно, що Ангел повинен ним користуватися.
jpmc26

23
Чи можу я нагадати людям, що пітон - змія. Змій.
Містер Лістер

3
@MrLister Чи можу я вам нагадати, що Люцифер був великим Ангелом, перш ніж Бог викинув його з неба?
Zibbobz

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, The Atlantis Complex , Артеміс Фаул контракт психологічного захворювання ( так званий Атлантида комплексом) , який змусив його зробити все , що в упаковці 5 (говоріння, дій і т.д.). Коли він не міг зробити це в декількох кратних 5, він запанікував. Я в основному це роблю: бачте, чи добро чи зло (навмисне упередження) ділиться на 5, якщо це не так, то я панікую і бачу, що було більше і бігти з цим, або панікувати ще далі та випадково вибирати.


4
Коли я читав Артеміду Фаула в «Джуніор Хай», то існували лише дві книги. Приємно бачити, що зараз їх сім, і що Діснея робить це фільмом.
Rainbolt

1
Насправді 8 книг.
Кайл Канос

7
Тим більше веселіше (якщо ви не читаєте «Колесо часу»)
Rainbolt

1
І ти забув break;у своєму switch.
johnchen902

1
@ johnchen902, @ Manu: Я не дуже досвідчений в Java (я використовую Fortran90 + і бачу тут тільки Java), отже, мої помилки. Я їх виправлю, коли через годину потраплю в офіс.
Кайл Канос

19

Диспарнумерофобний

Непарні числа жахливі.

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

BackPacker

Визначає гравця, який найбільше обрав відповідну меншість, і обирає останній голос.

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

The CrowdFollower

Визначає гравця, який найбільше вибрав відповідну більшість, і обирає свій останній голос.

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

Дуже чиста програма!
Rainbolt

Ну, думаю, я, можливо, скопіював вашу програму іншою мовою.
PyRulez

@Rusher Я оновив код і хотів би додати це як дві записи, одна з goWithMajority = trueта одна, де її false. Це все в порядку, чи для цього мені потрібно додати другий BackPacker?
Анджело Фукс

@AngeloNeuschitzer Я редагував це повідомлення. Таким чином, я не забуду додати обидва матеріали. Я пропоную вам змінити дійсно нетворче ім’я, яке я йому дав, і, можливо, додати опис обом, якщо хочете.
Rainbolt

1
@Rainbolt Насправді мені подобається твій FrontPacker. Лолд.
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();
}

}

Якщо ваш бот запускає всі інші боти щороку, перш ніж відповісти, чи не знадобиться більше 1 секунди для відповіді?
планнапус

@plannapus Я думаю, що припущення цього бота полягає в тому, що всі інші будуть помилятися на стороні обережності і уникати нічого близького, якого варто чекати на 1 секунду. Я думаю, що, можливо, варто подати заяву та записати, що складається з 0,9 секунди очікування, перш ніж повернутись "добре", просто повозитися з ним. Насправді, SBoss побив мене до цього: D
скрагар

Ях! Тоді мені доведеться в чорний список ввести цей бот у своєму коді. Це було б засмучує ... Крім того, при різних записах у різних середовищах, таких як Python чи Perl, повторна завантаженість інтерпретатора може бути достатньою, щоб привести цей код вище часового обмеження.
Андріс

16
Якщо хтось інший робить те саме, що це, ви отримуєте нескінченну петлю.
Brilliand

4
Час подання закінчився. Я приєднав профілера, і майже півсекунди витратив на виклик деяких матеріалів. Принаймні, це працює, тому вітаю з цим.
Rainbolt

15

C ++, Вчений

Це намагається, з історією того, що більшість обрала за раунд 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(можливо, включаючи аргумент звичайно). Якщо ви дуже красиво запитаєте, я можу надати вам виконуваний файл Windows.

О, і не смій возитися з форматом введення. Інакше це зробить дивні речі.

EDIT: Мабуть, у попередній версії не вистачало часу в грі близько 600 раундів. Це не повинно робити цього. Його витрата часу контролюється #define WINDOW (...)лінією, більше повільніше, але дивиться далі назад.


8
Завантаження виконавчих файлів, написаних шістдесят + незнайомими людьми в Інтернеті, здається поганою ідеєю.
Rainbolt

@Rusher Я повністю згоден. Якщо ви хочете проблем, це перший крок у посібнику "для манекенів". Моя пропозиція стоїть, хоча :)
tomsmeding

2
Отримав цей, щоб скласти (і змагатися) штрафу.
Rainbolt

14

Code Runner

Отже, щоб зробити цікаві речі, я створив сценарій для автоматичного завантаження коду з кожної опублікованої відповіді, при необхідності компілював його, а потім запускав усі рішення відповідно до правил. Таким чином люди можуть перевірити, як у них справи. Просто збережіть цей скрипт у 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 - я додав підтримку, незабаром оновить код.
WhatAWorld

Так! Я (сорта) наполегливо працював над моїм представленням Fortran, і Рашер не можу змусити його працювати, тому я хотів би, щоб хтось отримав це :)
Kyle Kanos

1
@Rusher: Я погоджуюся з PeterTaylor щодо цього: підкреслення синтаксису як єдиного запропонованого редагування слід відхилити. Зміни слід використовувати для суттєвих виправлень , а не для незначних змін.
Кайл Канос

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це правильне співвідношення? Може, нам слід зробити якийсь обмін даними та отримати більш точне співвідношення?
recursion.ninja

1
@awashburn Я почав дивитися Supernatural 2 місяці тому (зараз застряг у 9 сезоні) і 9:1мені здається нормальним;)
CommonGuy

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
@Underated Замість Math.ceil(Math.random()-Math.random())вас також можна робити просто Math.round(Math.random()).
tomsmeding

10

R, дещо баєсівський бот

Використовуйте таблицю частот для кожного користувача як попередню ймовірність виходу інших користувачів.

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

Я цього не писав!
Rainbolt

Ось іронія. Нейтральність ніколи не перемагає
fabigler

2
@Rusher ах я це зараз отримав: D
fabigler

1
Він навіть не компілюється - пропущена крапка з комою.
Paŭlo Ebermann

9

HAL 9000

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

Редагувати: можливо, це більше підходить для HAL 9000, але будьте уважні! Це дуже зло. Рекомендую cdспорожнити каталог перед його запуском.

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

Це видаляє один файл з cwdкожного виклику!

Не настільки очевидний виклик:

У M $

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

Вам потрібно надати команду, яку можна використовувати для запуску програми. Для отримання додаткової інформації дивіться розділ «Випуск».
Rainbolt

@Rusher Done;)
core1024

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слід введення.

Проста програма, просто подивитися, як це буде робити. Іде з тим, що більшість казали минулого разу, або випадково.


Вам потрібно надати команду, яку можна використовувати для запуску програми. Для отримання додаткової інформації дивіться розділ «Випуск».
Rainbolt

Чорт забирає, що робить мій дублікатом. : D Змінив міну на меншість.
Мартін Ендер

@Rusher Додав команду. Що ви шукали?
isaacg

@isaacg Ідеально!
Rainbolt

1
Я обчислював середній рейтинг з балів на табло, і цей запис вигравав за цим показником.
Brilliand

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але це не є функцією. Чи можете ви передати свою заяву до точки, де вона буде складатись?
Rainbolt

@Rusher - зроблено :)
Algy Taylor

@Algy: lastRound.lengthвсе ще доступний (у першому, якщо) перед тим, lastRoundяк оголошено (у тому, якщо є інше). Будь-ласка, спробуйте скласти (а може, запустити) свій код, перш ніж надсилати його сюди.
Paŭlo Ebermann

@ PaŭloEbermann - вибачте, я не перебуваю в середовищі, де я можу це виконати - поправка зроблена, хоча
Алгі Тейлор

Тепер ви посилаєтесь на змінну під назвою "personToCopy", коли вона виходить за межі області. Я просто перемістив його всередині іншого блоку, щоб він компілювався, але я не знаю, чи це ви хотіли.
Rainbolt

8

Пізніше Evil, JavaScript ( node.js )

Вимірює кількість часу між стратами. Якщо різниця у часі більша, ніж минулого разу, це повинно бути злим. Інакше добре.

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

Шукач візерунків, Python

Шукає повторюваний зразок, і якщо він не може знайти його, просто йде з більшістю.

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 очок, якось.
Realdeo

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

Іди вперед. Мені цікаво бачити, як вони будуть робити, особливо проти тих, хто збирає статистику голосування.
jaybz

@Rainbolt Я щойно помітив дурну помилку із завушкою. Не потрібно виправляти це. Він все ще працює, не зовсім так, як задумано, і навіть якщо це не пізно виправити, виправлення це просто змусить поводитись так само, як один із нових записів у будь-якому випадку. Ви можете включити / виключити, якщо хочете.
jaybz

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]

Моя спроба майже інтелектуального запису (насправді розумний вимагає тестування на полі). Написано в Ruby, тому є ймовірність, що це буде занадто повільно, але на моїй машині все одно потрібні 11 секунд, щоб обчислити останній раунд, коли є 40 випадкових гравців, тож я сподіваюся, що він буде працювати досить добре.

зберегти як biographer.rb, запустити якruby biographer.rb

Ідея полягає в тому, що для кожного гравця він оцінює свої шанси на вибір "добре", переглядаючи як свій власний вибір за останні десять раундів, так і загальний результат, а також виявляючи випадки в минулому, коли однакові обставини (їх голоси + загальна кількість) результати) відбулися. Він вибирає найдовший вигляд за довжиною, до 10 раундів, таким, що є будь-який прецедент, і використовує цю функцію для створення частоти (коригується відповідно до Закону про спадщину Лапласа, щоб ми ніколи не були впевнені ні в кого).

Потім він виконує деякі симуляції і бачить, як часто Добро перемагає. Якщо моделювання виявилося здебільшого однаковим, тоді, ймовірно, це буде добре прогнозувати в цілому, тож він підбирає передбачувану меншість. Якщо це не впевнено, воно вибирає передбачувану більшість.


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 символу процесу в Windows, дайте мені знати. В іншому випадку, вибачте за те, що ви зіпсували ваш запис, і дякую за виправлення! Я не очікував отримання такої кількості матеріалів.
Rainbolt

7

Помилковий гравець (Python)

Якщо одна сторона кілька разів поспіль вигравала більшість, гравець розуміє, що інша сторона, швидше за все, буде більшістю в наступному турі (правда?), І це впливає на його голос. Він націлений на меншину, бо якщо він потрапить до меншості, коли він, ймовірно, зробить її там кілька разів (правда?) Та отримає багато балів.

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
Мені подобається, як ти впевнений у своєму коді, правда? : P
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
Я видалив рядок друку з коду для тестування. Записи Java потрібно лише повернути добро чи зло, а не друкувати.
Rainbolt

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.

Бігти

зателефонуйте ridge_professor.exe та надайте аргумент у міру необхідності.

Питання

Оскільки я поки не можу коментувати, я запитаю тут: чи не обмеження розміру аргументу у Windows не дає змоги викликати отримані бінарні файли з усією історією на кілька сотень витків? Я думав, що у аргументі не може бути більше ~ 9000 символів ...


Спасибі звернули мою увагу на це . Я вигадаю якийсь спосіб змусити його працювати, якщо він вже не працює на Java. Якщо Java не може цього зробити, дослідження показують мені, що C ++ може, і я скористаюся можливістю перевчити C ++. Незабаром повернусь з результатами тесту.
Rainbolt

Як виявляється, Java не підпадає під обмеження командного рядка. Здається, що лише команди, що перевищують 32k, викликають проблему. Ось мій доказ (я сам це написав): docs.google.com/document/d/… . Знову ж таки, я дуже вдячний, що ви довели це до того, як розпочнуться випробування завтра.
Rainbolt

@Rusher Вже є 57 ботів, і ви плануєте, щоб кожен запуск складався з 1000 раундів. Це зробило б ваші рядкові символи 57k (отже,> 32k), чи не так?
планнапус

1
@Rusher Я думаю, що може бути краще продовжити хронологію ще на тиждень і попросити учасників змінити свої програми для читання stdin, а не використовувати рядок аргументів. Було б банально змінити більшість програм
dgel

@dgel Хронологія виклику нескінченно довга, але я не хочу змінювати правила таким чином, щоб усі мали переписати свою відповідь. Я майже впевнений, що правило, яке я додав минулої ночі, буде виконувати лише одне подання, і я планую допомогти цій людині, якщо він коли-небудь потрапить до своєї програми до моменту, коли вона складається.
Rainbolt

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% "добрих" голосів ви сторони проти "добра" ще зі злом? (З цікавості: Ви віддаєте перевагу криптовалютним іменам змінних чи це випадковість?)
Angelo Fuchs

1
@AngeloNeuschitzer Я дивлюся на останні два обороти (0 коми досі та 1 кома поки що), і якщо вони обоє нехай зло переможе, я голосую добре. Інакше я голосую зло. Я вважаю за краще імена змінних, які є короткими, якщо код досить короткий, мета коду не буде плутатися. Я не професійний програміст, і це був перший раз, коли я програмував у Java або щось ще хтось бачив код за 6,5 років. Я написав це, щоб оновити свою пам’ять. (TLDR, вони не криптовані для мене, і я єдиний,
котрий

Для наочності ... Кроулі почав бути людиною, тому навмисно він починає добре ... Не сподівався, що він залишиться хорошим у всіх раундах, хоча ... чорт
Кайн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.