Walczę z tym problemem, który znalazłem w konkurencyjnej książce programistycznej, ale bez rozwiązania, jak to zrobić.
Dla danych dwóch liczb całkowitych A i B (mieszczących się w 64-bitowych liczbach całkowitych), gdzie A jest nieparzysty, znajdź parę liczb X i Y taką, że A = X * Y i B = X x lub Y. Moje podejście polegało na wyliczeniu wszystkie dzielniki liczby i spróbuj sparowaniu numery pod sqrt (a) z numerami na sqrt (a), które mnożą się na a i sprawdzić, czy ich xor jest równe B . Ale nie wiem, czy to wystarczy. Jakie byłoby dobre rozwiązanie / algorytm dla tego problemu?
algorithm
bit-manipulation
Aster W.
źródło
źródło
X*Y
czyX&Y
?Odpowiedzi:
Oto prosta rekurencja, która przestrzega znanych nam reguł: (1) ustawione są najmniej znaczące bity zarówno X, jak i Y, ponieważ tylko nieparzyste wielokrotności dają nieparzystą wielokrotność; (2) jeśli ustawimy X na najwyższy ustawiony bit B, Y nie może być większe niż sqrt (A); i (3) ustawić bity w X lub Y zgodnie z bieżącym bitem w B.
Poniższy kod w języku Python dał wynik poniżej 300 iteracji dla wszystkich losowych par oprócz jednej, którą wybrałem z przykładowego kodu Matta Timmermansa . Ale pierwsza miała 231.199 iteracji :)
Wynik:
źródło
Wiesz, że co najmniej jeden czynnik to <= sqrt (A). Zróbmy to X.
Długość X w bitach będzie wynosić około połowy długości A.
Dlatego górne bity X - te o wyższej wartości niż sqrt (A) - są równe 0, a odpowiednie bity w B muszą mieć tę samą wartość co odpowiadające bity w Y.
Znajomość górnych bitów Y daje całkiem mały zakres dla odpowiedniego współczynnika X = A / Y. Oblicz Xmin i Xmax odpowiadające odpowiednio największej i najmniejszej możliwej wartości Y. Pamiętaj, że Xmax musi być również <= sqrt (A).
Następnie wypróbuj wszystkie możliwe Xs między Xmin i Xmax. Nie będzie ich zbyt wiele, więc nie potrwa to długo.
źródło
Drugi prosty sposób rozwiązania tego problemu polega na tym, że niższe n bitów XY i X xor Y zależy tylko od niższych n bitów X i Y. Dlatego możesz użyć możliwych odpowiedzi dla niższych n bitów, aby ograniczyć możliwe odpowiedzi dla niższych bitów n + 1 , dopóki nie skończysz.
Odkryłem, że niestety może istnieć więcej niż jedna możliwość dla jednego n . Nie wiem, jak często będzie wiele możliwości, ale prawdopodobnie wcale nie jest to zbyt często, więc może być dobrze w kontekście konkurencyjnym. Prawdopodobnie będzie tylko kilka możliwości, ponieważ rozwiązanie dla n bitów zapewni albo 0, albo dwa rozwiązania dla n + 1 bitów, z jednakowym prawdopodobieństwem.
Wydaje się, że działa całkiem dobrze w przypadku losowego wprowadzania. Oto kod, którego użyłem do przetestowania:
Możesz zobaczyć wyniki tutaj: https://ideone.com/cEuHkQ
Wygląda na to, że zwykle zajmuje to tylko kilka tysięcy czeków.
źródło