Mantenha sua distância em um círculo


9

Isso se baseia nesse desafio e na idéia do Geobits / CarpetPython para melhorá-lo:

Mantenha distância!

Para esse desafio, a distância entre dois números é medida em um loop, portanto, por exemplo, a distância entre 0 e 999 é 1. Isso deve impedir que estratégias como sempre escolher o número mais baixo ou mais alto ganhem quase todas as vezes. A única outra alteração é que o número mais baixo que pode ser escolhido agora é 0 em vez de 1.

Vou resumir aqui:

  • Escreva uma função em Java, Python ou Ruby que aceite três argumentos:
    • o número de rodadas disputadas até agora
    • o número de jogadores
    • os números escolhidos nas rodadas anteriores, como uma matriz de sequências separadas por espaço
  • Ele deve retornar um número inteiro de 0 a 999, inclusive
  • A pontuação de um programa a cada rodada é a soma das raízes quadradas das distâncias dos números que o outro programa escolheu
  • O programa com a maior pontuação após 100 rodadas vence.
  • Uma resposta por pessoa

O programa de controle está aqui:

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

Entre os melhores

NumberOne, da TheBestOne, está ganhando.

  • NumberOne - 9700
  • NumberOnePlusFourNineNine - 9623
  • AntigoHistória - 9425
  • FindCampers - 9259
  • WowThisGameIsSoDeep - 9069
  • Amostrador - 9014
  • SabotageCampers - 8545

Aparentemente, minha sabotagem de campista ... er (?) Não funciona muito bem.

Aqui estão os resultados completos: https://github.com/KSFTmh/src/blob/master/results-3

Eu acho que isso é diferente o suficiente para não ser uma duplicata.

A propósito, esta é a primeira vez que faço uma pergunta no Stack Exchange, então, deixe-me saber se estou fazendo algo errado.


4
Realmente queremos uma pergunta parecida?
Optimizer

5
@Optimizer Algumas pessoas nos comentários pareciam pensar que era uma boa ideia. As respostas do original funcionarão de maneira muito diferente aqui, então não acho que seja uma duplicata.
KSFT 31/01

11
O crédito para sugerir o desafio deve ir para @Geobits. Eu apenas concordei com ele.
Logic Knight

11
Mmm. Parece que um número constante vence novamente. Estou curioso sobre o porquê disso. Podemos ver os 600 números de saída na pergunta, ou no github ou pastebin? Suspeito que alguns de nossos preditores tenham bugs. Possivelmente meu :-(
Logic Knight

11
@CarpetPython Uma mudança simples seria calcular a distância entre os pontos da última volta além dos pontos desta rodada.
TheNumberOne

Respostas:


3

Python 2, Sampler

Esta entrada é baseada no mesmo código da entrada Mantenha distância, Sampler . Espero que faça melhor aqui, onde as vantagens 1 e 999 não existem.

Em uma lista de locais, escolha o que está mais distante dos números usados ​​recentemente, ignorando a curva anterior (porque outras entradas podem prever com base apenas na curva anterior).

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

Parece que este está ganhando, mas isso pode ser porque eu não estou compilando o controlador direito e os outros estão travando.
KSFT

2

Number OnePlusFourNineNine, Java

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

A lógica é realmente simples. A menos que alguém encontre um algoritmo real que leve em consideração as pontuações anteriores, essa resposta é bastante otimizada.

Agora que contamos a distância em um círculo, a distância máxima de dois pontos pode ser 500. Agora, se todas as entradas estivessem gerando números aleatórios (ou pseudo-aleatórios com base em algum algoritmo), essa resposta não teria nenhuma vantagem. . Mas há pelo menos uma entrada que produz uma resposta constante a uma distância quase máxima. Isso faz com que a pontuação seja a favor de 500, pois existe uma fonte fixa de distância máxima possível em cada rodada :)


Você otimizou minha resposta. ;)
TheNumberOne

@TheBestOne haha
Optimizer

2

AncientHistorian - Python

É o mesmo algoritmo do anterior, exceto no cálculo das pontuações potenciais que utiliza a distância circular. Como estou perdendo horrivelmente e não consigo compilar o controlador, estou apenas tentando uma nova estratégia, na qual uso o pior das rodadas anteriores.

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

Isso não funciona. ié um elemento de scores.split(' '), o que significa que é uma string, não um int.
KSFT 01/02

@KSFT oh disparar, eu realmente deveria ter testado, atualizando.
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)

Os campistas ainda estão vencendo. Deixe-me saber se você tem alguma sugestão para isso.


2

FindCampers - Python 2

Encontre todos os campistas das últimas 10 rodadas e fique longe deles. Espero que os preditores corram de mim. Agora vou ignorar minhas antigas escolhas.

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 ... eu estava esperando que isso fosse direcionado para os campistas quando vi o nome ...
KSFT 07/02/15

Ri muito. Eu poderia adicionar uma entrada que sabotará os campistas.
Jmac

Infelizmente, permiti apenas uma entrada por pessoa.
KSFT

Acabei de publicar uma entrada para sabotar os campistas.
KSFT

O meu não funciona porque eu não percebi que os resultados anteriores foram classificados. Como o seu detecta os campistas?
KSFT

1

Número Um, Java

A primeira resposta Copiado da minha resposta anterior .

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

Alguém parece ter rebaixado todas as respostas.
KSFT

1

WowThisGameIsSoDeep, Java

Analisei o jogo por 10 anos em um cluster de 1 milhão de núcleos e encontrei a solução ideal.

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

Isso não é código-golfe
Otimizador

5
Essa solução não é ótima. Se você deseja uma distribuição uniforme, use Random.nextInt(int).
Peter Taylor

Isso sempre parece retornar 1.
KSFT 02/02

@KSFT Eu testei e obtive muitos números diferentes. Talvez seja sabotagem, afinal?
feersum

4
Aha! Eu consertei isso! Digitei acidentalmente "WowThisGameIsSoDeep.py" e ele estava tentando executá-lo como um arquivo Python.
KSFT 02/02

1

Extrapolador circular, Ruby

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

Isso está causando este erro:NoMethodError: undefined method `split' for #<Array:0x720f56e2> choose at CircilinearExtrapolator.rb:2
KSFT

Ah, é como previous_choicesuma matriz de valores ["1 6 500","2 8 503"]?
histocrat

Isto é. Você achou que era outra coisa? Caso contrário, provavelmente eu estraguei tudo ao executá-lo.
KSFT

Eu pensei que era apenas uma corda plana, desculpe. Eu vou editar.
Histocrat

Editado. Agora todo mundo sabe que eu postei algo sem testá-lo ...
histocrat
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.