距離を置く!


15

すべてのプレイヤーには番号があります。あなたのものはそれらすべてから最も遠いことができますか?

必要条件

choose()3つの引数を受け入れるJava、Python 2、またはRuby関数を作成します。

  • 整数-すでに完了したラウンドの数
  • 整数-プレーヤーの数
  • 文字列の配列-前回の各ラウンドの結果
    • 各文字列は、スペースで区切られた整数のリストであり、最低から最高にソートされています

たとえば、次のchoose(2, 4, ["4 93 93 174", "1 84 234 555"])ことを意味します。

  • すでに2ラウンドありました(これは3回目のラウンドです)
  • 合計4人のプレイヤーがいます
  • 最初のラウンドでは、選択された数字は4、93、93、174でした
  • 2回目のラウンドでは、選択された数字は1、84、234、555でした

1から999(両端を含む)までの整数を返す必要があります。

他の各プレイヤーにとって、あなたのスコアはあなたの番号と彼らの間の距離の平方根です。ラウンドのスコアは、これらすべてのスコアの合計です。

100ラウンドがプレイされます。最高の合計スコアが勝ちます!

ルール

  • コードは、コンソール、ファイル、ネットワークなどを含むI / Oを使用できません。
  • 制御プログラムや他のプレーヤーに干渉することはできません。
  • 上記の規則に違反しているように見えるプログラムは除外されます。
  • 関数(8GBのRAMを搭載したIntel Core i5 2450M)では、関数の各呼び出しに5秒未満かかります。
  • プログラムが例外をスローするか、無効な値を返す場合、1を返したものとして扱われます。
  • 各ユーザーは、最大1つのプログラムを送信できます。

その他

リーダーボード

勝者はConservatorです。

一定ではない戦略を持つ最高得点のプレイヤー、グスタフに敬意を表する。

  • 保護者-36226
  • 高-36115
  • FloorHugger-35880
  • ナンバーワン-35791
  • 過大評価-35791
  • グスタフ-35484
  • 歴史家-35201
  • サンプラー-34960
  • 焼rem人-34351
  • JumpRightIn-34074
  • ヴィクレイ-34020
  • ティーンエイジャー-33907
  • ランドゥ-33891
  • 重量挙げ-33682
  • ミドルマン-33647
  • バウンスインワード-33529
  • 淫乱数学者-33292
  • ジャンパー-33244
  • 模倣-33049

完全な結果はここにあります。(テキストの折り返しを無効にすることをお勧めします。)


以前のラウンドで自分の番号がどれであったかを知る方法はありますか?
マーティンエンダー

@MartinBüttner番号
Ypnypn

1
?私は、これらの言語のいずれかを知らない:(あなたはNode.jsのとそれを実行し、JavaScriptのように追加してもらえますか?
Cilan

1
@TheWobbuffet、私もそれらのどれも知りません。Pythonのエントリを作成するのを止めませんでした。
マーク

7
スペースが1から999の間の距離が1になるように円/ループであった場合、それはより興味深いと思うと思います。駐車します。明らかに今では変更するには遅すぎます;)
Geobits

回答:


9

Python、Conservator

def choose(round, players, scores):
    return 999

すべての例外は1をスローするため、例外は可能な限り回避されます。弱者を犠牲にしてその財産を作ります。

楽しい事実:私はそれを改善することを考えましたが、隅に隠れているよりも良い方法を見つけることができませんでした。


1
間違ったコーナーを選んだようです。:(
TheNumberOne

それは単純な理由のために良いです:他のものはあなたへの距離を最小化しようとします。スコアが自動的に改善されます。ゲームチェンジャーは、可能な限りあなたに近づこうとする相手です。
マーティントーマ

1
うわー... Pythonのセミコロン?
KSFT

@KSFT hehe私はPythonに
さびついてい

6

ナンバーワン、Java

名前はこれを完全に説明しています。

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

1
なぜ反対票なのか?
TheNumberOne

5
特に、ユーザー名が提出に結びつくのが好きです
ブライアンJ

5

Python、AncientHistorian

未来は過去とまったく同じであると固く信じていますが、最後のラウンドはあまりにも最近のものであり、歴史的ではないため、1-999をループし、前のラウンドが最後を除いて最高だったものを選択します。最初の2ラウンドは500を返します。

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

4

Python、Vickrey

def choose(rounds, players, results):        
    if not results:
        return (id(0)/7)%999 + 1

    def best(array):
        score = lambda x: sum(abs(x-y)**.5 for y in array)
        m = max(score(x) for x in range(1, 1000))
        return [x for x in range(1, 1000) if score(x) == m]

    def second_best(array):
        array.extend(best(array))
        options = best(array)
        return options[(id(0)/7) % len(options)]

    results = [map(int, s.split()) for s in results]
    counts = {}

    for round_ in results:
        for number in round_:
            counts[number] = counts.get(number, 0) + 1

    most_common = sorted([(c, n) for n,c in counts.items()], reverse=True)
    to_avoid = [t[1] for t in most_common[:players]]

    return second_best(to_avoid)

頻繁にプレイされている数字のリストを作成し、他の全員が最適にプレイすることを想定し、 2番目の、リストから最適な選択肢を選択します。

たとえば、最も一般的な数字がの[1, 990, 999]場合、Vickreyは最適なプレイ200を挿入してを与え[1, 200, 990, 999]、新しい配列に最適なオプション(556)を選択します。


4

Java、過大評価者

名前が示すように、このプログラムは、他のすべてのプログラムは、最後のラウンドに基づいて最良の答えを選ぶことによって、「ウェル」プレーしようと想定している-ので、これは「overestimator」常にピック最悪前のラウンドに基づいて可能な位置を。

 public static int choose(int round, int players, String[] args) {
     String[] lastRoundStrings = args[args.length - 1].split(" ");
     int[] lastRound = new int[lastRoundStrings.length];
     int worstSelection = 0;
     for (int i = 0; i < lastRound.length; i++) {
         double worstScore = Double.MAX_VALUE;
         for (int j = 1; j < 999; j++) {
             double computedScore = score(j, lastRound);
             if (computedScore < worstScore) {
                 worstScore = computedScore;
                 worstSelection = j;
             }
         }
     }
     return worstSelection;
 }

 public static double score(int position, int[] otherPositions) {
     double total = 0;
     for (int i = 0; i < otherPositions.length; i++) {
         total += Math.sqrt(Math.abs(otherPositions[i] - position));
     }
     return total;
 }

どうしてこれが一定の「1」を演じたのでしょうか?バグはありましたか?気をつけて、「1」をプレイすることは非常に成功することが証明されました。:)
エミール

悲しいことに、コードにはバグがあります。はい-最後のラウンドで読み取ったスコアを実際に解析することはありません。(しかし、私はそれが遅すぎることに気づき、それまでに提出物を編集するのは間違っているように見えました、そしてあなたが言うようにそれはとてもうまくいっていました...何でも:p)
アレックスウォーカー

4

Java-重量挙げ

1〜999をループして、各ラウンドに最適なものを見つけます。最新のものに応じてそれらの重量を量り(最近のラウンドの方が重量が大きい)、全体の最良の推測を返します。後のラウンドでパターンが形成されれば、うまくいけばうまくいくでしょう。

編集:再帰が+ Inf%増えました! 前のラウンドで選択したものを保存/保存/表示できないのはドラッグです。自分の入力を考慮に入れると、他の人が何をしようとしているのかを理解しようとするときに混乱します。それでは、計算しましょう!これは前のラウンドで選択したものを把握するために再帰的になり、次の動きを計算するときにそれを無視します。

最後のターンからの自身の入力のみを実際に無視することに注意してください。しかし、その入力は最も高く重み付けされているので、うまくいくようです。これはもう少し作業で修正できますが、リーダーボードが必要かどうかを確認するのを待ちます。

int choose(int rounds, int players, String[] hist){
    if(rounds < 1)
        return 1;

    int lastChoice = choose(rounds-1,players,java.util.Arrays.copyOf(hist, hist.length-1));

    int[][] history = new int[hist.length][players];
    for(int i=0;i<hist.length;i++){
        String[] tokens = hist[i].split(" ");
        boolean flag = false;
        for(int j=0;j<tokens.length;j++){
            history[i][j] = Integer.parseInt(tokens[j]);
            if(i==history.length-1 && history[i][j]==lastChoice && !flag){
                flag = true;
                history[i][j] = -1;
            }
        }
    }

    double best = 0;
    int guess = 1;
    for(int i=1;i<1000;i++){
        double score = 0;
        for(int j=0;j<history.length;j++){
            double weight = (double)(j+1)/history.length;
            for(int k=0;k<history[j].length;k++){
                if(history[j][k] > 0)
                    score += Math.sqrt(Math.abs(history[j][k]-i)) * weight;
            }
        }
        if(score > best){
            best = score;
            guess = i;
        }
    }
    return guess;
}

注:ラウンド100でも、やや遅いPCでは1秒未満で完了します。何らかの理由で時間がかかりすぎる場合は、再帰を制限できるようにお知らせください。
ジオビット

私のマシンでも非常に高速です。
Ypnypn

3

ルビー、コピーキャット

前回勝った番号を返すだけです。

def choose r, p, hist
  last = hist.last.split.map &:to_i
  scores = last.map{|n| last.map{|m| (n-m).abs ** 0.5 }.inject :+ }
  last[scores.index scores.max]
end

1
最初のラウンドでは何が返されますか?ああ気にしません。例外は1を返します
。– mbomb007

3

ルビー、JumpRightIn

def choose(round, players, args)
    return 500 if args.size == 0
    last_round = args[-1].split.map(&:to_i) + [1000]
    max_gap = 0
    last = 0
    move = 1
    last_round.each { |i|
        gap = i - last - 1
        if gap > max_gap
            max_gap = gap
            move = (i + last)/2
        end
        last = i
    }
    move
end

これはおそらく最も単純な戦略です。最後のラウンドで最大のギャップを見つけ、そのギャップの真ん中で数字を選択します。


最初のラウンドでは何が返されますか?1?
mbomb007

@ mbomb007ああ、私はいつもこれらの厄介な最初のラウンドを忘れています。おかげで、それは今500を返します
マーティン・エンダー

3

グスタフ(Python 2)

これは非常に単純なメタ戦略であり、同様のKotHチャレンジでの私の古い回答の 1つから恥知らずにコピーされました。いくつかの単純な戦略を検討し、以前のすべてのラウンドでそれらがどのように実行されるかを調べ、次のラウンドで最高のスコアリングを実行します。

def choose(k, N, h):
    if k<2: return 999
    H = [[int(x) for x in l.split()] for l in h]
    score = lambda x,l: sum(abs(x-y)**.5 for y in l)
    S = [range(1,1000)
         + [max(range(1,1000), key=lambda x: score(x, H[i-1]))]
         + [max(range(1,1000), key=lambda x: score(x, H[i-2]))]
         + [min(range(1,1000), key=lambda x: score(x, H[i-1]))]
         + [min(range(1,1000), key=lambda x: score(x, H[i-2]))]
         for i in range(2,k+1)]
    scores = [sum(score(s[j],l) for s,l in zip(S[:-1], H[2:]))
              for j in range(len(S[0]))]
    return max(zip(scores, S[-1]))[1]

アルゴリズムにはまだいくつかの欠陥があることがわかりました。例えば、自分の動きを相手の動きと区別しないため、「追いかけ続ける」かもしれません。ただし、このままにしておきます。



1

次の3つのプログラムが組み込まれています。

高(ルビー)

def choose(round, players, args)
    return 990
end

Incrementer(Java)

public static int choose(int round, int players, String[] args) {
    return round * 10 + 5;
}

FloorHugger(Python)

def choose(round, players, args):
    if len(args) == 0:
        return 10
    last = args[-1].split();

# next line from http://stackoverflow.com/a/7368801/3148067
    last = map(int, last)

    dist = 0
    for i in range(1, 999):
        if i in last:
            dist = 0
        else:
            dist = dist + 1
            if dist == 10:
                return i
    return 500

1

Python、サンプラー

場所のリストから、前のターンを無視して、最近使用した番号から最も遠い場所を選択します。

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

1

Java、BounceInwards

1から開始して、より高いオプションとより低いオプションの間を行き来しながら、徐々に500に近づきます。

public static int choose(int round, int players, String[] args) {
    return round%2 == 0 ? round * 5 : 1000 - round * 5;
}

1

淫乱数学者(Java)

最後の2ラウンドを調べます(最高の数値が70と80の場合、90を出力します)。それは彼の対戦相手に勝つためにできるだけ多くの数字を取得しようとするため、それは厄介です。

public static int choose(int round, int players, String[] args) {
    if (round == 0) {
        return 999;
    }

    int[][] results = new int[args.length][players];

    // parse input
    for (int i = 0; i < args.length; i++) {
        String[] rounds = args[i].split(" ");
        for (int j = 0; j < rounds.length; j++) {
            results[i][j] = Integer.parseInt(rounds[j]);
        }
    }

    int bestNumber = 0;
    double bestScore = -1;

    // get the best number for the last round
    for (int i = 1; i < 1000; i++) {
        double score = 0;
        for (int result : results[results.length - 1]) {
            score += Math.sqrt(Math.abs(i - result));
        }
        if (score >= bestScore) {
            bestScore = score;
            bestNumber = i;
        }
    }

    if (round == 1) {
        return bestNumber;
    }

    int bestNumber2 = 0;
    double bestScore2 = -1;

    // get the best number for the second last round
    for (int i = 1; i < 1000; i++) {
        double score = 0;
        for (int result : results[results.length - 2]) {
            score += Math.sqrt(Math.abs(i - result));
        }
        if (score > bestScore2) {
            bestScore2 = score;
            bestNumber2 = i;
        }
    }

    // add the difference between last round and second last round to get this rounds best number
    int difference = bestNumber - bestNumber2;
    bestNumber = bestNumber + difference;

    return bestNumber > 999 ? 999 : bestNumber;
}

1

Python-名前を考えたくない...

過去のラウンドで選択された数値の平均が500未満の場合、999が選択されます。それ以外の場合は1が選択されます。

def choose(a,b,c):
    total=0
    for i in c:
        for j in i.split(" "):
            total+=int(i)
    average=total/(a*b)
    if average<500:
        return 999
    return 1

0

Python、ミドルマン(@clabacchioによるコンサベーターに基づく)

def choose(round, players, scores):
    return 500;

上部のエッジのスコアが高いことに気づいた後(そして、下部のエッジよりも優れている)、真ん中に引っかかるよりも悪いことがあるのではないかと思いました。


0

ジャンパー(ルビー)

def choose(round, players, args)
    495*(round%3)+5
end

下、中、上を交互に切り替えます。(5,500,995)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.