To druga z serii łamigłówek, które będę publikować w każdy poniedziałek o północy czasu PST. Pierwsza zagadka znajduje się tutaj .
Kontekst:
Samotny miliarder stworzył teleturniej, aby przyciągnąć najlepszych i najzdolniejszych programistów na świecie. W poniedziałki o północy wybiera jedną osobę z grupy kandydatów na uczestnika tygodnia i zapewnia im grę. Jesteś szczęśliwym uczestnikiem tego tygodnia!
Gra w tym tygodniu:
Host zapewnia dostęp API do stosu 10 000 cyfrowych kopert. Te koperty są losowo sortowane i zawierają w nich wartość od 1 do 10 000 USD (żadne dwie koperty nie zawierają tej samej wartości w dolarach).
Do dyspozycji masz 4 polecenia:
Czytaj (): Przeczytaj cyfrę dolara w kopercie u góry stosu.
Take (): dodaj cyfrę dolara z koperty do portfela teleturnieju i zdejmij kopertę ze stosu.
Pass (): Zdejmij kopertę na górze stosu.
Oracle (M): Zwraca średnią wartość następnych M kopert w stosie, nie wliczając tej, którą możesz obecnie odczytać ().
Zasady:
Jeśli użyjesz Pass () na kopercie, pieniądze wewnątrz zostaną utracone na zawsze.
Jeśli użyjesz Take () na kopercie zawierającej $ X, od tego momentu nie możesz nigdy używać Take () na kopercie zawierającej <$ X. Take () na jednej z tych kopert doda 0 USD do Twojego portfela.
Jeśli użyjesz Wyroczni (M) podczas tury T, koperty od T + 1 do T + M zostaną zwrócone. Wyrocznia () jest wyłączona do momentu, aż T + M.
Napisz algorytm, który kończy grę z maksymalną kwotą pieniędzy.
Jeśli piszesz swój algorytm w Pythonie, możesz użyć tego kontrolera dostarczonego przez @Maltysen: https://gist.github.com/livinginformation/70ae3f2a57ecba4387b5
Uwagi 1: „Maksymalne” w tym przypadku oznacza medianę w portfelu po N> = 1000 uruchomień. Oczekuję, choć chciałbym, aby udowodniono, że się mylę, że wartość mediany dla danego algorytmu zbiegnie się, gdy N wzrośnie do nieskończoności. Spróbuj zamiast tego zmaksymalizować średnią, ale mam wrażenie, że średnia jest bardziej narażona na wyrzucenie przez małe N niż mediana.
Uwaga 2: ponieważ wszystkie rozwiązania z poprzedniej części tej układanki są tutaj ważne, ich ponowne opublikowanie ma niewielką wartość. Tylko ulepszenia algorytmiczne poprzednich łamigłówek będą brane pod uwagę w części II.
Edycja: Warunek nagrody został usunięty w świetle tego postu na stronie meta.
źródło
M
wartości, gdzie możesz dokonać wyboruM
.Odpowiedzi:
Groovy
713337817829 818227USDKod bootstrap:
Algorytm
Porównuję pozostałe wartości z możliwymi wartościami. Ten skrypt nie jest szybki (zajmuje 1 minutę na 1000x symulacji) ... ale wykona symulacje jednocześnie.
Nie mam pojęcia, dlaczego mój algorytm działa, ale było to tylko próba i błąd: łączenie operacji matematycznych razem i manipulowanie stałymi. Uruchomiłem go 5000x dla bieżącego wyniku, próbując zmniejszyć wahania wyniku (to +/- 4000 $ w zależności od liczby iteracji).
Nawet bez wyroczni na końcu powinno być (ledwo) pokonanie rozwiązania @ orlp dla poprzedniej układanki.
źródło
C # - 803,603 USD teraz -> 804,760 USD (z wyrocznią)
Kod ładujący
Kod gry:
Kredyt należy do Reto Koradi ( /codegolf//a/54181/30910 )
Edycja: zaimplementowano podstawowe użycie Oracle. Jeśli następna wyrocznia jest powyżej progu, aby użyć, rozwiń bieżącą obwiednię do indeksu Oracle Index. To nie trafia często, ale TO JEST Ulepszenie ;-)
źródło
Python - 74112 USD
Weź tylko, jeśli bieżąca wartość jest niższa niż następna wartość (tzn. Możesz wziąć obie).
Python - (wciąż oblicza średnią)
Ta odpowiedź trwa BARDZO DŁUGO. Osiąga około 670 000 $ . Pamiętam każdą kopertę, którą widziałem. Za każdym razem, gdy muszę podjąć decyzję, generuję dwie listy pozostałych kopert, które potencjalnie mogę dodać do mojego portfela, jeśli odpowiednio wezmę bieżącą kopertę lub ją zostawię.
Nie zoptymalizowałem kodu.
I init_game zaczyna się tak:
źródło
C # - 780,176 USD
Sprawdź, czy następna wartość nie przekracza 5% wszystkich pozostałych wartości. Zbliżamy się do końca.
Moja klasa gry, bardzo brzydka, nie sprawdza nawet, czy wyrocznia jest dozwolona, ale ponieważ używam tylko Oracle (1), nie powinno to stanowić problemu.
źródło
Java, 804,991 USD
Wynik pochodzi z 1001 rund. Prawdopodobnie jest zbyt blisko, aby zadzwonić między tą odpowiedzią a odpowiedzią Stephana Schinkla .
Opiera się to na mojej odpowiedzi z poprzedniego wyzwania, ponieważ używa tego samego obliczenia opartego na entropii do oszacowania wypłat. Główną różnicą jest to, że po prostu teraz pobiera koperty parami (1 i 2, a następnie 3 i 4 itd.) I analizuje możliwe kombinacje odbioru, przyjęcia, podania itp. Oblicza również dokładny szacunkowy wynik, gdy liczba prawidłowych kopert jest naprawdę mała.
„Opakowanie”, które napisałem, tak naprawdę nie jest prawdziwym opakowaniem, po prostu daje koperty parami zamiast wywoływać
Oracle(1)
funkcję co drugą rundę.Ogólnie rzecz biorąc, powiedziałbym, że pomimo zwiększonej złożoności, ten bot naprawdę nie jest lepszy niż mój poprzedni.
Gracz
Kontroler
Adres Bitcoin: 1BVBs9ZEP8YY4EpV868nxi2R23YfL7hdMq
źródło
Python 3 - 615570 USD
W rzeczywistości nie używa wyroczni ... Eh :)
Tworzy listę wszystkich poprzednich kopert i sprawdza, czy bieżąca koperta jest mniejsza niż liczba poprzednich kopert w 10 przyrostach kopert.
źródło
Python, 87 424
Oto prosty i łatwy algorytm, szczęśliwa siódemka.
Zasadniczo konwertuje read () na ciąg znaków i sprawdza, czy jest w nim siedem. Jeśli tak, bierze kopertę. Jeśli nie, to przechodzi.
Średnio wynosi 81 000, nie śledziłem.
źródło