保持距离成圈


9

这是基于这一挑战以及Geobits / CarpetPython提出的改进建议:

保持距离!

对于此挑战,两个数字之间的距离是在一个循环中测量的,因此,例如0与999之间的距离为1。这应避免总是每次都选择最低或最高数字之类的策略。唯一的其他变化是,现在可以选择的最低数字为0而不是1。

我在这里总结一下:

  • 用Java,Python或Ruby编写一个带有三个参数的函数:
    • 到目前为止打过的回合数
    • 玩家人数
    • 前几轮中选取的数字,以空格分隔的字符串数组形式
  • 它应返回0到999之间的整数(含)
  • 每个程序的得分是每个程序选择的数字的距离的平方根之和
  • 100回合后得分最高的程序获胜。
  • 每人一个答案

控制程序在这里:

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

排行榜

TheBestOne的NumberOne获奖。

  • 一号-9700
  • NumberOnePlusFourNineNine-9623
  • 古代历史-9425
  • FindCampers-9259
  • WowThisGameIsSoDeep-9069
  • 采样器-9014
  • 破坏者露营车-8545

显然,我的露营者破坏活动... er(?)不能很好地工作。

这是完整的结果:https : //github.com/KSFTmh/src/blob/master/results-3

我认为这足够不同,不能重复。

顺便说一句,这是我第一次在Stack Exchange上提问,所以请让我知道我做错了什么。


4
我们真的想要一个类似的问题吗?
Optimizer

5
@Optimizer评论中的一些人似乎认为这是个好主意。原始答案在这里的工作方式将大不相同,因此我认为这不是重复的。
KSFT 2015年

1
建议挑战的功劳应该归功于@Geobits。我只是同意他的看法。
逻辑骑士

1
嗯 似乎一个恒定的数字再次获胜。我很好奇为什么会这样。我们可以在问题中还是在github或pastebin上看到600个输出数字?我怀疑我们的某些预测变量存在错误。可能是我的:-(
逻辑骑士

1
@CarpetPython一个简单的更改是除了计算本回合中的点之外,还要计算最后一点之间的距离。
TheNumberOne 2015年

Answers:


3

Python 2,采样器

该条目基于“ 保持距离,采样器”条目的相同代码。我希望它在没有1和999优势的地方会更好。

在位置列表中,选择与最近使用的数字相距最远的位置,而忽略前一弯(因为其他条目可能仅基于前一弯来预测)。

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

看来这是一个胜利,但这可能是因为我没有正确编写控制器,而其他都崩溃了。
KSFT 2015年

2

一号四号四号九号Java

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

逻辑很简单。除非有人找到将先前分数考虑在内的真实算法,否则此答案是相当优化的。

现在我们以一个圆为单位计算距离,任何两个点的最大距离可以是500。现在,如果所有条目都生成随机数(或基于某种算法的伪随机数),则此答案根本没有任何优势。 。但是至少有1个条目会产生一个恒定的答案,而该答案几乎是最大距离。使得得分有利于500,因为每一轮都有固定的最大距离来源:)


您优化了我的答案。;)
TheNumberOne 2015年

@TheBestOne哈哈
Optimizer

2

AncientHistorian-Python

它与上一个算法相同,不同之处在于,在计算潜在得分时,它使用圆形距离。由于我损失惨重并且无法编译控制器,因此我正在尝试一种新策略,在该策略中,我使用了前几轮中最糟糕的一种。

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

这行不通。i是的元素scores.split(' '),表示它是字符串,而不是整数。
KSFT'2

@KSFT哦,射击,我真的应该测试,更新。
马蒂森(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)

营员们仍在赢。让我知道您是否对此有任何建议。


2

FindCampers-Python 2

找到最近十轮的所有露营者,并远离他们。我希望预测因素能对我有利。我现在将忽略我的旧选择。

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

噢......我希望这会去营员,当我看到名字......
KSFT

大声笑。我可以添加一个条目,以破坏露营者。
Jmac

不幸的是,我每人只允许输入一次。
KSFT 2015年

我刚刚给破坏者们张贴了一篇文章。
KSFT 2015年

我的行不通,因为我没有意识到以前的结果是经过排序的。您如何发现露营者?
KSFT 2015年

1

Java第一

第一个答案。复制自我先前的答案

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

似乎有人拒绝所有答案。
KSFT'2

1

Java的WowThisGameIsSoDeep

我已经在100万核群集上分析了10年的游戏,并找到了最佳解决方案。

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


5
该解决方案不是最佳的。如果您想要统一分配,则应使用Random.nextInt(int)
彼得·泰勒

这似乎总是返回1
KSFT

@KSFT我测试了它,得到了许多不同的数字。也许毕竟是破坏活动?
feersum'2

4
啊哈!我修好了它!我不小心输入了“ WowThisGameIsSoDeep.py”,它试图将其作为Python文件运行。
KSFT 2015年

1

圆弧外推器,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

这给出了这个错误:NoMethodError: undefined method `split' for #<Array:0x720f56e2> choose at CircilinearExtrapolator.rb:2
KSFT 2015年

哦,是previous_choices值数组["1 6 500","2 8 503"]吗?
histocrat

它是。您是否认为这是另一回事?如果没有,我可能只是搞乱了运行它。
KSFT 2015年

我以为这只是一个扁平的字符串,对不起。我会编辑。
histocrat

编辑。现在大家都知道我发布了一些未经测试的东西……
histocrat
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.