Aukcja najniższych unikalnych ofert

22

Dzięki za wszystkie zgłoszenia, termin już minął, a ostateczne wyniki są na końcu pytania.
Gratulacje dla PhiNotPi za dość kompleksowe zwycięstwo.

Jest to wyzwanie na szczycie , którego celem jest stworzenie programu, który wygrywa częściej niż którykolwiek z jego przeciwników w aukcji o najniższej możliwej ofercie.

Wkład

Jako dane wejściowe program otrzyma licytację wszystkich poprzednich rund, jedną rundę na linię, wszystkie oferty oddzielone spacjami w następujący sposób:

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

Każda kolumna danych wejściowych reprezentuje licytację jednego bota. Pierwsza kolumna to oferty programu odbierającego, podczas gdy reszta jest losowo generowana. Podziękowania dla hammara i Petera Taylora za ich wkład.

Dane wejściowe są dostarczane jako jedyny argument wiersza polecenia (wielu wierszy) do programu:

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

Oznacza to, że Twój program będzie musiał być uruchamiany z wiersza poleceń. Podaj przykład wywołania jako część swojej odpowiedzi.

W pierwszej rundzie tylko w celu poinformowania Cię o liczbie botów, z którymi walczysz, dane wejściowe będą równe 0s - jeden dla każdego bota.

Wydajność

Twój program powinien wypisać swoją ofertę jako liczbę całkowitą z zakresu od 1 do 100 (włącznie).

Program strzelców

To jest mój program oceniania - wszelkie sugestie dotyczące dodatków, ulepszeń lub poprawek błędów byłyby mile widziane.

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

Testuj graczy

Pewny siebie Zawsze licytuje 1.

#include <stdio.h>

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

Random 100 losowych ofert w całym zakresie

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

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

Losowo 20 ofert losowych od 1 do 20

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

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

Losowe 5 ofert losowych od 1 do 5

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

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

Przykładowy przebieg:

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

Gracze ci służą wyłącznie do testowania. NIE zostaną one uwzględnione w konkursie. Możesz wprowadzić tyle botów, ile chcesz, więc jeśli ktoś wejdzie do bota, który tylko zgaduje 1, możesz wprowadzić innego bota, który robi to samo, aby uczynić go bezużytecznym.

Zwycięzca

Wygrywającym botem w każdej rundzie jest ta, która daje najniższą unikalną ofertę. Biorąc pod uwagę rundę, w której składane są następujące oferty: 1 1 3 5 2 3 6 3 2 8 7zwycięzcą będzie bot, który licytuje, 5ponieważ 1s, 2s i 3s nie są unikalne.

Zwycięzcą konkursu będzie program, który wygrywa najwięcej razy po 100 rundach. W przypadku remisu suma zwycięskich ofert zostanie wykorzystana jako remis, aw przypadku remisu, najniższa wygrana oferta zostanie wykorzystana jako remis. Te współczynniki punktacji są generowane przez program punktacji.

Uruchomię program oceniania we wszystkich programach roboczych, które zostały wprowadzone za 2 tygodnie od dzisiaj ( 18 lutego został przedłużony do 23:00 (GMT) 20 lutego ). Głosuję za wszystkimi pracami i zaakceptuję zwycięzcę mojego wyścigu punktacji.

Końcowy przebieg punktacji

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
źródło
1
Hmm ... przy zachowanych regułach, naprawdę mogłem zepsuć grę, wprowadzając 100 programów, z których każdy zawsze licytuje określoną liczbę.
Ilmari Karonen
1
Czy możesz powiedzieć dwa zdania, w jaki sposób wybierany jest zwycięski bot? Nie rozumiem
użytkownik nieznany
@IlmariKaronen To prawda, możesz. Ale ufam, że ludzie tego nie zrobią. Podejrzewam, że mógłbym ograniczyć liczbę wpisów na osobę, ale myślę, że skorzystam z tego tylko wtedy, gdy pojawią się jakieś spoilery.
Gareth,
@ userunknown Próbowałem wyjaśnić, jak działają rundy aukcji.
Gareth,
1
@PhiNotPi: Nie czuj się winny. Wygrałeś zgodnie z zasadami.
Steven Rumbalski

Odpowiedzi:

9

Perl

Tym razem trochę bardziej się starałem. To naprawdę prosta, złożona strategia, ale stworzyłem ramy dla ekspansji.

Edycja: Zakończ ponawianie. Ta rzecz jest w nim do wygrania.

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

Ten program pobiera dane po jednej linii, po której następują dwie nowe linie:

perl PhiNotPi2.plx
1 2 3 3 2
2 1 3 1 3
2 1 1 1 3
[empty line]
PhiNotPi
źródło
Ok, to prowadzi metagaming do skrajności.
Peter Taylor
@petertaylor Czy idę za daleko poza linię? Czy powinienem wrócić do oryginału?
PhiNotPi
2
Jest to strona znana osądowi prawników - jest całkowicie uczciwa. Ale dochodzę do wniosku, że mechanizm wymiany stosów może nie być najlepszy w przypadku zawodów króla wzgórza.
Peter Taylor,
Doszedłem również do tego wniosku. Musimy stworzyć metodę ukrywania botów przed przyszłymi konkursami. Z tego co wiem, ktoś gra teraz przeciwko moim botom.
PhiNotPi
Lol, to był mój pomysł: P. Ponieważ już zaimplementowałeś i czuję się leniwy, pozwolę ci to mieć :) Pamiętaj, że jedynym rodzajem wpisu, którego nie można łatwo pokonać, są te, które implementują losowość
mellamokb
8

Szef kuchni

Ponieważ zawsze obstawianie 1 jest teraz strategią przegraną , oczywiste jest, aby zawsze obstawiać 2 . Więc pozwól mi to zrobić. Aby ten nudny wpis był nieco bardziej interesujący, postanowiłem napisać go w Chef :

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.

Jako bonus, program faktycznie działa mniej więcej tak jak prawdziwa - choć trywialna - recepta, nawet jeśli czyta się tak, jakby pisarz był trochę upieczony. Gramatyka szefa kuchni sprawia, że ​​dość trudno jest napisać coś, co wymaga czegoś bardziej skomplikowanego niż mieszanie rzeczy w misce i pieczenie, i nadal działa jako program i jako przepis, zwłaszcza jeśli którykolwiek z czasowników, którego chce się użyć są nawet nieco nieregularne (np. „smażyć” → „smażone”).

Edytować: Zmieniono przepis z jajka sadzonego na smażone - dzięki Blazer za sugestię! Czas i temperatura gotowania należy traktować wyłącznie jako wskazówkę; Sam jeszcze nie wypróbowałem przepisu, więc nie mogę ręczyć za ich dokładność.

Ilmari Karonen
źródło
Myślę, że to daje wynik 1: patrz mój komentarz na codegolf.stackexchange.com/a/4851 .
msh210
Wyprowadza 2, przynajmniej używając interpretera Acme :: Chef . Ostatnia pętla służy tylko zaciemnieniu, aby goście nie musieli jeść jajek na surowo.
Ilmari Karonen
Ach, racja, tęskniłem za faktem, że jajka były już w naczyniu do pieczenia i że nie jest to zmniejszane.
msh210
2
Nazywasz to shirred eggs, co faktycznie robi się w naczyniu do pieczenia, a to sprawiłoby, że przepis byłby rzeczywistym obowiązującym przepisem kulinarnym i gramatycznie poprawnym. shirr the eggs. shirr the eggs until shirred.bzdura za to, że mam wykształcenie kulinarne! :)
Blazer
1
czas / temperatura gotowania wydaje się być odpowiednia :). oczywiście zawsze używaj ich tylko jako wskazówek, ponieważ to szef kuchni decyduje, czy coś jest zrobione, czy nie, a nie sam czas / temperatura!
Blazer
4

Python (2.6)

Niezwykle proste, ale wciąż jestem ciekawy, jak to się sprawdzi w porównaniu do innych podejść.

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)

Wystarczy wprowadzić oferty za pomocą standardowego wejścia, np python testbid.py < bids.txt.

EDYCJA : zmieniono dla „pierwszej rundy wszystkie zera”

EDYCJA : trochę zmieniłem „magiczne liczby” (drugi raz)

ChristopheD
źródło
1
nie powinno m = random.choice(1,2,2,3,3,3)być m = random.choice([1,2,2,3,3,3])?
Blazer
Zgłoszył błąd, w którym Blazer powiedział, że może. Do testu wprowadziłem nawiasy kwadratowe i wydaje się, że zadziałały.
Gareth,
@ Blazer: tak, absolutnie (mała literówka z mojej strony). Dziękujemy za powiadomienie.
ChristopheD
4

Python (Blazer)

Ten bot analizuje poprzednie rundy i zapisuje liczby, które wygrywają. Dlatego wygrane liczby, które pojawiają się częściej, będą miały większą szansę na wybranie. Następnie losowo wybierze liczby ze zwycięskich liczb (innych niż 1 lub 2). zamiast tego wybierze 2 3, jeśli jest to pierwsza runda.

Wejście odczytywane jest po jednym wierszu na raz. wystarczy wpisać pusty wiersz, aby przestać akceptować dane wejściowe

Sztuką jest po prostu wkleić (automatycznie akceptuje każdą linię z \ n wewnątrz wklejania) i nacisnąć dwukrotnie klawisz Enter

Możesz teraz po prostu uruchomić skrypt z nazwą pliku w wierszu polecenia:

python bidding.py bidding.txt

plik powinien wyglądać następująco:

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)

edycja: dodano or sum(rounds) == 0 aby zrekompensować ostatnią zmianę zera w pierwszej rundzie

edit: naprawiono problemy w komentarzach, umożliwiało także otrzymywanie danych wejściowych z nazwy pliku i nigdy więcej nie wybiera „2”, ponieważ konkurencja również to wyeliminowała. działa albo z zerami jako początkowym wejściem, albo w ogóle nie ma danych w pliku

edit2: zapomniałem min ()

edit3: zmieniono dane wejściowe, aby dopasować je do potrzeb pytania

Blezer
źródło
Powoduje mały problem z strzelcem - muszę nacisnąć Enter, aby uzyskać wynik dla każdej rundy. Nie ma większego problemu dla moich 10 rund testowych, ale może być kłopotem dla 100 rund.
Gareth
@Gareth, zawiń go w skrypcie bash. echo "$@" | python bidding.pypowinien wykonać pracę.
Peter Taylor,
Próbowałem tego, jak sugerował Peter, ale TypeError: unsupported operand type(s) for +: 'int' and 'list'pojawia się błąd dla linii 23. Używam Python 2.6.1, czy to jest problem? czy potrzebuję nowszej wersji? Ten sam problem pojawia się bez użycia skryptu bash.
Gareth,
@Gareth pomógłbym, gdybym to zrobił, więc dane wejściowe są przesyłane strumieniowo z sys.argv [1] z nazwą pliku?
Blazer
@ Blazer Nie jestem pewien, że to jest problem. Sam wywołuję program z wiersza poleceń, korzystając z przykładowego wywołania i otrzymując błąd, który podałem powyżej. Czy jest tam coś niezgodnego z Python 2.6.1?
Gareth
3

Schwarzenbeck (Scala)

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

Schwarzenbeck nie powinien strzelać goli. Jest sprzątaczem Beckenbauera, który nastąpi wkrótce. :)

Aby go użyć, potrzebujesz kompilatora i skompiluj go

scalac Schwarzenbeck.scala 

Następnie możesz go uruchomić:

scala Schwarzenbeck 'your ar-
gu-
ment' 

Edycja: Dalsze korekty.

nieznany użytkownik
źródło
1
Biorąc pod uwagę, że Schwarzenbeck nie miał strzelać goli, powiedziałbym, że to całkowicie nie powiodło się :-)
celtschk
Tak, miałem dylemat: stworzyłem linię 3 graczy i spodziewałem się, że Müller zdobędzie najwięcej punktów, ale ze strategicznej pozycji Schwarzenbeck wyznaczył najwyższą linię obrony. Metapher w piłce nożnej zawiódł, ponieważ moja linia obrony strzeliła gole. :)
użytkownik nieznany
3

Strateg (Ruby)

Realizuje setki prostych strategii: dla każdej rundy wybiera tę, która wygrałaby większość poprzednich rund:

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]

Nie jestem pewien, czy poprawnie wprowadziłem format wejściowy - nie jestem pewien, jak wygenerować wieloliniowe argumenty wiersza poleceń do testowania go w systemie Windows. (Ta metoda wydaje się działać na IDEone.)

AShelly
źródło
Nie mogę tego teraz przetestować, jestem w pracy i nie wrócę do domu przed godziną 9.30 (GMT). Czy to pytanie SO pomaga w argumentach wieloliniowych?
Gareth,
Właśnie to przetestowałem i daje mi błąd 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). Przestanę rozważać nowe wpisy po 23:00, ale nieco opóźnię przebieg punktacji, aby dać ci czas na sprawdzenie błędu, jeśli chcesz.
Gareth,
Okej, myślę, że problem polegał na tym, że miałeś ARGFzamiast ARGV. Po dokonaniu tej zmiany program zgaduje1 każdym razem. Jakieś pomysły, co mogę zrobić, aby to naprawić?
Gareth,
Czy możesz dodać ten wiersz do góry i powiedzieć mi, co drukuje, podając dane wejściowe 2. rundy (2 linie danych): p ARGV.map{|l|l};exit (Żadna z SO odpowiedzi na pytanie, do których się odwołujesz, lub podobne nie wydają się dawać oczekiwanych danych wejściowych)
AShelly
Drukuje się ["1 2\n3 4\n5 6\n1 2"]dla danych wejściowych testu w pytaniu.
Gareth,
2

Perl

Uznałem, że równie dobrze mogę wejść w nieuniknione. Więcej poważnych wpisów już wkrótce. Jako bonus, ten wpis nigdy nie przegra w zawodach jeden na jednego.

print 1
PhiNotPi
źródło
nie wygrywać w każdym konkursie. w pojedynku z innymi pewnymi siebie, będzie remis
Blazer
Nie! Nie mogę uwierzyć, że zapomniałem o tej sprawie! Naprawię to.
PhiNotPi
Jednym z moich wniosków, kiedy zacząłem projektować swój wpis, jest to, że każdy bot powinien zgłosić 1 co najmniej 1 / n czasu, aby zrobić swój uczciwy udział w zapobieganiu ucieczce pewnej osoby.
Peter Taylor,
@Peter: Nie martw się, zająłem się tym . :)
Ilmari Karonen
2

JavaScript (node.js)

Liczy najbardziej popularną ostatnią rundę i licytuje o jedną mniej, zwiększając do 20 i licytując 3 w pierwszej rundzie.

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

Jak wywołać:

node script.js 'the argument'
Ry-
źródło
Patrząc na wyniki ostatniego uruchomienia testowego, nie działa to tak, jak zostało to udokumentowane. Masz pomysł, dlaczego nie?
Peter Taylor,
1
@PeterTaylor Zastanawiam się, czy to pierwsza forpętla? Powinien if(i in numbers)być if(matches[i] in numbers)o tym sądzisz?
Gareth,
@minitech Po krótkiej analizie wygląda na to, że regex pasuje tylko do jednej liczby danych wejściowych - nie wiem wystarczająco dużo o javascript lub Nodejs, aby móc jednak powiedzieć dlaczego. Czy musisz także podzielić dane wejściowe na nowe wiersze, aby uzyskać ostatnią rundę?
Gareth,
@Gareth: Rzeczywiście tak jest. Zaktualizowano, chociaż jeśli pierwotnie działał lepiej, to nie mam nic przeciwko :)
Ry-
Niestety generuje błąd dla każdej rundy, z wyjątkiem pierwszej teraz: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)

Jeszcze raz, tym razem kopiuje dokładną odpowiedź, jaką miał ostatni zwycięzca, jeśli taka była. Jest przeznaczony zarówno do wygrania, jak i blokowania innych licytujących. licytuje w 5pierwszej rundzie, licytuje losową liczbę z poprzedniej rundy, jeśli jakoś nie było zwycięzcy

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
Blezer
źródło
2

Python (Joe)

Nie ma to na celu wygrania, ale i tak go wyrzucam, aby dodać trochę koloru tłumowi :) Licytuje średnią z ostatniej rundy (Przeciętny Joe). Wywołałem to samo co moja pierwotna odpowiedź (którą teraz wymienię, ponieważ wygląda na to, że robią to wszystkie fajne dzieciaki i pomaga to rozróżnić). jeśli zaczyna rundę, licytuje 10.

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

edit: zmieniono metodę wprowadzania, aby dopasować metodę wprowadzania pytania

Blezer
źródło
2

Python (TotalBots)

Myślę, że ten będzie mój ostatni, ale zobaczymy. Zaletą jest to, że wiemy, ile jest botów, po prostu wypisując liczbę konkurujących botów, więc jeśli jest 17 botów (aktualna liczba botów plus ten jeden), wyświetli17

content = sys.argv[1].split('\n')
print len(content[-1].split())
Blezer
źródło
2

Perl (inspektor zdrowia)

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

Założę się, że możesz zgadnąć, co to robi.

PhiNotPi
źródło
2

C ++ (wykształcone zgadywanie)

Już myślałem, że nie dotrzymam terminu, ale dzięki przedłużeniu nadal mogę dodać swój wpis. Ten program kompiluje się z g ++. Program próbuje odgadnąć statystyki pozostałych wpisów i wybrać najmniejszą, która prawdopodobnie nie zostanie wybrana przez żadną inną.

#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
źródło
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"}
}

Zobacz „Bob”, aby dowiedzieć się, jak wywołać.

PhiNotPi
źródło
To bardzo rekurencyjny przewodnik po wywołaniu ;-)
Gareth
Wprowadzono łańcuch logiki: Alice opisuje, w jaki sposób bierze wkład. Eve wspomina, że ​​pobiera dane tak samo jak Alice. Ewa wspomina również, że bierze dane tak samo jak Bob. Dlatego Bob przyjmuje ten sam format wejściowy, co Alice, który jest opisany.
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"}
}

Pobiera dane wejściowe podobne do moich innych botów.

perl Alice.plx
1 4 3 12
3 2 4 11
[blank line]
PhiNotPi
źródło
2

Perl (Ewa)

Całkowicie zmieniłem ten wpis, aby utorować drogę moim innym botom.

$_=<>;
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"}
}

Przyjmuje jeden format wejściowy: taki sam jak „Bob” i „Alice”.

PhiNotPi
źródło
1

Brainfuck

Cytat z wyzwania:

„Możesz wprowadzić tyle botów, ile chcesz, więc jeśli ktoś wejdzie do bota, który tylko zgaduje 1, możesz wprowadzić innego bota, który robi to samo, aby uczynić go bezużytecznym”.

Cóż, ponieważ PhiNotPi wszedł jeden , pozwól mi wprowadzić inny. Żeby być innym, zrobię to w Brainfuck:

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

Oczywiście teraz, gdy obstawianie 1 nie jest już wykonalną strategią, oczywistą rzeczą do zrobienia jest obstawienie 2 zamiast tego ...

Edycja: Podziel odpowiedź na dwa dla każdego komentarza, przepisaj oba programy w bardziej interesujących językach.

Ilmari Karonen
źródło
Po pierwsze, proszę podać jeden wpis na odpowiedź. Po drugie, wiem, że ktoś może zamieścić 100 odpowiedzi, drukując jedną z cyfr od 1 do 100, aby zagwarantować, że nie zostanie stracony - podobnie ktoś inny może zrobić dokładnie to samo, co oznacza, że ​​nikt nie wygra. W meczu piłki nożnej (piłka nożna) wszyscy 11 graczy może stać na linii bramkowej, aby zagwarantować, że druga drużyna nie zdobędzie gola. Zwykle tak się nie dzieje, bo gdyby tak zrobili, byłaby to duża gra?
Gareth,
Po trzecie, zarzut ten powinien był zostać podniesiony w piaskownicy - przecież taki jest jego cel.
Gareth,
@Gareth: OK, podzieliłem odpowiedź na dwie części. Jeśli chodzi o racjonalność wpisów, sam zasugerowałeś, że jeśli ktoś miałby przesłać „oneconfident”, ktoś inny mógłby zrobić to samo, aby temu przeciwdziałać. W tym momencie oczywiście przesłanie „pewnej siebie” ma tak samo sens, jak przesłanie „pewnej siebie” w pierwszej kolejności, więc ...
Ilmari Karonen
1
Przyjemne jest to, że nie mogę teraz usunąć swojego wpisu, który jest pewny siebie, bez umożliwienia mu wygrania.
PhiNotPi
1
@Peter: Dlaczego tak uważasz? Biorąc pod uwagę, że zarówno mój, jak i PhiNotPi, biorą udział w wyścigu, nikt nie ma powodu, aby przesyłać program, który kiedykolwiek obstawia 1 (jeśli chcą wygrać ten program).
Ilmari Karonen,
1

Mueller (Scala)

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

Jeśli znasz Schwarzenbecka i Beckenbauera, na pewno spodziewałeś się Muellera. Tutaj jest. Dużo skorzysta z Beckenbauera i Schwarzenbecka i ma wygrać.

Szczegóły dotyczące uruchamiania i kompilacji: patrz Schwarzenbeck

Teraz bliżej celu.

nieznany użytkownik
źródło
1

Beckenbauer (Scala)

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

Z pomocą Schwarzenbecka Beckenbauer ma strzelać gole. Bez Schwarzenbecka jest niczym.

Szczegółowe informacje na temat uruchamiania i kompilacji: patrz [Schwarzenbeck] [1]

Edycja: Teraz też grasz głębiej w pokoju.

nieznany użytkownik
źródło
1

Skrypty wsadowe

echo 5

Moje zgłoszenie daje 5 jako odpowiedź za każdym razem ;-)

mellamokb
źródło
1

Ósmy nietoperz

echo 8

Kolejna prosta odpowiedź, daje 8 za każdym razem.

mellamokb
źródło
1

FivesCancel (PHP)

Anuluje rozwiązanie „always 5” mellamokb.

5
Ry-
źródło
1

EightsCancel (PHP)

Anuluje rozwiązanie „always 8” mellamokb. Przepraszam, mellamokb!

8
Ry-
źródło
Znowu zaczynamy, konkurs: P
mellamokb
1

Python 2.7 - Copycat2

Kopiuje zwycięzcę drugiej ostatniej rundy. O nie! w przeciwnym razie wyjścia 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
Blezer
źródło
1

Skrypt powłoki (głęboka myśl)

OK, aby uzyskać drugą szansę, oto kolejny wpis, tym razem skrypt powłoki (powinien działać z każdą powłoką). To zawsze daje odpowiedź na pytanie o życie, wszechświat i wszystko.

echo 42

W rzeczywistości ten algorytm nie jest całkowicie poprawny, ponieważ pominąłem opóźnienie 7,5 miliona lat. :-)

celtschk
źródło
Przepraszam za późno na dzisiejszy test, ale zrobię coś innego rano.
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);
}

Myślę, że przechodzi przez losowe bity zbyt szybko, by je użyć /dev/random , jakkolwiek wolałbym. Jeśli ktoś chce przetestować go w systemie Windows, musisz go sam portować, ponieważ nie mam dostępu do okna systemu Windows z kompilatorem C.

Racjonalne uzasadnienie

Nie chciałem wyjaśniać logiki stojącej za tym przed zakończeniem turnieju, ale teraz, kiedy zwycięzca został ogłoszony, myślę, że już czas.

Zgodnie z zasadą gołębnika (zwaną także zasadą Dirichleta, stąd nazwa bota), jeśli istnieje N konkurujących botów, wówczas liczba w w [1..1 + N / 2] wygrywa lub wygrałaby, gdyby wybrany. Stwierdzam zatem, że optymalna strategia nie wybierze liczb większych niż 1+ N / 2. Ale jeśli N jest parzyste, wybranie 1+ N / 2 tworzy mniejszy wygrywający slot. Dlatego sloty, które warto wybrać, to [1 .. ( N +1) / 2].

To pozostawia pytanie, jak wybrać miejsce. W przypadku niewielkiej liczby botów sprawdziłem, że istnieje równowaga Nasha, gdy każdy bot wybiera równomiernie spośród kandydatów i mocno podejrzewam, że nadal będzie to prawdą.

Niewielkie odchylenie w strategii tego bota od teoretycznego to po prostu metagaming.

Peter Taylor
źródło