04 sierpnia 2018

Szukanie dzielników liczby wprost, odwrócenie mnożenia

Szuka się dzielników liczby w różny sposób. Ale w żadnym miejscu nie spotkałem zwykłego odwrócenia mnożenia. Domyślam się, co jest tego powodem - przeniesienia. Kiedy próbowałem znaleźć funkcję odwrotną do mnozenia od cyfr najmniej znaczących, przeniesienia wyzwalały nieoznaczoność, dzięki czemu znajdowałem zaledwie cyfrę najmniej znaczącą (też nie w każdym przypadku).

Jest jeszcze jeden problem - znajomość długości dzielników, czyli liczność ich bitów. To skomplikowało jeden z algorytmów, w których dopasowywałem liczbę do wzorca bitowego.

Niech zatem a i b będą stosunkowo małymi liczbami binarnymi, oraz dla pewnego wykładnika potegi k mamy
a*b*2^k <= N < a*(b+1)*2^k .
Dalej będę dopasowywał liczbę binarną N do wzorca binarnego W o wartości N, ale subtelniej.Wzorzec przypomina liczbę, lecz na pozycji cyfr mogą stać dowolne liczby nieujemne, ograniczone z góry krotnością bitów przypuszczalnych dzielników. Tzn. jeśli dzielnik ma 7 cyfr, w tym 3 ustawione bity, na żaden pozycji wzorca wartość nie przekroczy 3. Dla liczby 7-bitowej z siedmioma ustawionymi bitami na żadnej pozycji wzorca nie pojawi się wartość większa niż 7.
Na wzorzec najlepiej spojrzeć jak na iloczyn pisemny dwu liczb binarnych, w których nie dokonaliśmy przeniesień, czyli np. 11b * 111b = [1 2 2 1] (po trzech przeniesieniach 10101b).

Pierwsze spostrzeżenie, długość a można przenosić do długości b, o ile a kończy się zerami, tzn. ab = 1100*101 = 11*10100.
A najlepiej niech a i b zaczynają się i kończą ustawionymi bitami, a potrzebną długość pobieramy z k. Dlatego pozwalam by liczba 'binarna' a kończyła się dwójką, np. 12b = 1*2+2=4.

Spstrzeżenie drugie, gdy liczba po lekkiej modyfikacji a_{m+1) = 2a_m będzie mniejsza niż liczba o cyfrach najbardziej znaczących 10..020..011... (krotność zer jest równa), dzielniki na pewno zaczynają się od 10..0... z daną krotnością. W tym przypadku suma długości a*b i potęgi k jest długością liczby N. W innym przypadku suma długości a*b i k jest o 1 mniejsza.

Spostrzeżenie trzecie, jeśli wciskamy liczbę N we wzorzec W dla znalezionych wartości a*b*2^k, możliwe maksymalne przeniesienie cyfr bardziej znaczących N jest pojedynczym bitem na pozycji k+1. Zmniejszając tę wartość znika jedno z przeniesień.

I wydaje mi się, że te spostrzeżenia wystarczą do wyznaczenia dzielników.
Przyjmujemy a=11 lub a=12, dopasowujemy b tak, by schemat dla a*b*2^k był tylko odrobinę większy niż N. Długość b ma być nie mniejsza niż długość a. Dopasowujemy najbardziej znaczące cyfry binarne N do wzorca. Często uzyskamy za dużo, co oznacza, że wzięta została za duża wartość a, należy ją zmniejszyć. Niech jednak a nie kończy się zerem, lecz wartością 1, 2.  
Powinniśmy sprawdzić, czy przypadkiem nie trafiliśmy już na dzielnik.
Jeśli już przekształcimy co się da,  zwiększamy a=2a+1 i znów dopasowujemy b oraz N do wzorca dla a*b. 

Ciąg (a) w kolejnych iteracjach powinien rozbieżnie dążyć do dzielnika. Tyle teoria wg jednego przykładu. A jak praktyka w ogólności?


Detekcja wielokrotności potęg w dużych liczbach

Palindromy mogą służyć jako w miarę prosty detektor, czy dana liczba (odpowiednio duża) jest postaci
N = p*q^k,
operując na mniejszych potęgach a^k.
Pokażę sposób dla k=2.

Liczbę A = 4a+2b+a zapiszemy jako palindrom [a b a]. Reprezentacja ta jest niejednoznaczna, np. nieparzyste A przedstawimy także jako A = [1 (A-5)/2 1]. Niezmienicza jest jednak wartość liczby. Podobnie inne palindromy nad systemem binarnym mają niezmienianą wartość.

Pomnóżmy zachowując strukturę palindromu [...], tzn. nie wykonując przeniesień pomiędzy poszczególnymi pozycjami:
A*A = A^2 = [a^2  2ab  2a^2+b^2  2ab  a^2]
Pomnóżmy to dodatkowo przez Q = [1 c 1]
QA^2 = [a^2   ca^2+2ab   3a^2+b^2+2abc   c(2a^2+b^2)+4ab   3a^2+b^2+2abc   ca^2+2ab   a^2]
Na poszczególnych pozycjach pojawia się stosunkowo prosta kombinacja współczynników.

Wystarczy teraz dopasować wartość liczby N do tych współczynników.
Pragniemy uzyskać jak najprostsza postać, czyli stosunkowo największe a, najmniejsze b i ogromne c. Rozwiązujemy układ równań na a, b, c, przenosząc wartości jak w systemie binarnym, tzn.
schemat [2 -1 0 -12 0 -1 2] oznacza 2*(64+1) - (32+8*12+2)  = 0.
Inny schemat roboczy [0 2 -1 -6 -1 2 0] 


Dla liczby 1087^2 * 8219 takim palindromem jest:
[217^2   217^2*4107+434   1+4107*2*217+3*217^2   4107(1+2*217^2)+2*2*217   1+4107*2*217+3*217^2   217^2*4107+434   217^2]
oraz [217 1 217] = 1087, [1 4107 1] = 8219.

Wartość 1087^2 została zastąpiona przez 217^2, co przy detekcji ma znaczenie.
Dodatkowo, dla liczb nieparzystych a jest zawsze nieparzyste.