112
\$\begingroup\$

Results - July 19, 2014

The current King of the Hill is Mercenary by user Fabigler! Keep submitting entries and knock him off of his throne!

Click here to view the Scoreboard.

Programs submitted on or before July 19, 2014 were included. All other submissions will be included in future trials. New results should be posted around August 9, so that gives you plenty of time.


Illustration drawn by brother Illustrated by Chris Rainbolt, my brother and a fresh graduate from Savannah College of Art and Design

Introduction

The angels and demons are fighting and, as usual, using earth as their battleground. Humans are stuck in the middle and are being forced to take sides. An unknown neutral force rewards those who consistently fight for the losing side.

The Game

Each trial, you will be pseudorandomly paired and then shuffled with between 20 and 30 other submissions. Each trial will consist of 1000 rounds. Each round, you will be passed an input and be expected to produce output. Your output will be recorded and scored. This process will be repeated 1000 times.

Input

You will receive a single argument that represents the past votes of each player. Rounds are delimited by comma. A 0 represents a player who sided with Evil that round. A 1 represents a player who sided with Good. Within a trial, the players will always be in the same order. Your own vote will be included, but not explicitly identified. For example:

101,100,100

In this example, three rounds have been completed and three players are competing. Player one always sided with Good. Player two always sided with Evil. Player three swapped from Good in round 1 to Evil in rounds 2 and 3. One of those players was you.

Output

Java Submissions

  • Return the string good if you want to side with Good.
  • Return the string evil if you want to side with Evil.

Non-Java Submissions

  • Output the string good to stdout if you want to side with Good.
  • Output the string evil to stdout if you want to side with Evil.

If your program outputs or returns anything else, throws an exception, does not compile, or takes longer than one second to output anything on this exact machine, then it will be disqualified.

Scoring

Scores will be posted in a Google docs spreadsheet for easy viewing as soon as I can compile all the current entries. Don't worry - I will keep running trials for as long as you guys keep submitting programs!

  • You receive 3 points for siding with the majority during a round.
  • You receive n - 1 points for siding with the minority during a round, where n is the number of consecutive times you have sided with the minority.

Your score will be the median of 5 trials. Each trial consists of 1000 rounds.

Deliverables

Non-Java Submissions

You must submit a unique title, a program, and a Windows command line string that will run your program. Remember that an argument may be appended to that string. For example:

  • python Angel.py
    • Note that this one has no args. This is round one! Be prepared for this.
  • python Angel.py 11011,00101,11101,11111,00001,11001,11001

Java Submissions

You must submit a unique title and a Java class that extends the abstract Human class written below.

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

Testing

If you want to test your own submission, follow the instructions here.

Additional Notes

You may submit as many different submissions as you want. Submissions that appear to be colluding will be disqualified. The author of this challenge will be the only judge on that matter.

A new instance of your program or Java class will be created every time it is called upon. You may persist information by writing to a file. You may not modify the structure or behavior of anything except your own class.

Players will be shuffled before the trial starts. Demon and Angel will participate in every trial. If the number of players is even, Petyr Baelish will also join. Demon fights for Evil, Angel for Good, and Petyr Baelish chooses a pseudorandom side.

\$\endgroup\$
  • 2
    \$\begingroup\$ Comments purged, as they were obsolete and at request of OP. Please notify me of any comments that need to be undeleted. \$\endgroup\$ – Doorknob Jul 16 '14 at 11:28
  • 7
    \$\begingroup\$ Woah, OP changes his username. Ok, so when will the result be displayed? \$\endgroup\$ – justhalf Jul 18 '14 at 6:52
  • 6
    \$\begingroup\$ @Rainbolt This must be one freakin' hell of a job, running this challenge! The reason for this amount of attention is the simplicity of the protocol and the rules, making it accessible while also allowing simple, working entries. TL;DR: Your challenge is too good! :D \$\endgroup\$ – tomsmeding Jul 19 '14 at 18:54
  • 3
    \$\begingroup\$ @dgel I'll post the raw data, upper, lower, averages, and maybe a line chart so we can see who did better as the competition dragged on. \$\endgroup\$ – Rainbolt Jul 21 '14 at 12:03
  • 6
    \$\begingroup\$ One of the pods ended up with 10 entries that voted the same way every single time. Consequently, two users ended up with perfect or "one round short of perfect" scores of around 450,000. The same entries scored around 1900 in other trials. The average score is close to 2000. Because of the extreme imbalance in results, I decided that a more meaningful number would be a median. I edited the challenge so that after 5 trials, the winner will be the submission with the highest median. If anyone thinks that moving from mean to median is unfair or otherwise a poor choice, please comment. \$\endgroup\$ – Rainbolt Jul 21 '14 at 18:57

92 Answers 92

0
\$\begingroup\$

Logical

My code chooses its side by probabilities or by random if there isn't enough data.

C++:

#include <iostream>
#include <time.h>

using namespace std;

int main(int argc, char* argv2[])
{
    srand(time(0));
bool evil = false;
if(argc == 1) {
    if(rand() % 2 == 1) evil = true;
} else {

    char* argv = argv2[1];
    int length = strlen(argv);
    int rounds = 0, goods[1000], evils[1000];

    for(int i = 0; i < 1000; i++){

        goods[i] = 0;
        evils[i] = 0;
    }

    for(int i = 0; i < length; i++) {

        if(argv[i] == ',') {
            rounds++;
        } else if(argv[i] == '1') {
            goods[rounds]++;
        } else {
            evils[rounds]++;
        }
    }
    rounds++;
    cout << rounds << endl;
    if(rounds < 2) {

        if(rand() % 2 == 1) evil = true;
    } else {

        int changes[10]; //0-4 no change, 5-9 change
        int changeBorders[5], index = 0, difference = 0;
        fill_n(changes, 10, 0);
        fill_n(changeBorders, 5, 0);
        changeBorders[0] = (goods[0]+evils[0])/6;
        changeBorders[1] = changeBorders[0]*2;
        changeBorders[2] = changeBorders[0]*3;
        changeBorders[3] = changeBorders[0]*4;
        changeBorders[4] = changeBorders[0]*5;
        for(int i = 0; i < rounds-1; i++) {

            index = 0;

            if((goods[i] > evils[i] && goods[i+1] < evils[i+1]) || (goods[i] < evils[i] && goods[i+1] > evils[i+1])) index += 5;
            difference = abs(goods[i]-evils[i]);
            if(difference < changeBorders[0]) {//do nothing
            } else if(difference < changeBorders[1]) index++;
            else if(difference < changeBorders[2]) index += 2;
            else if(difference < changeBorders[3]) index += 3;
            else if(difference < changeBorders[4]) index += 4;
            changes[index]++;
        }

        difference = abs(goods[rounds-1]-evils[rounds-1]);
        if(difference < changeBorders[0]) index = 0;
        else if(difference < changeBorders[1]) index = 1;
        else if(difference < changeBorders[2]) index = 2;
        else if(difference < changeBorders[3]) index = 3;
        else if(difference < changeBorders[4]) index = 4;

        if(goods[rounds-1] > evils[rounds-1]) evil = false;
        else evil = true;

        if(changes[index] == 0 && changes[index+5] == 0) {
            if(rand() % 2 == 1) evil = true;
        } else if(changes[index+5] == 0) evil = !evil;
        else if(changes[index] == 0) { //do nothing
        } else if(changes[index] < changes[index+5]) evil = !evil;
    }
}

cout << (evil ? "evil" : "good") << endl;

return 0;

}

EXE: http://www.filedropper.com/goodandevil

Usage: Windows command line with "goodandevil.exe [vote history here]".

\$\endgroup\$
0
\$\begingroup\$

FBI (Ruby)

print %w&good evil&[ARGV.map{|w|w.each_char.reject{|r|%r{,}=~r}.shuffle.pop.to_i}[%*#{Math.sqrt(5/2)}*.to_i-1]]

The FBI uses codes to hide intent. What it dose is:

Something you can find out yourself! Why would I go to this extent to hide the meaning of code then tell you what it means in a spoiler right after?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.