รักษาระยะห่างของคุณบนวงกลม


9

สิ่งนี้ขึ้นอยู่กับความท้าทายนี้และความคิดของ Geobits / CarpetPython เพื่อปรับปรุง:

รักษาระยะห่างของคุณ!

สำหรับความท้าทายนี้ระยะห่างระหว่างตัวเลขสองจำนวนจะถูกวัดบนลูปดังนั้นเช่นระยะห่างระหว่าง 0 ถึง 999 คือ 1 สิ่งนี้ควรป้องกันกลยุทธ์เช่นการเลือกหมายเลขต่ำสุดหรือสูงที่สุดเสมอจากการชนะเกือบทุกครั้ง การเปลี่ยนแปลงอื่น ๆ เท่านั้นคือจำนวนต่ำสุดที่สามารถเลือกได้คือ 0 แทน 1

ฉันจะสรุปได้ที่นี่:

  • เขียนฟังก์ชั่นใน Java, Python หรือ Ruby ที่มีอาร์กิวเมนต์สามตัว:
    • จำนวนรอบที่เล่นจนถึง
    • จำนวนผู้เล่น
    • ตัวเลขที่เลือกในรอบก่อนหน้านี้เป็นอาร์เรย์ของสตริงที่คั่นด้วยช่องว่าง
  • มันควรจะกลับจำนวนเต็มตั้งแต่ 0 ถึง 999 รวม
  • คะแนนสำหรับโปรแกรมในแต่ละรอบคือผลรวมของสแควร์รูทของระยะทางไปยังหมายเลขที่แต่ละโปรแกรมอื่นเลือก
  • โปรแกรมที่มีคะแนนสูงสุดหลังจากชนะ 100 รอบ
  • หนึ่งคำตอบต่อคน

โปรแกรมควบคุมอยู่ที่นี่:

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

ลีดเดอร์บอร์ด

NumberOne โดย TheBestOne เป็นผู้ชนะ

  • NumberOne - 9700
  • NumberOnePlusFourNineNine - 9623
  • ประวัติศาสตร์โบราณ - 9425
  • FindCampers - 9259
  • WowThisGameIsSoDeep - 9069
  • ตัวอย่าง - 9014
  • การก่อวินาศกรรม - 8545

เห็นได้ชัดว่าการก่อวินาศกรรมค่ายของฉัน ... เอ่อ (?) ทำงานได้ไม่ดีนัก

นี่คือผลการแข่งขันเต็มรูปแบบ: https://github.com/KSFTmh/src/blob/master/results-3

ฉันคิดว่ามันแตกต่างกันพอที่จะไม่ซ้ำซ้อน

นี่เป็นครั้งแรกที่ฉันถามคำถามเกี่ยวกับการแลกเปลี่ยนแบบสแต็กดังนั้นแจ้งให้ฉันทราบหากฉันทำอะไรผิด


4
เราต้องการคำถามที่คล้ายกันนี้จริง ๆ หรือไม่
เครื่องมือเพิ่มประสิทธิภาพ

5
@Optimizer ไม่กี่คนในความคิดเห็นที่ดูเหมือนจะคิดว่านี่เป็นความคิดที่ดี คำตอบจากต้นฉบับจะทำงานแตกต่างกันมากที่นี่ดังนั้นฉันไม่คิดว่ามันจะซ้ำกัน
KSFT

1
เครดิตสำหรับการแนะนำความท้าทายควรไปที่ @Geobits ฉันแค่เห็นด้วยกับเขา
Logic Knight อัศวิน

1
อืมมม ดูเหมือนว่าจำนวนคงที่ชนะอีกครั้ง ฉันอยากรู้ว่าทำไมถึงเป็นอย่างนั้น เราสามารถดูหมายเลขออก 600 ในคำถามหรือบน github หรือ pastebin ฉันสงสัยว่านักทำนายของเราบางคนมีข้อบกพร่อง อาจเป็นไปได้ :-(
Logic Knight

1
@CarpetPython การเปลี่ยนแปลงง่าย ๆ คือการคำนวณระยะห่างระหว่างคะแนนจากรอบสุดท้ายนอกเหนือจากคะแนนในรอบนี้
TheNumberOne

คำตอบ:


3

Python 2, Sampler

รายการนี้จะขึ้นอยู่กับรหัสเดียวกันสำหรับการรักษาระยะห่างของคุณเข้าเก็บตัวอย่าง ฉันหวังว่ามันจะดีขึ้นที่นี่โดยที่ไม่มีข้อได้เปรียบ 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

2

Number OnePlusFourNineNine, Java

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

ตรรกะนั้นง่ายมาก หากไม่มีใครพบอัลกอริทึมจริงซึ่งพิจารณาคะแนนก่อนหน้านี้คำตอบนี้ได้รับการปรับให้เหมาะสม

ตอนนี้เรานับระยะทางเป็นวงกลมระยะทางสูงสุดของจุดสองจุดใด ๆ สามารถเป็น 500 ได้ตอนนี้หากทุกรายการกำลังสร้างตัวเลขสุ่ม . แต่มีอย่างน้อย 1 รายการที่สร้างคำตอบคงที่ซึ่งเป็นระยะทางสูงสุดเกือบ คะแนนทำให้คะแนนในความโปรดปรานของ 500 เพราะมีแหล่งที่มาคงที่ระยะทางสูงสุดที่เป็นไปได้ในแต่ละรอบ :)


คุณปรับปรุงคำตอบของฉัน ;)
TheNumberOne


2

ประวัติศาสตร์โบราณ - ธ

มันเป็นอัลกอริทึมเดียวกันจากก่อนหน้านี้ยกเว้นเมื่อคำนวณคะแนนที่เป็นไปได้จะใช้ระยะทางแบบวงกลม เนื่องจากฉันแพ้อย่างน่ากลัวและไม่สามารถรวบรวมคอนโทรลเลอร์ได้ฉันแค่ลองใช้กลยุทธ์ใหม่ที่ซึ่งฉันใช้สิ่งที่แย่ที่สุดจากรอบก่อนหน้า

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(' ')ซึ่งหมายความว่ามันเป็นสตริงไม่ใช่ int
KSFT

@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

ค้นหาค่ายทั้งหมดจาก 10 รอบสุดท้ายและอยู่ห่างจากพวกเขา ฉันหวังว่าผู้ทำนายจะหนีไปจากฉัน ตอนนี้ฉันจะเพิกเฉยต่อทางเลือกเดิมของฉัน

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

ฉันเพิ่งโพสต์ข้อความไปยังค่ายก่อวินาศกรรมด้วยตัวเอง
KSFT

ฉันไม่ทำงานเพราะฉันไม่ได้ตระหนักว่าผลลัพธ์ก่อนหน้านี้ถูกจัดเรียง คุณตรวจจับค่ายได้อย่างไร
KSFT

1

อันดับหนึ่ง Java

คำตอบแรก คัดลอกจากของฉันคำตอบก่อนหน้า

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

ดูเหมือนว่ามีคนบางคนลงคะแนนให้กับคำตอบทั้งหมด
KSFT

1

WowThisGameIsSoDeep, Java

ฉันวิเคราะห์เกมเป็นเวลา 10 ปีในคลัสเตอร์ 1 ล้านคอร์และพบทางออกที่ดีที่สุด

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


5
ทางออกนั้นไม่เหมาะสม Random.nextInt(int)ถ้าคุณต้องการกระจายชุดคุณควรใช้
ปีเตอร์เทย์เลอร์

สิ่งนี้ดูเหมือนจะส่งคืน 1 เสมอ
KSFT

@KSFT ฉันทดสอบและได้ตัวเลขที่แตกต่างกันมากมาย อาจเป็นการก่อวินาศกรรมหลังจากทั้งหมดหรือไม่
feersum

4
Aha! ฉันซ่อมมัน! ฉันพิมพ์ "WowThisGameIsSoDeep.py" โดยไม่ได้ตั้งใจและพยายามเรียกใช้เป็นไฟล์ Python
KSFT

1

Extrapolator Circilinear ทับทิม

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

โอ้previous_choicesมีค่ามากมาย["1 6 500","2 8 503"]ไหม
ประวัติศาสตร์

มันคือ. คุณคิดว่ามันเป็นอย่างอื่นหรือไม่? ถ้าไม่ฉันก็อาจทำอะไรบางอย่างยุ่งวิ่ง
KSFT

ฉันคิดว่ามันเป็นแค่สายแบนขอโทษ ฉันจะแก้ไข
ประวัติศาสตร์

แก้ไข ตอนนี้ทุกคนรู้ว่าฉันโพสต์บางอย่างโดยไม่ต้องทดสอบ ...
ประวัติศาสตร์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.