To wyzwanie jest częściowo wyzwaniem algorytmów, częściowo wyzwaniem optymalizacji, a częściowo po prostu najszybszym wyzwaniem kodu.
Cykliczna macierz jest w pełni określona przez jej pierwszy wiersz r
. Pozostałe rzędy to cykliczne permutacje wiersza r
z przesunięciem równym indeksowi wiersza. Dopuszczamy macierze cykliczne, które nie są kwadratowe, tak że po prostu brakuje niektórych ostatnich wierszy. Zawsze jednak zakładamy, że liczba wierszy jest nie większa niż liczba kolumn. Na przykład rozważmy następującą macierz cykliczną 3 na 5.
10111
11011
11101
Mówimy, że macierz ma właściwość X, jeśli zawiera dwa niepuste zbiory kolumn o nieidentycznych indeksach, które mają tę samą (wektorową) sumę. Suma wektorowa dwóch kolumn jest po prostu elementarnym sumowaniem dwóch kolumn. To jest suma dwóch kolumn zawierających x
elementy, z których każda jest kolejną kolumną zawierającą x
elementy.
Powyższa macierz w sposób trywialny ma właściwość X, ponieważ pierwsza i ostatnia kolumna są takie same. Matryca tożsamości nigdy nie ma właściwości X.
Jeśli po prostu usuniemy ostatnią kolumnę macierzy powyżej, otrzymamy przykład, który nie ma właściwości X i dałby wynik 4/3.
1011
1101
1110
Zadanie
Zadaniem jest napisanie kodu w celu znalezienia macierzy cyklicznej o najwyższym wyniku, której wszystkie wpisy to 0 lub 1 i która nie ma właściwości X.
Wynik
Twój wynik będzie liczbą kolumn podzieloną przez liczbę wierszy w najlepszej macierzy punktacji.
Tie Breaker
Jeśli dwie odpowiedzi mają ten sam wynik, wygrywa ten, który przesłał pierwszy.
W (bardzo) mało prawdopodobnym przypadku, gdy ktoś znajdzie sposób na uzyskanie nieograniczonej liczby punktów, zostanie zaakceptowany pierwszy ważny dowód takiego rozwiązania. W jeszcze bardziej mało prawdopodobnym przypadku, w którym można znaleźć dowód na optymalizację skończonej macierzy, oczywiście przyznam również zwycięstwo.
Wskazówka
Uzyskanie wyniku 12/8 nie jest zbyt trudne.
Języki i biblioteki
Możesz używać dowolnego języka, który ma swobodnie dostępny kompilator / tłumacz / etc. dla systemu Linux i dowolnych bibliotek, które są również bezpłatnie dostępne dla systemu Linux.
Wiodące wpisy
- 36/19 autor: Peter Taylor (Java)
- 32/17 autor: Suboptimus Prime (C #)
- 21/12 autor: justhalf (Python 2)
źródło
01
ma właściwość X, ponieważ zbiór pierwszej kolumny ma tę samą sumę wektorów, co pusty zbiór. Być może chodziło Ci o niepuste zestawy kolumn? Myślę, że to czystsze, żeby tego nie zmieniać.01
ma własność X:(1) = (0) + (1)
. Jeśli chcesz to wykluczyć, powinieneś powiedzieć, że dwa zestawy kolumn muszą być rozłączne.2^m
m * 2^(m/2)
Odpowiedzi:
16/9 20/11 22/12 28/15 30/16 32/17 34/1836/19 (Java)Wykorzystuje to szereg pomysłów w celu zmniejszenia przestrzeni wyszukiwania i kosztów. Zobacz historię zmian, aby uzyskać więcej informacji na temat wcześniejszych wersji kodu.
0
i1
) i opracowując; Używam algorytmu opisanego w kodzie A Gray dla naszyjników o stałej gęstości i słów Lyndona w stałym zamortyzowanym czasie , Sawada i Williams, Theoretical Computer Science 502 (2013): 46-54.BigInteger
dokładnym testem. Dostaję znaczną poprawę prędkości, ryzykując fałszywe negatywy, operując modulo dużą liczbą pierwszą i utrzymując wszystko w prymitywach. Wybrana przeze mnie liczba pierwsza jest największa mniejsza niż 2 57 , ponieważ pozwala to na pomnożenie przez podstawę mojej reprezentatywnej reprezentacji wektorowej bez przepełnienia.{-1,0,1}^m
ma swoją negację,{-1,0,1}^m
dlatego konieczne jest przechowywanie tylko jednego z nich.2n/(n+1)
, przyspieszam to, testując to.Pierwszy znaleziony to
i to jedyny hit w ciągu 15 godzin.
Mali zwycięzcy:
źródło
n
raczej używać niżrows
, chociaż jest bezpieczny w tym sensie, że odrzuciłby prawidłowe rozwiązania, zamiast zaakceptować nieprawidłowe. Nie wpływa również na wyniki.Python 2 - 21/12
W trakcie udowadniania, że
2-(3/n)
zawsze istnieje dla każdegon
Zainspirowany tym pytaniem użyłem De Bruijn Sequence do brutalnej siły możliwych matryc. A po brutalnym forsowaniu
n=6,7,8,9,10
znalazłem wzór, w którym najwyższe rozwiązanie jest zawsze w kształcie(n, 2n-3)
.Stworzyłem więc kolejną metodę brutalizacji siły tego kształtu matrycy i używam przetwarzania wieloprocesorowego, aby przyspieszyć, ponieważ to zadanie jest wysoce rozdzielne. W 16-rdzeniowym Ubuntu może znaleźć rozwiązanie
n=12
w ciągu około 4 minut:Większość obliczeń idzie na sprawdzenie właściwości X, która wymaga sprawdzenia wszystkich podzbiorów (istnieją
2^(2n-3)
podzbiory)Zauważ, że obracam pierwszy rząd w lewo, a nie w prawo, jak w pytaniu. Ale są one równoważne, ponieważ można po prostu odwrócić całą macierz. =)
Kod:
Stara odpowiedź w celach informacyjnych
Jak dotąd optymalne rozwiązanie (
n=10
):Dla
n=7
:Rozwiązanie o kształcie opisanym przez OP (
n=8
):Ale lepszy (
n=8
):Znalazł również inne optymalne rozwiązanie w
n=9
:Kod jest następujący. To tylko brutalna siła, ale przynajmniej może znaleźć coś lepszego niż twierdzenie OP =)
źródło
n >= 31
, co oznacza, że muszę sprawdzić2^(2n-3) = 2^59
kombinacje 31-wymiarowego wektora. Nie skończymy za naszego życia = Dn*(2n-3)
24/13 26/14 28/15 30/1632/17 (C #)Edycja: Usunąłem nieaktualne informacje z mojej odpowiedzi. Używam głównie tego samego algorytmu, co Peter Taylor ( edycja: wygląda na to, że używa teraz lepszego algorytmu), chociaż dodałem kilka własnych optymalizacji:
HasPropertyXFast
funkcję, która szybko sprawdza, czy jest mały zestaw z równymi sumami, zanim zastosujesz podejście „spotkaj się w środku”.HasPropertyXFast
funkcji, zaczynam od sprawdzenia zestawów kolumn z 1 kolumną, następnie z 2, 3 i tak dalej. Funkcja powraca, gdy tylko zostanie znalezione pierwsze zderzenie sum kolumn. W praktyce oznacza to, że zwykle muszę sprawdzić tylko kilkaset lub tysiące zestawów kolumn zamiast milionów.long
zmiennych do przechowywania i porównywania całych kolumn i ich wektorów. Takie podejście jest co najmniej o rząd wielkości szybsze niż porównywanie kolumn jako tablic.long
typu danych i wzorców użytkowania.Wyjście programu:
Kod:
Plik konfiguracyjny:
źródło
ulong
i pozwolenie owinięciu shift zamiast używaniaBigInteger
.GetSumOfColumns
krotność i dodaje dodatkową pętlę, którą spodziewałbym się kosztować więcej niż 2-krotny współczynnik. Sortowanie masek brzmi interesująco: może mógłbyś edytować odpowiedź, aby trochę o tym porozmawiać? (W pewnym momencie eksperymentuję z alternatywnym sposobem wykonania wczesnego przerwania: powodem, dla którego nie mogę tego zrobić, jest to, że HashSet nie obsługuje jednoczesnej iteracji i modyfikacji, ale mam pomysły, aby uniknąć potrzeby iteratora) .