Trzymaj dystans na kole

9

Jest to oparte na tym wyzwaniu i pomyśle Geobits / CarpetPython, aby je poprawić:

Zachowaj dystans!

W przypadku tego wyzwania odległość między dwiema liczbami jest mierzona na pętli, więc na przykład odległość między 0 a 999 wynosi 1. To powinno zapobiec strategiom, takim jak zawsze wybieranie najniższej lub najwyższej liczby, wygrywanie prawie za każdym razem. Jedyną inną zmianą jest to, że najniższą liczbą, którą można wybrać, jest teraz 0 zamiast 1.

Podsumuję to tutaj:

  • Napisz funkcję w Javie, Pythonie lub Ruby, która pobiera trzy argumenty:
    • liczba rozegranych rund do tej pory
    • liczba graczy
    • liczby wybrane w poprzednich rundach, jako tablica ciągów rozdzielonych spacjami
  • Powinien zwrócić liczbę całkowitą od 0 do 999 włącznie
  • Wynik dla programu w każdej rundzie jest sumą pierwiastków kwadratowych odległości do liczb, które wybrał każdy inny program
  • Program z najwyższym wynikiem po 100 rundach wygrywa.
  • Jedna odpowiedź na osobę

Program sterujący jest tutaj:

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

Tabela liderów

NumberOne, TheBestOne, wygrywa.

  • NumberOne - 9700
  • NumberOnePlusFourNineNine - 9623
  • AncientHistorian - 9425
  • FindCampers - 9259
  • WowThisGameIsSoDeep - 9069
  • Próbnik - 9014
  • Sabotaż Obozowiska - 8545

Najwyraźniej mój sabotaż kampera ... er (?) Nie działa zbyt dobrze.

Oto pełne wyniki: https://github.com/KSFTmh/src/blob/master/results-3

Myślę, że jest to wystarczająco inne, aby nie być duplikatem.

Nawiasem mówiąc, po raz pierwszy zadaję pytanie na Stack Exchange, więc daj mi znać, jeśli robię coś źle.

KSFT
źródło
4
Czy naprawdę chcemy takiego pytania?
Optymalizator
5
@Optimizer Kilka osób w komentarzach uznało, że to dobry pomysł. Odpowiedzi z oryginału będą działać tutaj zupełnie inaczej, więc nie sądzę, że to duplikat.
KSFT
1
Zasługą za zasugerowanie wyzwania powinna być @Geobits. Właśnie się z nim zgodziłem.
Logic Knight
1
Mmmm Wygląda na to, że stała liczba ponownie wygrywa. Jestem ciekawy, dlaczego tak jest. Czy możemy zobaczyć 600 liczb wyjściowych w pytaniu lub na github lub pastebin? Podejrzewam, że niektóre z naszych predyktorów mają błędy. Prawdopodobnie mój :-(
Logic Knight
1
@CarpetPython Prostą zmianą byłoby obliczenie odległości między punktami od ostatniego dookoła oprócz punktów z tej rundy.
TheNumberOne

Odpowiedzi:

3

Python 2, Sampler

Ten wpis jest oparty na tym samym kodzie dla Zachowaj odległość, wpis Samplera . Mam nadzieję, że będzie lepiej tutaj, gdzie nie ma zalet 1 i 999.

Z listy miejsc wybierz tę, która jest najbardziej oddalona od ostatnio używanych liczb, ignorując poprzednią kolej (ponieważ inne wpisy mogą przewidywać na podstawie tylko poprzedniej kolejki).

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
Logic Knight
źródło
Wygląda na to, że ten wygrywa, ale może to być spowodowane tym, że nie kompiluję poprawnie kontrolera, a wszystkie inne ulegają awarii.
KSFT
2

Numer OnePlusFourNineNine, Java

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

Logika jest naprawdę prosta. O ile ktoś nie znajdzie prawdziwego algorytmu, który bierze pod uwagę poprzednie wyniki, odpowiedź ta jest dość zoptymalizowana.

Teraz, gdy policzymy odległość w okręgu, maksymalna odległość dowolnych dwóch punktów może wynosić 500. Teraz, gdyby wszystkie wpisy generowały liczby losowe (lub pseudolosowe na podstawie jakiegoś algorytmu), ta odpowiedź w ogóle nie byłaby korzystna . Ale jest co najmniej 1 wpis, który daje stałą odpowiedź, która jest prawie maksymalną odległością. Sprawia, że ​​wynik jest na korzyść 500, ponieważ w każdej rundzie istnieje stałe źródło maksymalnej odległości :)

Optymalizator
źródło
Zoptymalizowałeś moją odpowiedź. ;)
TheNumberOne
@TheBestOne haha
Optymalizator
2

AncientHistorian - Python

Jest to ten sam algorytm z poprzedniego, z wyjątkiem tego, że przy obliczaniu potencjalnych wyników używa odległości kołowej. Ponieważ strasznie przegrywam i nie mogę zmusić kontrolera do kompilacji, po prostu próbuję nowej strategii, w której wykorzystuję najgorsze z poprzednich rund.

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
źródło
To nie działa ijest elementem scores.split(' '), co oznacza, że ​​jest łańcuchem, a nie liczbą całkowitą.
KSFT
@KSFT oh strzelaj, naprawdę powinienem był przetestować i zaktualizować.
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)

Obozowicze wciąż wygrywają. Daj mi znać, jeśli masz jakieś sugestie.

KSFT
źródło
2

FindCampers - Python 2

Znajdź wszystkich obozowiczów z ostatnich 10 rund i trzymaj się od nich z daleka. Mam nadzieję, że predyktory mi uciekną. Teraz zignoruję moje stare wybory.

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
źródło
Aww ... Miałem nadzieję, że to pójdzie w stronę obozowiczów, kiedy zobaczyłem nazwę ...
KSFT
Lol. Mógłbym dodać wpis, który sabotuje obozowiczów.
Jmac
Niestety, dozwolone było tylko jedno wejście na osobę.
KSFT
Właśnie sam opublikowałem wpis dla obozowiczów sabotażowych.
KSFT
Mój nie działa, ponieważ nie zdawałem sobie sprawy, że poprzednie wyniki zostały posortowane. Jak twój wykrywa obozowiczów?
KSFT
1

Numer jeden, Java

Pierwsza odpowiedź. Skopiowano z mojej poprzedniej odpowiedzi .

public static int choose(int round, int players, String[] args) {
    return 1;
}
Numer jeden
źródło
Wygląda na to, że ktoś zanegował wszystkie odpowiedzi.
KSFT
1

WowThisGameIsSoDeep, Java

Analizowałem grę przez 10 lat w klastrze o milionie rdzeni i znalazłem optymalne rozwiązanie.

public static int choose(int round, int players,String[]spam) { return(int)(Math.random()*1e3); }
feersum
źródło
To nie jest kod-golf
Optymalizator
5
To rozwiązanie nie jest optymalne. Jeśli chcesz uzyskać jednolity rozkład, powinieneś użyć Random.nextInt(int).
Peter Taylor
To wydaje się zawsze zwracać 1.
KSFT
@KSFT Przetestowałem to i otrzymałem wiele różnych numerów. Może w końcu to sabotaż?
feersum
4
Aha! Naprawiłem to! Przypadkowo wpisałem „WowThisGameIsSoDeep.py” i próbowałem uruchomić go jako plik Python.
KSFT
1

Ekstrapolator kołowy, 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
histocrat
źródło
To daje następujący błąd:NoMethodError: undefined method `split' for #<Array:0x720f56e2> choose at CircilinearExtrapolator.rb:2
KSFT
Och, czy previous_choicestablica wartości jak ["1 6 500","2 8 503"]?
histocrat
To jest. Myślałeś, że to coś innego? Jeśli nie, prawdopodobnie po prostu coś pomieszałem.
KSFT
Przepraszam, myślałem, że to tylko płaski sznurek. Będę edytować.
histocrat
Edytowane. Teraz wszyscy wiedzą, że coś opublikowałem bez testowania ...
histocrat