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.