Niedrigstes Einzelgebot

22

Vielen Dank für alle Einsendungen, die Deadline ist nun abgelaufen und die Endergebnisse sind am Ende der Frage.
Glückwunsch an PhiNotPi zu einem recht umfassenden Sieg.

Dies ist eine Herausforderung, deren Ziel es ist, ein Programm zu erstellen, das in einer Auktion mit dem niedrigsten Einzelgebot häufiger gewinnt als jeder seiner Gegner.

Eingang

Als Eingabe erhält das Programm alle Gebote der vorherigen Runden, eine Runde pro Zeile, wobei alle Gebote wie folgt durch Leerzeichen getrennt sind:

10 4 12 11 12 4 7 3 3
1 2 9 15 1 15 15 9 3
3 21 6 4 3 8 6 13 1

Jede Spalte der Eingabe repräsentiert das Bieten eines Bots. Die erste Spalte enthält die Gebote des empfangenden Programms, während der Rest in zufälliger Reihenfolge generiert wird. Vielen Dank an Hammar und Peter Taylor für ihren Beitrag.

Die Eingabe wird als einziges (mehrzeiliges) Befehlszeilenargument für Ihr Programm bereitgestellt:

./test1 '1 2
3 4
5 6
1 2'

Dies bedeutet, dass Ihr Programm über die Befehlszeile ausgeführt werden muss. Bitte geben Sie ein Beispiel für den Aufruf als Teil Ihrer Antwort.

In der ersten Runde wird 0für jeden Bot eine S-Eins- Zeile eingegeben, um Sie über die Anzahl der Bots zu informieren, gegen die Sie antreten .

Ausgabe

Ihr Programm sollte sein Gebot als Ganzzahl im Bereich von 1 bis 100 (einschließlich) ausgeben.

Torschütze Programm

Dies ist mein Bewertungsprogramm - Vorschläge für Ergänzungen, Verbesserungen oder Fehlerkorrekturen sind willkommen.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NUMROUNDS 10
#define NUMBOTS 4
#define MAXINPUTSIZE 10000
#define MAXFILENAMESIZE 100

int main()
{
    int i,j,a,b,winner;
    FILE *fp;
    char bots[NUMBOTS][MAXFILENAMESIZE]={"onesconfident","random100","random20","random5"};
    char openstring[MAXFILENAMESIZE+MAXINPUTSIZE+3];
    char input[MAXINPUTSIZE];
    char buff[5];
    int shuffle[NUMBOTS],auction[100],lowestbid[NUMBOTS]={[0 ... NUMBOTS-1]=101};
    static int guesses[NUMBOTS][NUMROUNDS];
    static int scores[NUMBOTS],totalwinbids[NUMBOTS];

    srand(time(NULL));

    for(i=0;i<NUMROUNDS;i++)
    {
        /*blank the auction bids for the next round */
        for(a=0;a<100;a++)
        {
            auction[a]=9999;
        }

        /*loop through the bots sending the input and storing their output */
        for(j=0;j<NUMBOTS;j++)
        {
            /*Fisher-Yates shuffle */
            for(b=0;b<NUMBOTS;b++)
            {
                shuffle[b]=(b+j)%NUMBOTS;/*put current bot at index 0 */
            }
            for(b=NUMBOTS-1;b>1;b--)
            {
                int z=rand()%(b-1)+1;/*make sure shuffle leaves index 0 alone */
                int t=shuffle[b];
                shuffle[b]=shuffle[z];
                shuffle[z]=t;
            }

            /*generate the input for the bots */
            strcpy(input,"'");
            if(i==0)
            {
                for(b=0;b<NUMBOTS;b++)
                {
                    if(b!=0)
                        sprintf(input,"%s 0",input);
                    else
                        sprintf(input,"%s0",input);
                }
            }
            else
            {
                for(a=0;a<i;a++)
                {
                    for(b=0;b<NUMBOTS;b++)
                    {
                        if(b!=0)
                            sprintf(input,"%s %d",input,guesses[shuffle[b]][a]);
                        else
                            sprintf(input,"%s%d",input,guesses[shuffle[b]][a]);
                    }
                    if(a!=i-1)
                        strcat(input,"\n");
                }
            }
            strcat(input,"'");

            sprintf(openstring,"%s %s",bots[j],input);
            fp=popen(openstring,"r");

            fgets(buff,3,fp);
            fflush(NULL);
            pclose(fp);
            guesses[j][i]=atoi(buff);

            /*add the bid to the auction, eliminating any duplicates */
            if(auction[atoi(buff)-1]!=9999)
                auction[atoi(buff)-1]=9998;
            else
                auction[atoi(buff)-1]=j;
        }

        winner=9999;
        /*add one to the score of the winning bot */
        for(a=0;a<100;a++)
        {
            if(auction[a]!=9998 && auction[a]!=9999)
            {
                winner=auction[a];
                scores[winner]+=1;
                totalwinbids[winner]+=guesses[winner][i];
                if(guesses[winner][i]<lowestbid[winner])
                    lowestbid[winner]=guesses[winner][i];
                break;
            }
        }

        /*output this round's bids and the winning bot's name */
        strcpy(input,"");
        for(b=0;b<NUMBOTS;b++)
        {
            if(strcmp(input,"")!=0)
                sprintf(input,"%s %d",input,guesses[b][i]);
            else
                sprintf(input,"%d",guesses[b][i]);
        }
        if(winner!=9999)
            printf("%s %s\n",input,bots[winner]);
        else
            printf("%s No winner\n",input);
    }

    /*output final scores */
    printf("\nResults:\n");
    printf("Bot\tScore\tTotal\tLowest\n");
    for(a=0;a<NUMBOTS;a++)
    {
        printf("%s\t%d\t%d\t%d\n",bots[a],scores[a],totalwinbids[a],lowestbid[a]);
    }

    return 0;
}

Spieler testen

Man ist zuversichtlich, immer bietet 1.

#include <stdio.h>

int main()
{
    printf("1");
    return 0;
}

Random100 Bietet zufällig über den gesamten Bereich

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    srand(getpid());
    printf("%d",rand()%100+1);
    return 0;
}

Random20 Bietet zufällig zwischen 1 und 20

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    srand(getpid());
    printf("%d",rand()%20+1);
    return 0;
}

Random5 Bietet zufällig zwischen 1 und 5

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    srand(getpid());
    printf("%d",rand()%5+1);
    return 0;
}

Beispiel Durchlauf:

1 38 5 2 onesconfident
1 66 13 5 onesconfident
1 94 1 3 random5
1 22 9 1 random20
1 50 17 4 onesconfident
1 78 5 2 onesconfident
1 6 13 5 onesconfident
1 34 1 3 random5
1 62 9 1 random20
1 90 17 4 onesconfident

Results:
Bot Score   Total   Lowest
onesconfident   6   6   1
random100   0   0   101
random20    2   18  9
random5 2   6   3

Diese Player dienen nur zu Testzwecken. Sie werden NICHT in den Wettbewerb aufgenommen. Sie können so viele Bots eingeben, wie Sie möchten. Wenn also jemand einen Bot eingibt, der nur raten kann 1, können Sie einen anderen eingeben, der dasselbe tut, um ihn unbrauchbar zu machen.

Gewinner

Der Gewinner in jeder Runde ist derjenige, der das niedrigste Einzelgebot abgibt. Bei einer Runde, in der die folgenden Gebote abgegeben werden, ist 1 1 3 5 2 3 6 3 2 8 7der Gewinner derjenige, der geboten hat, 5da 1s, 2s und 3s nicht eindeutig sind.

Gewinner des Wettbewerbs ist das Programm, das nach 100 Runden am häufigsten gewinnt. Im Falle eines Unentschieden wird die Summe der gewonnenen Gebote als Unentschieden gewertet, und im Falle eines Unentschieden wird das niedrigste gewonnene Gebot als weiterer Unentschieden gewertet. Diese Bewertungsfaktoren werden alle vom Bewertungsprogramm ausgegeben.

Ich werde das Scoring-Programm für alle Arbeitsprogramme durchführen, die in zwei Wochen ab heute ( 18. Februar, jetzt verlängert um 23 Uhr (GMT) am 20. Februar ) eingegangen sind . Ich werde alle funktionierenden Einträge verbessern und den Gewinner meines Wertungslaufs akzeptieren.

Letzter Wertungslauf

1 9 3 2 1 6 4 3 6 8 7 10 26 6 10 5 26 2 5 8 8 5 7 6 42 1 ./phinotpi2
1 11 4 2 1 4 9 20 6 8 7 6 26 4 8 4 26 2 5 8 8 5 7 7 42 1 ./phinotpi2
1 7 9 2 1 4 3 20 6 8 7 6 7 4 8 9 26 2 5 8 8 5 4 9 42 3 node minitech1.js
1 13 20 2 1 3 3 20 6 8 7 7 9 6 8 20 26 2 5 8 8 5 9 9 42 3 ./dirichlet
1 12 13 2 1 1 3 20 6 8 7 7 9 6 9 13 26 2 5 8 8 5 20 9 42 3 ./dirichlet
1 2 4 2 1 1 3 20 6 8 7 7 9 6 9 12 26 2 5 8 8 5 13 9 42 3 python blazer1.py
1 11 4 2 1 4 3 20 6 8 7 6 7 4 8 4 26 2 5 8 8 5 12 9 42 3 ./celtschk
1 3 4 2 1 1 3 20 6 8 7 6 7 4 8 9 26 2 5 8 8 5 4 9 42 3 node minitech1.js
1 7 4 2 1 1 3 20 6 8 7 9 26 6 7 20 26 2 5 8 8 5 9 9 42 10 ./phinotpi2
1 9 9 2 1 3 4 20 6 8 7 6 7 3 9 3 26 2 5 8 8 5 20 9 42 10 ./phinotpi2
1 13 4 2 1 3 9 20 6 8 7 4 6 3 8 4 26 2 5 8 8 5 3 9 42 10 scala Schwarzenbeck
1 12 20 2 1 1 3 20 6 8 7 6 20 4 8 7 26 2 5 8 8 5 4 9 42 10 ./phinotpi2
1 10 3 2 1 2 4 20 6 8 7 6 9 3 9 3 26 2 5 8 8 5 7 9 42 10 ./phinotpi2
1 6 9 2 1 4 9 20 6 8 7 4 6 3 8 4 26 2 5 8 8 5 3 9 42 10 scala Schwarzenbeck
1 8 4 2 1 3 3 20 6 8 7 6 20 4 8 7 26 2 5 8 8 5 4 9 42 10 ./celtschk
1 2 13 2 1 3 3 20 6 8 7 9 20 6 8 9 26 2 5 8 8 5 7 9 42 10 ruby1.9 strategist.rb
1 2 4 2 1 3 3 20 6 8 7 7 10 6 9 10 26 2 5 8 8 5 9 9 42 10 python blazer1.py
1 3 13 2 1 4 3 20 6 8 7 6 7 4 8 4 26 2 5 8 8 5 10 9 42 10 ./celtschk
1 4 4 2 1 3 3 20 6 8 7 6 7 4 8 9 26 2 5 8 8 5 4 9 42 10 ruby1.9 strategist.rb
1 4 9 2 1 4 3 20 6 8 7 7 9 6 8 10 26 2 5 8 8 5 9 9 42 10 ./phinotpi2
1 11 7 2 1 1 4 20 6 8 7 6 7 3 8 3 26 2 5 8 8 5 10 9 42 10 ./phinotpi2
1 6 4 2 1 3 9 20 6 8 7 4 6 3 8 4 26 2 5 8 8 5 3 9 42 10 scala Schwarzenbeck
1 13 7 2 1 1 3 20 6 8 7 6 20 4 8 7 26 2 5 8 8 5 4 9 42 10 ./phinotpi2
1 7 4 2 1 4 4 20 6 8 7 6 20 3 8 3 26 2 5 8 8 5 7 9 42 10 ./celtschk
1 13 3 2 1 1 4 20 6 8 7 6 7 3 8 9 26 2 5 8 8 5 3 9 42 10 ./phinotpi2
1 3 4 2 1 3 3 20 6 8 7 6 7 4 8 4 26 2 5 8 8 5 9 9 42 10 ruby1.9 strategist.rb
1 5 4 2 1 2 3 20 6 8 7 6 7 4 8 10 26 2 5 8 8 5 4 9 42 10 ./phinotpi2
1 6 3 2 1 3 4 20 6 8 7 6 7 3 8 3 26 2 5 8 8 5 10 9 42 10 ./phinotpi2
1 10 20 2 1 1 9 20 6 8 7 4 6 3 8 4 26 2 5 8 8 5 3 9 42 10 scala Schwarzenbeck
1 10 3 2 1 4 3 20 6 8 7 6 20 4 8 7 26 2 5 8 8 5 4 9 42 10 ./celtschk
1 12 4 2 1 1 3 20 6 8 7 9 20 6 8 9 26 2 5 8 8 5 7 9 42 10 ./phinotpi2
1 5 3 2 1 1 4 20 6 8 7 6 7 3 9 3 26 2 5 8 8 5 9 9 42 10 ./phinotpi2
1 13 3 2 1 4 9 20 6 8 7 4 6 3 8 4 26 2 5 8 8 5 3 9 42 10 scala Schwarzenbeck
1 6 9 2 1 4 3 20 6 8 7 6 20 4 8 7 26 2 5 8 8 5 4 9 42 10 ./phinotpi2
1 5 4 2 1 2 4 20 6 8 7 6 20 3 8 3 26 2 5 8 8 5 7 9 42 10 ./celtschk
1 12 3 2 1 3 4 20 6 8 7 6 7 3 8 9 26 2 5 8 8 5 3 9 42 10 ./phinotpi2
1 10 7 2 1 2 3 20 6 8 7 6 7 4 8 4 26 2 5 8 8 5 9 9 42 10 ./phinotpi2
1 9 10 2 1 4 9 20 6 8 7 4 6 3 8 3 26 2 5 8 8 5 4 9 42 10 scala Schwarzenbeck
1 9 20 2 1 4 4 20 6 8 7 6 20 3 8 7 26 2 5 8 8 5 3 9 42 10 ruby1.9 strategist.rb
1 6 3 2 1 3 3 20 6 8 7 9 10 6 9 10 26 2 5 8 8 5 7 9 42 10 node minitech1.js
1 13 3 2 1 3 3 20 6 8 7 7 10 6 8 20 26 2 5 8 8 5 10 9 42 11 ./celtschk
1 3 3 2 1 1 3 20 6 8 7 7 26 6 9 9 26 2 5 8 8 5 20 9 42 11 ruby1.9 strategist.rb
1 5 20 2 1 2 3 20 6 8 7 7 11 6 9 11 26 2 5 8 8 5 9 9 42 11 ./phinotpi2
1 7 3 2 1 4 4 20 6 8 7 6 7 3 9 3 26 2 5 8 8 5 11 9 42 11 node minitech1.js
1 7 3 2 1 1 4 20 6 8 7 6 7 3 8 20 26 2 5 8 8 5 3 9 42 10 ./phinotpi2
1 8 4 2 1 4 3 20 6 8 7 6 7 4 8 4 26 2 5 8 8 5 20 9 42 10 ./phinotpi2
1 2 3 2 1 3 9 20 6 8 7 4 6 3 8 3 26 2 5 8 8 5 4 9 42 10 scala Schwarzenbeck
1 4 13 2 1 3 4 20 6 8 7 6 20 3 7 7 26 2 5 8 8 5 3 9 42 10 ./celtschk
1 8 3 2 1 3 3 20 6 8 7 9 20 6 8 9 26 2 5 8 8 5 7 9 42 10 ruby1.9 strategist.rb
1 9 10 2 1 2 3 20 6 8 7 7 10 6 9 10 26 2 5 8 8 5 9 9 42 10 ./phinotpi2
1 10 20 2 1 1 4 20 6 8 7 6 7 3 9 3 26 2 5 8 8 5 10 9 42 10 ./phinotpi2
1 9 4 2 1 1 9 20 6 8 7 4 6 3 8 4 26 2 5 8 8 5 3 9 42 10 scala Schwarzenbeck
1 11 20 2 1 4 3 20 6 8 7 6 20 4 8 7 26 2 5 8 8 5 4 9 42 10 ./phinotpi2
1 4 9 2 1 3 4 20 6 8 7 6 9 3 9 3 26 2 5 8 8 5 7 9 42 10 ruby1.9 strategist.rb
1 5 3 2 1 4 4 20 6 8 7 6 7 3 8 10 26 2 5 8 8 5 3 9 42 10 ./celtschk
1 7 4 2 1 3 3 20 6 8 7 7 9 6 8 9 26 2 5 8 8 5 10 9 42 10 python blazer1.py
1 4 9 2 1 1 3 20 6 8 7 6 7 4 8 4 26 2 5 8 8 5 9 9 42 10 ./phinotpi2
1 8 4 2 1 3 9 20 6 8 7 4 6 3 8 3 26 2 5 8 8 5 4 9 42 10 scala Schwarzenbeck
1 10 9 2 1 3 4 20 6 8 7 6 20 3 8 7 26 2 5 8 8 5 3 9 42 10 ./phinotpi2
1 4 20 2 1 1 3 20 6 8 7 6 20 4 8 4 26 2 5 8 8 5 7 9 42 10 ./phinotpi2
1 5 3 2 1 2 9 20 6 8 7 4 6 3 9 3 26 2 5 8 8 5 4 9 42 10 scala Schwarzenbeck
1 2 4 2 1 1 4 20 6 8 7 6 20 3 8 7 26 2 5 8 8 5 3 9 42 10 ./celtschk
1 10 12 2 1 1 3 20 6 8 7 9 20 6 8 9 26 2 5 8 8 5 7 9 42 10 ./phinotpi2
1 9 4 2 1 4 4 20 6 8 7 6 7 3 9 3 26 2 5 8 8 5 9 9 42 10 ruby1.9 strategist.rb
1 11 3 2 1 3 4 20 6 8 7 6 7 3 8 10 26 2 5 8 8 5 3 9 42 10 ./phinotpi2
1 8 4 2 1 1 3 20 6 8 7 6 7 4 8 4 26 2 5 8 8 5 10 9 42 10 ./phinotpi2
1 13 9 2 1 4 9 20 6 8 7 4 6 3 8 3 26 2 5 8 8 5 4 9 42 10 scala Schwarzenbeck
1 2 9 2 1 3 4 20 6 8 7 6 20 3 8 7 26 2 5 8 8 5 3 9 42 10 ./phinotpi2
1 8 3 2 1 2 3 20 6 8 7 6 20 4 8 4 26 2 5 8 8 5 7 9 42 10 ./celtschk
1 3 3 2 1 4 3 20 6 8 7 6 7 4 8 9 26 2 5 8 8 5 4 9 42 10 ruby1.9 strategist.rb
1 10 4 2 1 1 3 20 6 8 7 7 9 6 8 10 26 2 5 8 8 5 9 9 42 10 ./phinotpi2
1 3 9 2 1 4 4 20 6 8 7 6 7 3 8 3 26 2 5 8 8 5 10 9 42 10 node minitech1.js
1 7 11 2 1 4 4 20 6 8 7 6 7 3 8 20 26 2 5 8 8 5 3 9 42 10 ./celtschk
1 8 3 2 1 2 3 20 6 8 7 7 9 6 8 9 26 2 5 8 8 5 20 9 42 10 ruby1.9 strategist.rb
1 3 10 2 1 3 3 20 6 8 7 7 10 6 9 10 26 2 5 8 8 5 9 9 42 10 node minitech1.js
1 8 4 2 1 1 3 20 6 8 7 7 10 6 8 20 26 2 5 8 8 5 10 9 42 11 ./phinotpi2
1 2 4 2 1 2 4 20 6 8 7 6 7 3 9 3 26 2 5 8 8 5 20 9 42 11 ruby1.9 strategist.rb
1 4 9 2 1 4 4 20 6 8 7 6 7 3 8 11 26 2 5 8 8 5 3 9 42 11 node minitech1.js
1 4 9 2 1 1 3 20 6 8 7 7 11 6 8 20 26 2 5 8 8 5 11 9 42 10 ./phinotpi2
1 2 7 2 1 1 4 20 6 8 7 6 7 3 9 3 26 2 5 8 8 5 20 9 42 10 ./phinotpi2
1 9 3 2 1 1 9 20 6 8 7 4 6 3 8 4 26 2 5 8 8 5 3 9 42 10 scala Schwarzenbeck
1 3 9 2 1 2 3 20 6 8 7 6 20 4 8 7 26 2 5 8 8 5 4 9 42 10 ruby1.9 strategist.rb
1 5 7 2 1 3 3 20 6 8 7 10 20 6 8 10 26 2 5 8 8 5 7 9 42 10 ./celtschk
1 8 10 2 1 4 3 20 6 8 7 7 10 6 9 9 26 2 5 8 8 5 10 9 42 10 ./phinotpi2
1 5 4 2 1 4 4 20 6 8 7 6 7 3 9 3 26 2 5 8 8 5 9 9 42 10 ruby1.9 strategist.rb
1 5 20 2 1 3 4 20 6 8 7 6 7 3 8 10 26 2 5 8 8 5 3 9 42 10 ./phinotpi2
1 11 20 2 1 2 3 20 6 8 7 6 7 4 8 4 26 2 5 8 8 5 10 9 42 10 ./phinotpi2
1 12 10 2 1 1 9 20 6 8 7 4 6 3 9 3 26 2 5 8 8 5 4 9 42 10 scala Schwarzenbeck
1 10 3 2 1 1 4 20 6 8 7 6 20 3 8 7 26 2 5 8 8 5 3 9 42 10 ./phinotpi2
1 9 4 2 1 4 3 20 6 8 7 6 20 4 8 4 26 2 5 8 8 5 7 9 42 10 ./phinotpi2
1 5 3 2 1 1 9 20 6 8 7 4 6 3 8 3 26 2 5 8 8 5 4 9 42 10 scala Schwarzenbeck
1 7 4 2 1 1 4 20 6 8 7 6 20 3 7 7 26 2 5 8 8 5 3 9 42 10 ./celtschk
1 11 7 2 1 3 3 20 6 8 7 9 20 6 8 9 26 2 5 8 8 5 7 9 42 10 ruby1.9 strategist.rb
1 13 10 2 1 1 3 20 6 8 7 7 10 6 9 10 26 2 5 8 8 5 9 9 42 10 ./phinotpi2
1 9 9 2 1 1 4 20 6 8 7 6 7 3 9 3 26 2 5 8 8 5 10 9 42 10 ./phinotpi2
1 7 9 2 1 3 9 20 6 8 7 4 6 3 8 4 26 2 5 8 8 5 3 9 42 10 ruby1.9 strategist.rb
1 13 7 2 1 4 3 20 6 8 7 6 7 4 8 10 26 2 5 8 8 5 4 9 42 10 ./phinotpi2
1 8 7 2 1 1 4 20 6 8 7 6 7 3 8 3 26 2 5 8 8 5 10 9 42 10 ./phinotpi2
1 12 3 2 1 1 9 20 6 8 7 4 6 3 8 4 26 2 5 8 8 5 3 9 42 10 scala Schwarzenbeck
1 13 7 2 1 2 3 20 6 8 7 6 20 4 8 7 26 2 5 8 8 5 4 9 42 10 ./phinotpi2

Results:
Bot                 Score   Total   Lowest
perl phinotpi1.pl           0   0   101
./dirichlet                 2   25  12
python blazer1.py           3   12  4
perl chef.pl ilmari2.chef   0   0   101
./brainfuck ilmari1.bf      0   0   101
./christophe1               0   0   101
./phinotpi2                 44  156 3
node minitech1.js           7   140 20
scala Mueller               0   0   101
scala Beckenbauer           0   0   101
scala Schwarzenbeck         15  105 7
./alice                     0   0   101
./bob                       0   0   101
./eve                       0   0   101
python joe.py               0   0   101
python copycat.py           0   0   101
python totalbots.py         0   0   101
perl healthinspector.pl     0   0   101
./mellamokb1                0   0   101
./mellamokb2                0   0   101
php eightscancel.php        0   0   101
php fivescancel.php         0   0   101
python copycat2.py          0   0   101
./celtschk                  14  126 9
./deepthought               0   0   101
ruby1.9 strategist.rb       15  152 10
Gareth
quelle
1
Hmm ... mit den Regeln, die so geschrieben sind, könnte ich das Spiel wirklich verderben, indem ich 100 Programme eingebe, die jeweils eine bestimmte Zahl bieten.
Ilmari Karonen
1
Können Sie zwei Sätze sagen, wie der Gewinner ausgewählt wird? Ich verstehe es nicht.
Benutzer unbekannt
@IlmariKaronen Das stimmt, du könntest. Aber ich vertraue darauf, dass die Leute das nicht tun werden. Ich könnte die Anzahl der Einträge pro Person begrenzen, aber ich denke, ich werde nur darauf zurückgreifen, wenn irgendwelche Spoiler mitkommen.
Gareth
@userunknown Ich habe versucht zu klären, wie die Auktionsrunden funktionieren.
Gareth
1
@PhiNotPi: Fühle dich nicht schuldig. Sie haben innerhalb der Regeln gewonnen.
Steven Rumbalski

Antworten:

9

Perl

Ich habe es diesmal etwas härter versucht. Es ist eine sehr einfache und komplexe Strategie, aber ich habe den Rahmen für die Erweiterung festgelegt.

Bearbeiten: Vollständiges Wiederherstellen. Diese Sache ist drin für den Sieg.

    sub prob{
$_[0]+$_[1]-$_[0]*$_[1]
}

$_=<>;
INPUT:{

tr/ /,/;
@in = eval;
for(1..$#in){
 $bids[$rnum][$in[$_]]++
}
for(0..$#in){
 $tbids[$rnum][$in[$_]]++
}
$rnum++;
$_=<>;
if($_ ne"\n"){redo INPUT}
}

for(0..100){$pre[$_]=0}

dirichlet: for(2..$#in/2+2){    #rough approximation, 
$pre[$_]=prob($pre[$_], 1/int($#in/2+1))
}

CDP:{
    @cdps1=(1,1,1,2,2,3,3,4);
    @cdps2=(-2,-1,0,1,1,2,2,3,3);
    for($a=0;$a<8;$a++){
    for($b=0;$b<9;$b++){
     $sum=$cdps1[$a]+$cdps2[$b];
     if($sum<1){$sum=1};
     $pre[$sum] = prob($pre[$sum], 1/72);
    }
    }
}

blazer: {
for($r=1;$r<$rnum;$r++){
winner: for($pnt=1;$pnt<101;$pnt++){
        if($tbids[$r][$pnt] == 1){
            if($pnt > 2){
                $winnum[$pnt]++;
            $wins++;
            }
        last winner
        }
}
    }
    if($wins==0){
    $pre[3]=prob($pre[3], 1);last blazer
    }
    for(1..100){
    $pre[$_]=prob($pre[$_], $winnum[$_]/$wins);
    }
}

CC1: for($pnt=1;$pnt<101;$pnt++){
    if($tbids[$rnum-1][$pnt] == 1){
        $pre[$pnt] = prob($pre[$pnt], 1);last CC1
    }
    if($pnt==100){
        for($pnt2=1;$pnt2<100;$pnt2++){
        $pre[$pnt2] = prob($pre[$pnt2], $tbids[$rnum-1][$pnt2]/($#in+1));
    }
    }
}

CC2: for($pnt=1;$pnt<101;$pnt++){
    if($rnum-2<0){$pre[7] = prob($pre[7], 1);last CC2}
    if($tbids[$rnum-2][$pnt] == 1){
        $pre[$pnt] = prob($pre[$pnt], 1);last CC2
    }
    if($pnt==100){
        $pre[7] = prob($pre[7], 1);last CC2
    }
}

one: {
$pre[1] = prob($pre[1], 1);
}

two: {
$pre[2] = prob($pre[2], 1);
}

five: {
$pre[5] = prob($pre[5], 1);
}

eight: {
$pre[8] = prob($pre[8], 1);
}

fortytwo: {
$pre[42] = prob($pre[42], 1);
}

mueller: {
    $a=($#in+2)/4;
    $pre[int$a]=prob($pre[int$a], 1)
}

schwarzenbeck: {
    $a=($#in+2)/4+1;
    $pre[int$a]=prob($pre[int$a], 1)
}

beckenbauer: {
    $a=($#in+2)/4+2;
    $pre[int$a]=prob($pre[int$a], 1)
}

totalbots: {
    $pre[$#in+1]=prob($pre[$#in+1], 1)
}

joe: {
$sum=0;
    for(1..100){
    $sum+=$tbids[$rnum-1][$_];
}
    $average=$sum/($#in+1);
    if($average==0){$average=10};
    $pre[$average]=prob($pre[$average], 1);
}

node: {
$max=0;$maxloc=0;
for(1..100){
    if($tbids[$rnum-1][$_]>$max){$max=$tbids[$rnum-1][$_];$maxloc=$_}
}
$maxloc--;
#if($maxloc==0){
$maxloc=20;
#}
if($rnum==1){$maxloc=3}
    $pre[$maxloc]=prob($pre[$maxloc], 1);
}
#print"\n@pre\n\n";

decide: for(1..100){if($pre[$_]<0.5){print; last decide}}

Dieses Programm nimmt die Eingabe zeilenweise vor, gefolgt von zwei neuen Zeilen:

perl PhiNotPi2.plx
1 2 3 3 2
2 1 3 1 3
2 1 1 1 3
[empty line]
PhiNotPi
quelle
Ok, das bringt Metagaming auf die Spitze.
Peter Taylor
@petertaylor Gehe ich zu weit aus der Reihe? Soll ich zu meinem Original zurückkehren?
PhiNotPi
2
Dies ist eine für Rechtsanwälte berüchtigte Website - sie ist absolut fair. Aber ich komme zu dem Schluss, dass der Stapelaustauschmechanismus möglicherweise nicht der beste für King-of-the-Hill-Wettbewerbe ist.
Peter Taylor
Zu diesem Schluss bin ich auch gekommen. Wir müssen eine Methode entwickeln, um die Bots in zukünftigen Wettbewerben vor dem Blick zu schützen. Soweit ich weiß, spielt gerade jemand gegen meine Bots.
PhiNotPi
Lol, das war meine Idee: P. Da Sie bereits implementiert haben und ich mich faul fühle, lasse ich Sie es haben :) Beachten Sie, dass die einzige Art von Eintrag, die dies nicht leicht zu übertreffen ist, diejenigen sind, die Zufälligkeit implementieren
mellamokb
8

Koch

Da immer 1 zu setzen jetzt eine verlierende Strategie ist , ist es naheliegend, immer 2 zu setzen. Also lass mich das machen. Um diesen ansonsten langweiligen Eintrag ein wenig interessanter zu machen, habe ich beschlossen, ihn in Chef zu schreiben :

Shirred Eggs.

This recipe prints the number 2 and, in doing so, yields two delicious
shirred eggs.

Ingredients.
2 eggs

Cooking time: 12 minutes.

Pre-heat oven to 175 degrees Celsius.

Method.
Put eggs into mixing bowl. Pour contents of the mixing bowl into the
baking dish. Shirr the eggs. Bake the eggs until shirred.

Serves 1.

Als Bonus funktioniert das Programm mehr oder weniger wie ein echtes - wenn auch triviales - Rezept, auch wenn es so liest, als ob der Schreiber ein bisschen, ähm, gebacken wäre. Die Chef-Grammatik scheint es ziemlich schwierig zu machen, etwas zu schreiben, das komplizierter ist als das Mischen von Dingen in einer Schüssel und das Backen, und dennoch funktioniert es sowohl als Programm als auch als Rezept, besonders wenn eines der Verben verwendet werden soll sind sogar leicht unregelmäßig (wie "braten" → "gebraten").

Edit: Das Rezept wurde von gebratenen zu gerafften Eiern geändert - danke an Blazer für den Vorschlag! Die Garzeit und die Temperatur sollten nur als Richtwerte angesehen werden. Ich habe das Rezept noch nicht selbst ausprobiert und kann daher nicht für deren Richtigkeit bürgen.

Ilmari Karonen
quelle
Ich denke, dies gibt 1 aus: siehe meinen Kommentar unter codegolf.stackexchange.com/a/4851 .
msh210
Es gibt 2 aus, zumindest unter Verwendung des Acme :: Chef- Interpreters. Die letzte Schleife ist nur zur Verschleierung da, damit die Gäste die Eier nicht roh essen müssen.
Ilmari Karonen
Ah, richtig, ich habe die Tatsache übersehen, dass die Eier bereits in der Auflaufform waren und dass das nicht dekrementiert ist.
msh210
2
Sie nennen es shirred eggs, was tatsächlich in einer Auflaufform gemacht wird, und das würde das Rezept zu einem tatsächlich gültigen und grammatikalisch korrekten Kochrezept machen. shirr the eggs. shirr the eggs until shirred.Schrecken, dass ich kulinarische Ausbildung habe! :)
Blazer
1
Die Garzeit / Temperatur scheint in etwa richtig zu sein :). Verwenden Sie diese natürlich immer nur als Richtlinien, da der Koch selbst bestimmt, ob etwas getan wird oder nicht, und nicht die Zeit / Temperatur selbst!
Blazer
4

Python (2.6)

Extrem einfach, aber ich bin trotzdem gespannt, wie es sich im Vergleich zu den anderen Ansätzen verhält.

import sys, random
try:
    s = sys.stdin.readlines()[-2]
    m = min(int(x) for x in s.split())
except IndexError:
    m = random.choice([1,1,1,2,2,3,3,4])
a = random.choice([-2,-1,0,1,1,2,2,3,3])
print max(m + a, 1)

Einfach die gebote über stdin einpfeifen, zb python testbid.py < bids.txt.

BEARBEITEN : geändert für die 'erste Runde alle Nullen'

BEARBEITEN : änderte die "magischen Zahlen" ein wenig (ein zweites Mal)

ChristopheD
quelle
1
sollte nicht m = random.choice(1,2,2,3,3,3)sein m = random.choice([1,2,2,3,3,3])?
Blazer
Es warf einen Fehler, wo Blazer sagte, dass es könnte. Ich habe die eckigen Klammern für den Testlauf gesetzt und es scheint, als hätte es funktioniert.
Gareth
@Blazer: ja, absolut (kleiner Tippfehler meinerseits). Vielen Dank für die Benachrichtigung.
ChristopheD
4

Python (Blazer)

Dieser Bot analysiert die vorherigen Runden und zeichnet die Gewinnzahlen auf. Gewinnzahlen, die häufiger erscheinen, haben daher eine bessere Chance, ausgewählt zu werden. Es werden dann zufällig Zahlen aus den Gewinnzahlen ausgewählt (außer 1 oder 2). es wird stattdessen 2 3 wählen, wenn es die erste Runde ist.

Die Eingabe wird zeilenweise gelesen. Geben Sie einfach eine leere Zeile ein, um keine Eingaben mehr zu akzeptieren

Ein Trick ist, einfach einzufügen (es akzeptiert automatisch jede Zeile mit \ n innerhalb des Einfügens) und zweimal die Eingabetaste zu drücken

Sie können das Skript jetzt einfach mit einem Dateinamen in der Befehlszeile ausführen:

python bidding.py bidding.txt

Die Datei sollte folgendermaßen aussehen:

10 4 12 11 12 4 7 3 3
1 2 9 15 1 15 15 9 3
3 21 6 4 3 8 6 13 1

-

import random
import sys

winning = [] # record the winning numbers

content = sys.argv[1].split('\n')  
for each in content:
    x = map(int, each.split())
    if len(x)+sum(x) == 0: 
        continue 

    y = []
    for each in x:
        if x.count(each) == 1:
            y.append(each)
    if len(y) > 0: 
        if min(y) not in [1,2]:  #never choose 1 or 2
            winning.append(min(y))

# choose an output
if len(winning) == 0:
    print 3
else:
    print random.choice(winning)

edit: hinzugefügt or sum(rounds) == 0, um die letzte Änderung der Nullen in der ersten Runde zu kompensieren

edit: Probleme mit Kommentaren behoben, die Eingabe von einem Dateinamen möglich machten und nie mehr '2' wählten, da die Konkurrenz dies ebenfalls ausgemerzt hat. Arbeitet entweder mit allen Nullen als Ausgangseingabe oder ohne Daten in der Datei

edit2: habe eine Minute vergessen ()

edit3: Eingabe geändert, um den Eingabebedürfnissen der Frage zu entsprechen

Blazer
quelle
Verursacht ein kleines Problem mit dem Torschützen - Ich muss die Eingabetaste drücken, um die Punktzahl für jede Runde zu erhalten. Für meine 10-Runden-Testläufe kein großes Problem, aber für die 100-Runden-Testläufe könnte es schwierig werden.
Gareth,
@ Gareth, wickeln Sie es in ein Bash-Skript. echo "$@" | python bidding.pysollte den Job machen.
Peter Taylor
Ich habe es wie von Peter vorgeschlagen versucht, aber in TypeError: unsupported operand type(s) for +: 'int' and 'list'Zeile 23 wird ein Fehler angezeigt. Ich verwende Python 2.6.1. Ist das das Problem? Benötige ich eine neuere Version? Ich bekomme das gleiche Problem ohne das Bash-Skript.
Gareth,
@Gareth würde es helfen, wenn ich es so mache, dass die Eingabe von sys.argv [1] mit einem Dateinamen weitergeleitet wird?
Blazer
@ Blazer Ich bin mir nicht sicher, ob das das Problem ist. Ich rufe das Programm selbst über die Befehlszeile auf, indem ich Ihren Beispielaufruf verwende und den oben angegebenen Fehler erhalte. Gibt es etwas, das mit Python 2.6.1 nicht kompatibel ist?
Gareth
3

Schwarzenbeck (Scala)

object Schwarzenbeck extends App {
  println ((args(0).split('\n')(0).split(' ').length+1)/4+1)
}

Schwarzenbeck soll die Tore nicht schießen. Er ist die Bereinigung für Beckenbauer, die bald folgt. :)

Um es zu benutzen, brauchen Sie einen Compiler und kompilieren es

scalac Schwarzenbeck.scala 

Dann können Sie es ausführen:

scala Schwarzenbeck 'your ar-
gu-
ment' 

Bearbeiten: Weitere Anpassungen.

Benutzer unbekannt
quelle
1
Angesichts der Tatsache, dass Schwarzenbeck die Tore nicht erzielen sollte, würde ich sagen, dass dies völlig fehlgeschlagen ist :-)
celtschk
Ja, ich hatte ein Dilemma: Ich habe eine Linie von 3 Spielern gebildet und erwartet, dass Müller die meisten Punkte erzielt, aber von einer strategischen Position aus markierte Schwarzenbeck die ultimative Verteidigungslinie. Die Fußball-Metapher schlug fehl, da meine Verteidigungslinie die Tore erzielte. :)
Benutzer unbekannt
3

Stratege (Ruby)

Implementiert Hunderte einfacher Strategien: Wählt für jede Runde diejenige aus, die die meisten vorherigen Runden gewonnen hätte:

require 'Matrix'
def winner guesses
  g=guesses.sort
  while g[0]&&g[0]==g[1]
    g.shift while g[0]==g[1]
    g.shift
  end
  g[0]
end

def prob g
  prob=[0]*100;best=0;n=g.size*(g[0].size-1)
  g.each{|r|r[1..-1].each{|v|prob[v-1]+=1.0/n}};
  prob.map!{|v|v/n}
end    

def regression x, y, degree
  return y if x.size==1 
  x_data = x.map {|xi| (0..degree).map{|pow| (xi**pow.to_f) }}
  mx = Matrix[*x_data]
  my = Matrix.column_vector y
  begin
    r = ((mx.t * mx).inv * mx.t * my).transpose.to_a[0]
  rescue Exception => e
    r=[0]*degree;r[-1]=y[-1].to_f/(x[-1]**degree)
  end
  r
end

brains=((1..50).map{|w|[proc{|g|w},
    proc{|g|best=0;(p=prob g).each_with_index{|v,i|
      best=i if(v+i/100.0/w)<p[best]};best+1}]}+
  (1..7).map{|w|[proc{|g|p=1; if (g[1]) then h=g[1..-1];x=(1..h.size).to_a
      p=0;regression(x,h.map{|r|winner r},w).each_with_index{|v,i|
      p+=v*(g.size**i)};end;p.to_i},
    proc{|g|b=g[0].size/4;if g[1] then pred=[];h=g[1..-1]
      x=(1..h.size).to_a;h[0].size.times{|i|p=0
      regression(x,h.map{|r|r[i]},w).each_with_index{|v,i|p+=v*((x[-1]+1)**i)}
      pred<<[[p.to_i,1].max,100].min}
      (1..100).each{|i|if !pred.include?(i) then b=i;break;end};end;b}]}+
  (-1..1).map{|w|[proc{|g|r=g[0].size; if g.size>1 then
      f=g[1..-1].flatten;r=(f.inject{|s,v|s+v}/f.size.to_f+w).to_i;end;r},
    proc{|g|r=g[0].size/2; if g.size>1 then
      r=(g[1..-1].inject(0){|s,v|s+winner(v)}/(g.size.to_f-1)+w).to_i;end;r},
    proc{|g|(winner(g[-1])||9)+w}  ]}+
  [proc{|g|b=0;(p=prob g).each_with_index{|v,i|b=i if v<p[b]};b+1}]).flatten

games = ARGV[0].split("\n").map{|l|l.split.map{|v|v.to_i}}
winpct=[0]*brains.size
(games.size-1).times{|round|
  entries=games[round+1].dup
  brains.each_with_index{|b,i|
    entries[0]=pick=[b[games[0..round]],1].max
    winpct[i]+= 1.0/games.size if winner(entries)==pick 
  }
}
best=0;
winpct.each_index{|i|best = i if (winpct[i]>winpct[best])}
puts brains[best][games]

Ich bin nicht sicher, ob ich das richtige Eingabeformat habe - ich bin nicht sicher, wie ich mehrzeilige Befehlszeilenargumente zum Testen unter Windows generieren soll. (Diese Methode scheint auf IDEone zu funktionieren.)

Ahelly
quelle
Ich kann es momentan nicht testen, bin auf der Arbeit und werde erst nach 9.30 Uhr zu Hause sein. Hilft diese SO-Frage bei den mehrzeiligen Argumenten?
Gareth
Gerade getestet und es gibt mir einen Fehler - strategist.rb:48:in 'each': No such file or directory - 42 2 6 10 8 6 5 7 6 1 5 8 3 6 3 4 26 2 10 1 26 8 42 5 3 7 (Errno::ENOENT). Ich werde nach 23:00 Uhr aufhören, neue Einträge zu berücksichtigen, aber ich werde den Wertungslauf etwas verzögern, um Ihnen Zeit zu geben, den Fehler zu untersuchen, wenn Sie möchten.
Gareth
Okay, ich denke das Problem war, dass Sie ARGFanstelle von ARGV hatten. Nachdem Sie diese Änderung vorgenommen haben, wird das Programm 1jedes Mal erraten . Irgendwelche Ideen, was ich tun kann, um es zu beheben?
Gareth
Können Sie diese Zeile nach oben setzen und mir sagen, was sie druckt, wenn Sie die Eingabe für die 2. Runde vornehmen (2 Datenzeilen): p ARGV.map{|l|l};exit (Keine der SO-Antworten auf die Frage, auf die Sie verweisen, oder ähnliche scheinen mir die erwartete Eingabe zu geben)
AShelly 20.02.12
Es wird ["1 2\n3 4\n5 6\n1 2"]für die Testeingabe in der Frage ausgedruckt.
Gareth
2

Perl

Ich dachte mir, dass ich genauso gut das Unvermeidliche betreten könnte. Weitere ernsthafte Einträge folgen in Kürze. Als Bonus verliert dieser Beitrag niemals im Einzelwettbewerb.

print 1
PhiNotPi
quelle
nicht jeden Wettbewerb gewinnen. in einem eins-zu-eins mit einem anderen selbstbewussten, wird es Gleichstand geben
Blazer
Nein! Ich kann nicht glauben, dass ich diesen Fall vergessen habe! Ich werde das reparieren.
PhiNotPi
Eine meiner Schlussfolgerungen, als ich anfing, meinen Eintrag zu entwerfen, ist, dass jeder Bot mindestens 1 / n der Zeit einsenden sollte, um seinen angemessenen Beitrag dazu zu leisten, dass diejenigen, die sich nicht damit abfinden, davonkommen.
Peter Taylor
@ Peter: Keine Sorge, ich habe mich darum gekümmert . :)
Ilmari Karonen
2

JavaScript (node.js)

Zählt, was in der letzten Runde am beliebtesten war, und bietet weniger als eins. In der ersten Runde wird auf 20 gewettet und 3 geboten.

var lastRound = /[^\n]+$/.exec(process.argv[2]);
var numbers = {};
var re = /\d+/g;
var match;

while(match = re.exec(lastRound)) {
    numbers[match] = numbers[match] >>> 0 + 1;
}

var maxKey = -1;

for(var i in numbers) {
    if(maxKey === -1 || numbers[i] > numbers[maxKey]) {
        maxKey = i;
    }
}

if(maxKey == 0) {
    // First round. Bid 3.
    console.log(3);
} else if(maxKey == 1) {
    // Bid 20.
    console.log(20);
} else {
    // Bid one less.
    console.log(maxKey - 1);
}

So rufen Sie auf:

node script.js 'the argument'
Ry-
quelle
Betrachtet man die Ergebnisse des letzten Testlaufs, verhält sich dies nicht wie dokumentiert. Irgendeine Idee warum nicht?
Peter Taylor
1
@ PeterTaylor Ich frage mich, ob es die erste forSchleife ist? Sollte if(i in numbers)sein if(matches[i] in numbers), denkst du?
Gareth
@minitech Nach einigem Stöbern sieht es so aus, als würde die Regex nur mit der einen Nummer der Eingabe übereinstimmen. Sie wissen nicht genug über Javascript oder Nodejs, um sagen zu können, warum. Müssen Sie auch die Eingabe in Zeilenumbrüche aufteilen, um die letzte Runde zu erhalten?
Gareth
@ Gareth: In der Tat ist es. Aktualisiert, aber wenn es ursprünglich besser lief, habe ich nichts dagegen :)
Ry-
Leider wird in jeder Runde ein Fehler ausgegeben, außer in der ersten:node.js:201 throw e; // process.nextTick error, or 'error' event on first tick TypeError: Cannot read property 'length' of null at Object.<anonymous> (minitech1.js:6:23)
Gareth,
2

Python (CopyCat)

Ein weiteres Mal kopiert es die genaue Antwort des letzten Gewinners, falls es eine gab. Es soll sowohl versuchen, andere Bieter zu gewinnen als auch zu blockieren. bietet 5wenn erste Runde, bietet eine Zufallszahl von der vorherigen Runde, wenn es irgendwie keinen Sieger gab

content = sys.argv[1].split('\n')
x = map(int, content[-1].split())
y = []
for each in x:
    if x.count(each) == 1:
        y.append(each)
print min(y) if sum(y) > 0 else random.choice(x) if sum(x) > 0 else 5
Blazer
quelle
2

Python (Joe)

Dies ist keineswegs zum Gewinnen gedacht, aber ich werfe es trotzdem raus, um der Menge etwas Farbe zu verleihen :) Es bietet den Durchschnitt der letzten Runde (Average Joe). Wird genauso aufgerufen wie meine ursprüngliche Antwort (die ich jetzt benenne, weil es so aussieht, als ob all die coolen Kinder das tun, und es hilft, die beiden zu unterscheiden). Wenn Sie eine Runde anfangen, bieten Sie 10.

content = sys.argv[1].split('\n')  
x = map(int, content[-1].split())
print sum(x)/len(x) if sum(x) != 0 else 10

Bearbeiten: Eingabemethode geändert, um der Eingabemethode der Frage zu entsprechen

Blazer
quelle
2

Python (TotalBots)

Ich denke, das wird mein letzter sein, aber wir werden sehen. Es ist von Vorteil zu wissen, wie viele Bots es gibt, indem einfach die Anzahl der konkurrierenden Bots ausgegeben wird. Wenn es also 17 Bots gibt (aktuelle Anzahl der Bots plus dieser), wird ausgegeben17

content = sys.argv[1].split('\n')
print len(content[-1].split())
Blazer
quelle
2

Perl (Gesundheitsinspektor)

print ((((((2)**(2))*((2)**(2)))/((((2)**(2))*(2))*(2)))+((((2)**(2))*(2))/((2)+((2)*(((((2)**(2))+((2)*(2)))+(((2)*(2))/((2)**(2))))**(((2)/(2))/(2)))))))+((((2)-(2))/((((2)**(2))+(2))*((2)+(2))))*(rand(2))))

Ich wette, Sie können erraten, was es tut.

PhiNotPi
quelle
2

C ++ (fundierte Vermutung)

Ich dachte schon, ich hätte die Deadline verpasst, aber dank der Erweiterung kann ich meinen Eintrag immer noch hinzufügen. Dieses Programm kompiliert mit g ++. Das Programm versucht, die Statistik der anderen Einträge zu erraten und die kleinste auszuwählen, die wahrscheinlich von keiner anderen ausgewählt wird.

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <deque>
#include <cstdlib>
#include <ctime>
#include <exception>
#include <stdexcept>

typedef std::vector<int> botvec;
typedef std::vector<botvec> scorevec;

// read all the scores from the given string
// note that this only does minimal error checking
// the result is a vector of vector, each entry of which
// represents one round. That is, the vectors in the vector
// correspond to the lines of the command line argument.
scorevec read_past_scores(char const* scoretext)
{
  scorevec past_scores;

  std::istringstream is(scoretext);
  std::string line;

  scorevec::size_type size = 0;

  while (std::getline(is, line))
  {
    past_scores.push_back(botvec());

    std::istringstream ils(line);
    int i;
    while (ils >> i)
      past_scores.back().push_back(i);
    if (size == 0)
      size = past_scores.back().size();
    else if (past_scores.back().size() != size)
      throw std::runtime_error("invalid score format");
  }
  return past_scores;
}

struct counts { int count[100]; };
struct prob { double p[100]; };

int generate_answer(scorevec& past_scores)
{
  int const number_of_players = past_scores.front().size();
  if (past_scores.front().front() == 0) // initial round
    past_scores.pop_back();

  // Pre-fill the counts to get reasonable probabilities also for
  // insufficient statistics (and the statistics *will* be
  // insufficient!). Bias in favour of small numbers.
  counts initial;
  for (int i = 0; i < 100; ++i)
    initial.count[i] =
      i < number_of_players? 100*(number_of_players-i) : 1;

  std::deque<counts> playercounts(number_of_players, initial);

  // add the actual guesses (with a high factor, to give them high
  // weight against the initial counts)
  for (int i = 0; i < past_scores.size(); ++i)
    for (int j = 0; j < number_of_players; ++j)
      playercounts[j].count[past_scores[i][j]-1]+=5000;

  // drop the own guesses
  playercounts.pop_front();

  // calculate the probabilities corresponding to the counts
  std::vector<prob> playerprobabilities(playercounts.size());
  for (int i = 0; i < playercounts.size(); ++i)
  {
    double sum = 0;
    for (int k = 0; k < 100; ++k)
      sum += playercounts[i].count[k];
    for (int k = 0; k < 100; ++k)
      playerprobabilities[i].p[k] = playercounts[i].count[k]/sum;
  }

  // for each selection, estimate the expected number of other players
  // who will bet on it. Return the first one with an expectation
  // below 1.5.
  for (int i = 0; i < 100; ++i)
  {
    double estimate = 0;
    for (int j = 0; j < number_of_players; ++j)
      estimate += playerprobabilities[j].p[i];
    if (estimate < 1.5)
      return i+1;
  }

  // in the unlikely case that such a choice doesn't exist (meaning
  // there are far more than 100 players), just return 100.
  return 100;
}

int main(int argc, char* argv[])
{
  if (argc < 2)
  {
    std::cerr << "Missing score argument!\n";
    return EXIT_FAILURE;
  }

  try
  {
    scorevec past_scores = read_past_scores(argv[1]);

    std::srand(std::time(0));

    std::cout << generate_answer(past_scores) << std::endl;

    return EXIT_SUCCESS;
  }
  catch(std::exception& e)
  {
    std::cerr << e.what() << "\n";
    return EXIT_FAILURE;
  }
  catch(...)
  {
    std::cerr << "Unknown error\n";
    return EXIT_FAILURE;
  }
}
Celtschk
quelle
2

Perl (Bob)

$_=<>;
INPUT:{

tr/ /,/;
@in = eval;
for(1..$#in){
 $bids[$rnum][$in[$_]]++
}
for(0..$#in){
 $tbids[$rnum][$in[$_]]++
}
$rnum++;
$_=<>;
if($_ ne"\n"){redo INPUT}
}

for(0..100){$pre[$_]=0}

blazer: {
for($r=1;$r<$rnum;$r++){
winner: for($pnt=1;$pnt<101;$pnt++){
        if($tbids[$r][$pnt] == 1){
            if($pnt > 2){
                $winnum[$pnt]++;
            $wins++;
            }
        last winner
        }
}
    }
    if($wins==0){
    $pre[3]++;last blazer
    }
}

CC1: for($pnt=1;$pnt<101;$pnt++){
    if($tbids[$rnum-1][$pnt] == 1){
        $pre[$pnt]++;last CC1
    }
}

CC2: for($pnt=1;$pnt<101;$pnt++){
    if($rnum-2<0){$pre[7]++;last CC2}
    if($tbids[$rnum-2][$pnt] == 1){
        $pre[$pnt]++;last CC2
    }
    if($pnt==100){
    $pre[7]++;last CC2
    }
}

one: {
$pre[1]+=2;
}

two: {
$pre[2]+=2;
}

five: {
$pre[5]+=2;
}

eight: {
$pre[8]+=2;
}

fortytwo: {
$pre[42]++;
}

mueller: {
    $a=($#in+2)/4;
    $pre[int$a]++;
}

schwarzenbeck: {
    $a=($#in+2)/4+1;
    $pre[int$a]++;
}

beckenbauer: {
    $a=($#in+2)/4+2;
    $pre[int$a]++;
}

totalbots: {
    $pre[$#in+1]++;
}

joe: {
$sum=0;
    for(1..100){
    $sum+=$_*$tbids[$rnum-1][$_];
}
    $average=$sum/($#in+1);
    if($average==0){$average=10};
    $pre[$average]++;
}

node: {
$max=0;$maxloc=0;
for(1..100){
    if($tbids[$rnum-1][$_]>$max){$max=$tbids[$rnum-1][$_];$maxloc=$_}
}
$maxloc--;
#if($maxloc==0){
$maxloc=20;
#}
if($rnum==1){$maxloc=3}
    $pre[$maxloc]++;
}
choice: for(1..100){
    if($pre[$_]==1){ 
$count++;
    if($count==3){print; last choice}
}
    if($_==100){print"98"}
}

Informationen zum Aufrufen finden Sie unter "Bob".

PhiNotPi
quelle
Das ist eine sehr rekursive Anleitung zur Anrufung ;-)
Gareth
Es gibt tatsächlich eine Kette von Logik: Alice beschreibt, wie sie Eingaben aufnimmt. Eva erwähnt, dass sie die gleichen Eingaben wie Alice nimmt. Eve erwähnt auch, dass sie die gleichen Eingaben wie Bob nimmt. Somit verwendet Bob dasselbe Eingabeformat wie Alice, das beschrieben wird.
PhiNotPi
2

Perl (Alice)

$_=<>;
INPUT:{

tr/ /,/;
@in = eval;
for(1..$#in){
 $bids[$rnum][$in[$_]]++
}
for(0..$#in){
 $tbids[$rnum][$in[$_]]++
}
$rnum++;
$_=<>;
if($_ ne"\n"){redo INPUT}
}

for(0..100){$pre[$_]=0}

blazer: {
for($r=1;$r<$rnum;$r++){
winner: for($pnt=1;$pnt<101;$pnt++){
        if($tbids[$r][$pnt] == 1){
            if($pnt > 2){
                $winnum[$pnt]++;
            $wins++;
            }
        last winner
        }
}
    }
    if($wins==0){
    $pre[3]++;last blazer
    }
}

CC1: for($pnt=1;$pnt<101;$pnt++){
    if($tbids[$rnum-1][$pnt] == 1){
        $pre[$pnt]++;last CC1
    }
}

CC2: for($pnt=1;$pnt<101;$pnt++){
    if($rnum-2<0){$pre[7]++;last CC2}
    if($tbids[$rnum-2][$pnt] == 1){
        $pre[$pnt]++;last CC2
    }
    if($pnt==100){
    $pre[7]++;last CC2
    }
}

one: {
$pre[1]+=2;
}

two: {
$pre[2]+=2;
}

five: {
$pre[5]+=2;
}

eight: {
$pre[8]+=2;
}

fortytwo: {
$pre[42]++;
}

mueller: {
    $a=($#in+2)/4;
    $pre[int$a]++;
}

schwarzenbeck: {
    $a=($#in+2)/4+1;
    $pre[int$a]++;
}

beckenbauer: {
    $a=($#in+2)/4+2;
    $pre[int$a]++;
}

totalbots: {
    $pre[$#in+1]++;
}

joe: {
$sum=0;
    for(1..100){
    $sum+=$_*$tbids[$rnum-1][$_];
}
    $average=$sum/($#in+1);
    if($average==0){$average=10};
    $pre[$average]++;
}

node: {
$max=0;$maxloc=0;
for(1..100){
    if($tbids[$rnum-1][$_]>$max){$max=$tbids[$rnum-1][$_];$maxloc=$_}
}
$maxloc--;
#if($maxloc==0){
$maxloc=20;
#}
if($rnum==1){$maxloc=3}
    $pre[$maxloc]++;
}
choice: for(1..100){
    if($pre[$_]==1){ 
$count++;
    if($count==2){print; last choice}
}
    if($_==100){print"99"}
}

Übernimmt Eingaben ähnlich wie bei meinen anderen Bots.

perl Alice.plx
1 4 3 12
3 2 4 11
[blank line]
PhiNotPi
quelle
2

Perl (Eva)

Ich habe diesen Eintrag komplett überarbeitet, um den Weg für meine anderen Bots zu ebnen.

$_=<>;
INPUT:{

tr/ /,/;
@in = eval;
for(1..$#in){
 $bids[$rnum][$in[$_]]++
}
for(0..$#in){
 $tbids[$rnum][$in[$_]]++
}
$rnum++;
$_=<>;
if($_ ne"\n"){redo INPUT}
}

for(0..100){$pre[$_]=0}

blazer: {
for($r=1;$r<$rnum;$r++){
winner: for($pnt=1;$pnt<101;$pnt++){
        if($tbids[$r][$pnt] == 1){
            if($pnt > 2){
                $winnum[$pnt]++;
            $wins++;
            }
        last winner
        }
}
    }
    if($wins==0){
    $pre[3]++;last blazer
    }
}

CC1: for($pnt=1;$pnt<101;$pnt++){
    if($tbids[$rnum-1][$pnt] == 1){
        $pre[$pnt]++;last CC1
    }
}

CC2: for($pnt=1;$pnt<101;$pnt++){
    if($rnum-2<0){$pre[7]++;last CC2}
    if($tbids[$rnum-2][$pnt] == 1){
        $pre[$pnt]++;last CC2
    }
    if($pnt==100){
    $pre[7]++;last CC2
    }
}

one: {
$pre[1]+=2;
}

two: {
$pre[2]+=2;
}

five: {
$pre[5]+=2;
}

eight: {
$pre[8]+=2;
}

fortytwo: {
$pre[42]++;
}

mueller: {
    $a=($#in+2)/4;
    $pre[int$a]++;
}

schwarzenbeck: {
    $a=($#in+2)/4+1;
    $pre[int$a]++;
}

beckenbauer: {
    $a=($#in+2)/4+2;
    $pre[int$a]++;
}

totalbots: {
    $pre[$#in+1]++;
}

joe: {
$sum=0;
    for(1..100){
    $sum+=$_*$tbids[$rnum-1][$_];
}
    $average=$sum/($#in+1);
    if($average==0){$average=10};
    $pre[$average]++;
}

node: {
$max=0;$maxloc=0;
for(1..100){
    if($tbids[$rnum-1][$_]>$max){$max=$tbids[$rnum-1][$_];$maxloc=$_}
}
$maxloc--;
#if($maxloc==0){
$maxloc=20;
#}
if($rnum==1){$maxloc=3}
    $pre[$maxloc]++;
}
choice: for(1..100){
    if($pre[$_]==1){ 
$count++;
    if($count==1){print; last choice}
}
    if($_==100){print"100"}
}

Nimmt ein Eingabeformat an: das gleiche wie "Bob" und "Alice".

PhiNotPi
quelle
1

Brainfuck

Um aus der Herausforderung zu zitieren:

"Sie können so viele Bots eingeben, wie Sie möchten. Wenn also jemand einen Bot eingibt, der nur raten kann 1, können Sie einen anderen eingeben, der dasselbe tut, um ihn unbrauchbar zu machen."

Nun, da PhiNotPi eines eingegeben hat , lass mich ein anderes eingeben. Nur um anders zu sein, mache ich es in Brainfuck:

+++[->++++<]>[-<++++>]<+.

Natürlich ist es jetzt, da Wetten 1 nicht länger eine praktikable Strategie ist, naheliegend, stattdessen 2 zu setzen ...

Bearbeiten: Antwort in zwei Teile pro Kommentar teilen, beide Programme in interessanteren Sprachen umschreiben.

Ilmari Karonen
quelle
Erstens bitte ein Eintrag pro Antwort. Zweitens weiß ich, dass jemand 100 Antworten posten kann, indem er eine der Ziffern von 1 bis 100 druckt, um zu gewährleisten, dass er nicht verliert. Ebenso könnte jemand anderes genau das Gleiche tun, was bedeutet, dass niemand gewinnt. In einem Fußballspiel könnten alle 11 Spieler auf der Torlinie stehen, um zu gewährleisten, dass die andere Mannschaft kein Tor erzielt. Das passiert normalerweise nie so, weil es ein großes Spiel wäre, wenn sie es tun würden.
Gareth
Drittens hätte dieser Einwand eigentlich im Sandkasten lauten müssen - schließlich ist das sein Zweck.
Gareth
@Gareth: OK, ich habe die Antwort in zwei Teile geteilt. Was die Plausibilität der Einträge anbelangt, so haben Sie selbst vorgeschlagen, dass jemand anderes das Gleiche tun könnte, um dem entgegenzuwirken, wenn jemand "ein Selbstvertrauen" unterbreiten würde. An diesem Punkt natürlich einreichen „twosconfident“ macht genauso viel Sinn wie die Einreichung „onesconfident“ hat in erster Linie, so ...
Ilmari Karonen
1
Das Schöne daran ist, dass ich jetzt meinen selbstsicheren Eintrag nicht löschen kann, ohne dass dieser Eintrag gewinnt.
PhiNotPi
1
@ Peter: Warum denkst du so? Angesichts der Tatsache, dass sowohl meine als auch PhiNotPis Programme im Rennen sind, gibt es keinen Grund für andere, ein solches Programm einzureichen jemals 1 setzt (wenn sie wollen, dass dieses Programm gewinnt, das heißt).
Ilmari Karonen
1

Mueller (Scala)

object Mueller extends App {
  println ((args(0).split('\n')(0).split(' ').length+1)/4)
}

Wenn Sie Schwarzenbeck und Beckenbauer kennen, haben Sie sicherlich Müller erwartet. Hier ist er. Er wird viel von Beckenbauer und Schwarzenbeck profitieren und soll gewinnen.

Details zum Laufen und Kompilieren: Siehe Schwarzenbeck

Jetzt näher am Ziel.

Benutzer unbekannt
quelle
1

Beckenbauer (Scala)

object Beckenbauer extends App {
  println ((args(0).split('\n')(0).split(' ').length+1)/4+2)
}

Mit Hilfe von Schwarzenbeck soll Beckenbauer einige Tore schießen. Ohne Schwarzenbeck ist er nichts.

Details zum Laufen und Kompilieren: Siehe [Schwarzenbeck] [1]

Edit: Spiele jetzt auch tiefer im Raum.

Benutzer unbekannt
quelle
1

Batch-Scripting

echo 5

Mein Beitrag gibt jedes Mal 5 als Antwort ;-)

mellamokb
quelle
1

Eight.bat

echo 8

Eine andere einfache Antwort, gibt jedes Mal 8.

mellamokb
quelle
1

FivesCancel (PHP)

Bricht die "always 5" -Lösung von mellamokb ab.

5
Ry-
quelle
1

EightsCancel (PHP)

Bricht die "always 8" -Lösung von mellamokb ab. Entschuldigung, mellamokb!

8
Ry-
quelle
Hier geht es wieder los, Wettbewerb: P
mellamokb
1

Python 2.7 - Copycat2

Kopiert die zweite letzte Runde des Gewinner. Ach nein! sonst Ausgänge 7.

import sys
content = sys.argv[1].split('\n')
x = map(int, content[-2].split()) if len(content) > 1 else [7]
y = []
for each in x:
    if x.count(each) == 1:
        y.append(each)
print min(y) if sum(y) > 0 else random.choice(x) if sum(x) > 0 else 7
Blazer
quelle
1

Shell-Skript (Deep Thought)

OK, damit ich eine kleine zweite Chance bekomme, hier ist ein weiterer Eintrag, diesmal ein Shell-Skript (sollte mit jeder Shell funktionieren). Dies gibt immer die Antwort auf die Frage nach dem Leben, dem Universum und allem.

echo 42

Eigentlich ist dieser Algorithmus nicht ganz korrekt, da ich die Verzögerung von 7,5 Millionen Jahren weggelassen habe. :-)

Celtschk
quelle
Für den heutigen Testlauf ist es zu spät. Tut mir leid, aber morgen früh mache ich noch einen.
Gareth
1

dirichlet.c

#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>

main(int argc, char* argv[])
{
    int handle;
    char *str;
    int32_t bits, val, n = 0;

    if (argc) {
        for (str = argv[1]; *str; str++)
            if (*str == 32) n++;
            else if (*str == 10) break;
    }

    n /= 2;
    if (n > 99) n = 99;

    handle = open("/dev/urandom", O_RDONLY);
    do {
        read(handle, &bits, sizeof bits);
        bits &= 0x7fffffff;
        val = bits % n;
    } while (bits - val + (n-1) < 0);
    close(handle);

    printf("%d", 2 + val);
}

Ich denke, das geht durch zufällige Bits zu schnell zu verwenden /dev/random , wie viel ich bevorzugen würde. Wenn jemand es unter Windows testen möchte, muss er es selbst portieren, da ich keinen Zugriff auf eine Windows-Box mit einem C-Compiler habe.

Begründung

Ich wollte die Logik dahinter nicht erklären, bevor das Turnier vorbei war, aber jetzt, da der Gewinner bekannt gegeben wurde, denke ich, ist es Zeit.

Nach dem Pigeon-Hole-Prinzip (alias Dirichlet-Prinzip, daher der Name des Bots) gibt es bei N konkurrierenden Bots eine Zahl w in [1..1 + N / 2], die entweder gewonnen hat oder gewonnen hätte, wenn ausgewählt. Ich komme daher zu dem Schluss, dass die optimale Strategie keine Zahlen größer als 1+ N / 2 auswählt . Aber wenn N gerade ist, erzeugt die Auswahl von 1+ N / 2 einen kleineren Gewinnschlitz. Daher sind die Schlitze, die es wert sind, ausgewählt zu werden, [1 .. ( N +1) / 2].

Es bleibt die Frage, wie ein Steckplatz ausgewählt werden soll. Bei einer kleinen Anzahl von Bots habe ich festgestellt, dass es ein Nash-Gleichgewicht gibt, wenn jeder Bot unter den Kandidaten einheitlich auswählt, und ich bin fest davon überzeugt, dass dies auch weiterhin der Fall sein wird.

Die geringfügige Abweichung der Strategie dieses Bots von der theoretischen ist einfach Metagaming.

Peter Taylor
quelle