Jaga jarak Anda pada lingkaran

9

Ini didasarkan pada tantangan ini dan ide Geobits / CarpetPython untuk memperbaikinya:

Jaga jarak Anda!

Untuk tantangan ini, jarak antara dua angka diukur pada satu lingkaran, jadi, misalnya, jarak antara 0 dan 999 adalah 1. Ini harus mencegah strategi seperti selalu memilih angka terendah atau tertinggi dari kemenangan hampir setiap waktu. Satu-satunya perubahan lainnya adalah bahwa angka terendah yang dapat dipilih sekarang adalah 0 bukannya 1.

Saya akan meringkasnya di sini:

  • Tulis fungsi dalam Java, Python, atau Ruby yang mengambil tiga argumen:
    • jumlah putaran yang dimainkan sejauh ini
    • jumlah pemain
    • nomor dipilih pada putaran sebelumnya, sebagai array string yang dipisahkan oleh ruang
  • Seharusnya mengembalikan bilangan bulat dari 0 hingga 999, inklusif
  • Skor untuk suatu program setiap putaran adalah jumlah dari akar kuadrat dari jarak ke angka yang dipilih masing-masing program
  • Program dengan skor tertinggi setelah 100 putaran menang.
  • Satu jawaban per orang

Program kontrol ada di sini:

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

Papan peringkat

NumberOne, oleh TheBestOne, menang.

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

Rupanya, sabotase karavan saya ... eh (?) Tidak bekerja dengan baik.

Inilah hasil lengkapnya: https://github.com/KSFTmh/src/blob/master/result-3

Saya pikir ini cukup berbeda untuk tidak menjadi duplikat.

Ngomong-ngomong, ini adalah pertama kalinya saya mengajukan pertanyaan di Stack Exchange, jadi beri tahu saya jika saya melakukan sesuatu yang salah.

KSFT
sumber
4
Apakah kita benar-benar menginginkan pertanyaan yang serupa ini?
Pengoptimal
5
@ Pengoptimal Beberapa orang di komentar sepertinya berpikir ini adalah ide yang bagus. Jawaban dari yang asli akan bekerja sangat berbeda di sini, jadi saya rasa itu bukan duplikat.
KSFT
1
Penghargaan untuk menyarankan tantangan harus ke @Geobits. Saya hanya setuju dengannya.
Logic Knight
1
Mmm Tampaknya angka konstan menang lagi. Saya ingin tahu mengapa itu terjadi. Bisakah kita melihat 600 angka keluaran dalam pertanyaan, atau di github atau pastebin? Saya menduga beberapa prediktor kami memiliki bug. Mungkin milikku :-(
Logic Knight
1
@CarpetPython Perubahan sederhana akan menghitung jarak antara titik-titik dari terakhir di sekitar selain poin-poin dari putaran ini.
TheNumberOne

Jawaban:

3

Python 2, Sampler

Entri ini didasarkan pada kode yang sama untuk Jaga jarak Anda, entri Sampler . Saya harap ini akan lebih baik di sini di mana keunggulan 1 dan 999 tidak ada.

Di luar daftar tempat, pilih salah satu yang paling jauh dari angka yang baru digunakan, abaikan belokan sebelumnya (karena entri lain dapat memprediksi berdasarkan belokan sebelumnya).

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
Ksatria Logika
sumber
Sepertinya ini yang menang, tapi itu mungkin karena aku tidak mengkompilasi controller yang benar dan yang lainnya semuanya crash.
KSFT
2

Nomor OnePlusFourNineNine, Jawa

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

Logikanya sangat sederhana. Kecuali jika seseorang menemukan algoritma nyata yang mempertimbangkan skor sebelumnya, jawaban ini cukup dioptimalkan.

Sekarang kita menghitung jarak dalam lingkaran, jarak maksimum dua titik bisa menjadi 500. Sekarang jika semua entri menghasilkan angka acak (atau pseudo acak berdasarkan beberapa algoritma), jawaban ini tidak akan menguntungkan sama sekali . Tetapi setidaknya ada 1 entri yang menghasilkan jawaban konstan yang jaraknya hampir maksimal. Yang membuat skor mendukung 500 karena ada sumber tetap jarak maksimum yang mungkin di setiap putaran :)

Pengoptimal
sumber
Anda mengoptimalkan jawaban saya. ;)
TheNumberOne
@TheBestOne haha
Pengoptimal
2

AncientHistorian - Python

Ini adalah algoritma yang sama dari yang sebelumnya, kecuali ketika menghitung skor potensial menggunakan jarak melingkar. Karena saya kalah hebat dan tidak bisa dikompilasi oleh pengontrol, saya hanya mencoba strategi baru, di mana saya menggunakan yang terburuk dari putaran sebelumnya.

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
Maltysen
sumber
Ini tidak berhasil. iadalah elemen dari scores.split(' '), yang berarti string, bukan int.
KSFT
@KSFT oh menembak, saya benar-benar harus menguji, memperbarui.
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)

Para berkemah masih menang. Beri tahu saya jika Anda memiliki saran untuk ini.

KSFT
sumber
2

FindCampers - Python 2

Temukan semua berkemah dari 10 putaran terakhir dan menjauhlah dari mereka. Saya berharap bahwa prediktor akan lari dari saya. Sekarang saya akan mengabaikan pilihan lama saya.

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
Jmac
sumber
Aww ... Saya berharap ini akan menuju para berkemah ketika saya melihat nama ...
KSFT
Lol. Saya bisa menambahkan entri yang akan menyabot berkemah.
Jmac
Sayangnya, saya hanya mengizinkan satu entri per orang.
KSFT
Saya baru saja memposting entri untuk menyabot berkemah.
KSFT
Milik saya tidak berfungsi karena saya tidak menyadari bahwa hasil sebelumnya diurutkan. Bagaimana Anda mendeteksi berkemah?
KSFT
1

Nomor Satu, Jawa

Jawaban pertama Disalin dari jawaban saya sebelumnya .

public static int choose(int round, int players, String[] args) {
    return 1;
}
TheNumberOne
sumber
Seseorang sepertinya telah menurunkan semua jawaban.
KSFT
1

WowThisGameIsSoDeep, Java

Saya telah menganalisis permainan selama 10 tahun pada kluster 1 juta inti dan menemukan solusi optimal.

public static int choose(int round, int players,String[]spam) { return(int)(Math.random()*1e3); }
feersum
sumber
Ini bukan kode-golf
Pengoptimal
5
Solusi itu tidak optimal. Jika Anda ingin distribusi yang seragam, Anda harus menggunakannya Random.nextInt(int).
Peter Taylor
Ini sepertinya selalu kembali 1.
KSFT
@KSFT Saya mengujinya dan mendapat banyak nomor berbeda. Mungkin itu sabotase?
feersum
4
Aha! Aku telah memperbaikinya! Saya tidak sengaja mengetik "WowThisGameIsSoDeep.py", dan mencoba menjalankannya sebagai file Python.
KSFT
1

Circilinear Extrapolator, 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
histokrat
sumber
Ini memberikan kesalahan ini:NoMethodError: undefined method `split' for #<Array:0x720f56e2> choose at CircilinearExtrapolator.rb:2
KSFT
Oh, apakah previous_choicesarray nilai seperti ["1 6 500","2 8 503"]?
histokrat
Ini. Apakah Anda pikir itu sesuatu yang lain? Jika tidak, saya mungkin hanya mengacaukan sesuatu menjalankannya.
KSFT
Saya pikir itu hanya string datar, maaf. Saya akan mengedit.
histokrat
Diedit. Sekarang semua orang tahu saya memposting sesuatu tanpa mengujinya ...
histokrat