Mantieni la distanza su un cerchio


9

Questo si basa su questa sfida e sull'idea di Geobits / CarpetPython di migliorarla:

Mantieni le distanze!

Per questa sfida, la distanza tra due numeri viene misurata su un loop, quindi, ad esempio, la distanza tra 0 e 999 è 1. Questo dovrebbe impedire a strategie come scegliere sempre il numero più basso o più alto di vincere quasi ogni volta. L'unica altra modifica è che il numero più basso che può essere scelto è ora 0 anziché 1.

Lo riassumo qui:

  • Scrivi una funzione in Java, Python o Ruby che accetta tre argomenti:
    • il numero di round giocati finora
    • il numero di giocatori
    • i numeri raccolti nei round precedenti, come una matrice di stringhe separate da spazio
  • Dovrebbe restituire un numero intero compreso tra 0 e 999, inclusi
  • Il punteggio per un programma per ogni round è la somma delle radici quadrate delle distanze rispetto ai numeri scelti da ciascun altro programma
  • Vince il programma con il punteggio più alto dopo 100 round.
  • Una risposta per persona

Il programma di controllo è qui:

https://github.com/KSFTmh/src/

Classifica

NumberOne, di TheBestOne, sta vincendo.

  • NumberOne - 9700
  • NumberOnePlusFourNineNine - 9623
  • AncientHistorian - 9425
  • FindCampers - 9259
  • WowThisGameIsSoDeep - 9069
  • Sampler - 9014
  • SabotageCampers - 8545

Apparentemente, il mio sabotaggio di camper ... er (?) Non funziona molto bene.

Ecco i risultati completi: https://github.com/KSFTmh/src/blob/master/results-3

Penso che questo sia abbastanza diverso da non essere un duplicato.

A proposito, questa è la prima volta che faccio una domanda su Stack Exchange, quindi fatemi sapere se sto facendo qualcosa di sbagliato.


4
Vogliamo davvero una domanda così simile?
Ottimizzatore

5
@Optimizer Alcune persone nei commenti sembravano pensare che fosse una buona idea. Le risposte dall'originale funzioneranno in modo molto diverso qui, quindi non penso che sia un duplicato.
KSFT,

1
Il merito per aver suggerito la sfida dovrebbe andare a @Geobits. Sono appena stato d'accordo con lui.
Logic Knight,

1
Mmm. Sembra che un numero costante vinca di nuovo. Sono curioso di sapere perché. Potremmo vedere i 600 numeri di output nella domanda, o su github o pastebin? Sospetto che alcuni dei nostri predittori abbiano dei bug. Forse il mio :-(
Logic Knight,

1
@CarpetPython Una semplice modifica sarebbe quella di calcolare la distanza tra i punti dall'ultimo giro in aggiunta ai punti di questo round.
TheNumberOne

Risposte:


3

Python 2, Sampler

Questa voce si basa sullo stesso codice per Mantieni la distanza, voce Sampler . Spero che farà meglio qui dove non esistono i vantaggi 1 e 999.

Da un elenco di luoghi, scegli quello più lontano dai numeri utilizzati di recente, ignorando il turno precedente (perché altre voci possono prevedere in base al solo turno precedente).

def choose(turn, players, history):
    sample = map(int, (' '.join( history[-5:-1] )).split())
    def distance(x):
        return sum(min(1000-abs(x-y), abs(x-y))**0.5 for y in sample)
    score, place = max((distance(x), x) for x in range(1000))
    return place

Sembra che questo sia vincente, ma potrebbe essere perché non sto compilando correttamente il controller e tutti gli altri si stanno bloccando.
KSFT,

2

Numero OnePlusFourNineNine, Java

public static int choose(int round, int players, String[] args) {
    return 500;
}

La logica è davvero semplice. A meno che qualcuno non trovi un vero algoritmo che tenga conto dei punteggi precedenti, questa risposta è abbastanza ottimizzata.

Ora che contiamo la distanza in un cerchio, la distanza massima di due punti può essere 500. Ora se tutte le voci generassero numeri casuali (o pseudo casuali basati su un algoritmo), questa risposta non sarebbe stata affatto vantaggiosa . Ma c'è almeno 1 voce che produce una risposta costante a una distanza quasi massima. Ciò rende il punteggio a favore di 500 in quanto vi è una fonte fissa di massima distanza possibile in ogni round :)


Hai ottimizzato la mia risposta. ;)
TheNumberOne

@TheBestOne haha
Optimizer

2

AncientHistorian - Python

È lo stesso algoritmo del precedente, tranne che per il calcolo dei punteggi potenziali utilizza la distanza circolare. Dato che sto perdendo orribilmente e non riesco a compilare il controller, sto solo provando una nuova strategia, in cui utilizzo il peggio dei round precedenti.

def choose(round, players, scores):
    calc = lambda n, scores: sum([min(abs(int(i)-n), 1000-max(int(i),n)+min(int(i),n))**.5 for i in scores.split(' ')])
    return min(range(1000), key=lambda n: sum([calc(n, j) for j in scores[1:]])) if round>1 else 250

Questo non funziona iè un elemento di scores.split(' '), nel senso che è una stringa, non un int.
KSFT,

@KSFT oh sparare, avrei dovuto testarlo, aggiornarlo.
Maltysen,

2

SabotageCampers - Python

def choose(rounds, players, previous):
    if rounds<3:
        return 1
    prevchoices=[int(i) for i in " ".join(previous[-5:]).split(" ")]
    remove=[]
    for i in prevchoices:
        if prevchoices.count(i)<3:
            remove.append(i)
    campers=[i for i in prevchoices if i not in remove]
    return random.choice(campers)

I campeggiatori stanno ancora vincendo. Fammi sapere se hai qualche suggerimento per questo.


2

FindCampers - Python 2

Trova tutti i campeggiatori degli ultimi 10 round e stai lontano da loro. Spero che i predittori scapperanno da me. Ora ignorerò le mie vecchie scelte.

def choose(rounds, players, previous):
    from collections import Counter

    def distance(x, y):
        return min(1000 - abs(x-y), abs(x-y))

    pastRounds = list(map(lambda x: Counter(map(int, x.split())), previous))
    me = 751
    for (index, round) in enumerate(pastRounds):
        round.subtract((me,))
        pastRounds[index] = set(round.elements())
        campers = reduce(lambda x,y: x.intersection(y), pastRounds[max(1, index-9):index], pastRounds[max(0,index-10)])
        if campers:
            dist, me = max(min((distance(x, y), x) for y in campers) for x in range(1000))
        else:
            me = 751
    return me

Aww ... Speravo che questo sarebbe andato verso i campeggiatori quando ho visto il nome ...
KSFT

Lol. Potrei aggiungere una voce che saboterà i campeggiatori.
Jmac,

Sfortunatamente, ho permesso solo una voce a persona.
KSFT

Ho appena pubblicato un post per sabotare i campeggiatori.
KSFT

Il mio non funziona perché non mi rendevo conto che i risultati precedenti erano ordinati. In che modo i tuoi rilevano i campeggiatori?
KSFT

1

Numero uno, Java

La prima risposta Copiato dalla mia risposta precedente .

public static int choose(int round, int players, String[] args) {
    return 1;
}

Qualcuno sembra aver annullato il voto di tutte le risposte.
KSFT,

1

WowThisGameIsSoDeep, Java

Ho analizzato il gioco per 10 anni su un cluster da 1 milione di core e ho trovato la soluzione ottimale.

public static int choose(int round, int players,String[]spam) { return(int)(Math.random()*1e3); }

Questo non è un codice-golf
Ottimizzatore

5
Quella soluzione non è ottimale. Se si desidera una distribuzione uniforme, è necessario utilizzare Random.nextInt(int).
Peter Taylor,

Questo sembra restituire sempre 1.
KSFT

@KSFT L'ho provato e ho ottenuto molti numeri diversi. Forse dopo tutto è un sabotaggio?
feersum

4
Aha! L'ho riparato! Ho accidentalmente digitato "WowThisGameIsSoDeep.py" e stavo cercando di eseguirlo come file Python.
KSFT,

1

Estrapolatore Circilineare, Rubino

def choose(round, players, previous_choices)
  previous_rounds = previous_choices.map{ |round| round.split.map(&:to_i) }
  optimal_past_choices = previous_rounds.map do |choices|
    (0..999).max_by { |i| choices.map{ |c| root_distance(i,c) }.inject(:+) }
  end
  if (last_round = optimal_past_choices.last)
    (last_round + average_delta(optimal_past_choices).round) % 1000
  else
    750
  end
end

def root_distance(i,j)
  dist = (i-j).abs
  dist = [dist, 1000 - dist].min
  dist ** 0.5
end

def directed_distance(i,j)
  dist = j - i
  if dist > 500
    dist - 1000
  elsif dist < -500
    dist + 1000
  else
    dist
  end
end

def average_delta(ary)
  ary.each_cons(2).map{ |x,y| directed_distance(x,y) }.inject(0,:+)/ary.count
end

Questo sta dando questo errore:NoMethodError: undefined method `split' for #<Array:0x720f56e2> choose at CircilinearExtrapolator.rb:2
KSFT

Oh, è previous_choicesuna serie di valori come ["1 6 500","2 8 503"]?
istocrato

È. Pensavi fosse qualcos'altro? In caso contrario, probabilmente ho appena incasinato qualcosa eseguendolo.
KSFT,

Pensavo fosse solo una corda piatta, scusa. Lo modificherò.
istocrato

Modificato. Ora tutti sanno che ho pubblicato qualcosa senza
testarlo
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.