Algorytmy obliczające, jeśli liczba jest wielokrotnością liczby 3


13

Wykonując rachunek psychiczny, możesz:

  • Biorąc pod uwagę liczbę całkowitą k, zsumuj wszystkie cyfry (w podstawie 10), a jeśli wynikiem jest wielokrotność 3, to k jest wielokrotnością 3.

Czy znasz algorytm działający podobnie, ale działający na cyfrach binarnych (bitach)?

  • Najpierw zastanawiałem się nad użyciem gotowych funkcji mojego języka konwertujących liczbę całkowitą na ascii, aby wykonać konwersję z bazy 2 na bazę 10, a następnie zastosować sztuczkę rachunku różniczkowego. Ale oczywiście mógłbym również samodzielnie zakodować konwersję podstawową 2 na 10. Jeszcze tego nie zrobiłem, ale spróbuję.

  • Potem pomyślałem o podziale euklidesowym w bazie 2 ...

Zastanawiam się jednak, czy istnieją inne środki, algorytmy.


Odpowiedzi:


22

Rozważ następujące dwie uwagi (pozostawione czytelnikowi jako ćwiczenie):

  1. Parzyste potęgi dwóch to 1 moduł 3.
  2. Dziwne potęgi dwóch to -1 modulo 3.

Dochodzimy do wniosku, że liczba (binarnie) jest podzielna przez trzy wtedy i tylko wtedy, gdy suma bitów w pozycjach parzystych jest równa sumie bitów w pozycjach nieparzystych modulo 3.


7
To jest jak reguła dzielenia przez 11 w systemie dziesiętnym.
Yuval Filmus

1
@YuvalFilmus: Dokładnie. Zamierzałem dodać kolejne ćwiczenie dla czytelnika, ale zdecydowałem się tego nie robić.
mhum,

3
OK, co powiesz na sprawdzenie, czy liczba zapisana w systemie szesnastkowym jest podzielna przez 17 (dziesiętnie)? Lub 15 (dziesiętnie) w tej sprawie? ;-)
vonbrand

33

Co z automatem skończonym dla zadania?

wprowadź opis zdjęcia tutaj

Oczywiście magia jest tylko obliczenie modulo 3. Dodanie symbolu ciąg za oznacza „wartość binarna” łańcucha idzie od dla do dla . W konsekwencji ze stanu i symbolu przechodzimy do stanu , dla i . Uwaga jest łańcuchem, wheras jest jego wartością jako ciąg binarny.x v a l ( x ) x 2 v a l ( x ) + a x a p a 2 p + a mod 3 p { 0 , 1 , 2 } a { 0 , 1 } x { 0 , 1 } v a l ( x ) Naxval(x)x2val(x)+axapa2p+amod3p{0,1,2}a{0,1}x{0,1}val(x)N


1
Podoba mi się ten pomysł, spróbujmy z 9. Karmię 1001 binarnie. Pierwszy bit wysyła mnie do stanu 1, następnie do stanu 2, następnie do stanu 1, a następnie z powrotem do stanu 0. Zatem stan 0 jest wielokrotnością 3. A złożonością algorytmu jest liczba użytych bitów, nic więcej. To jest zajebiste !
Stephane Rolland

Czy ta koncepcja w linku jest powiązana? Myślę, że jest to prostsze. geomathry.wordpress.com/2017/02/13/0-1-and-a-new-number

1
@WaqarAhmad Tak, powiązane, nie prostsze. Przejścia w skończonym automacie można również wykorzystać do opisania oceny L2R, tak jak w wyjaśnieniu. Przejścia definiują , , , , , . Tutaj mamy trzy stany, więc potrzebne są trzy symbole stanów. Twoje symbole to odpowiednio oceny liczb modulo , a pierwszym symbolem w twojej ocenie L2R jest „stan”. Jeśli chcesz dyskusji, być może lepiej zacząć nowe pytanie na stronie! ˉ 0 1= ˉ 1 ˉ 1 0= ˉ 2 ˉ 1 1= ˉ 0 ˉ 2 0= ˉ 1 ˉ 2 1= ˉ 2 Θ,1,01,2,00¯0=0¯0¯1=1¯1¯0=2¯1¯1=0¯2¯0=1¯2¯1=2¯Θ,1,01,2,0
Hendrik Jan

Nie o programowaniu. Czy to będzie bardziej wydajne w komputerze trójskładnikowym?

4

W systemie dwójkowym liczby 1, 100, 10000 (= 100 × 100), 1000000 (= 100 × 100 × 100) itd. Dają tę samą resztę po podzieleniu przez 11 (trzy). Dlatego jeśli podzielimy liczbę binarną na części o parzystej długości , suma części daje taką samą resztę jak liczba pierwotna.

(Przy dzieleniu liczby dodajemy tyle zer, ile potrzeba na początku . Na przykład podzielilibyśmy 10111 na grupy 01,11 lub 0001,0111.)

Matematycznie, tylko podzielić liczbę na grupy dwóch cyfr, a następnie dodać do grupy; i powtarzaj to, aż wynik wyniesie 00 lub 11 = pierwotna liczba była wielokrotnością trzech; lub 01 lub 10 = pierwotny numer nie był wielokrotnością trzech.

W przypadku programu komputerowego użycie grup po osiem, szesnaście lub trzydzieści dwa bity może być szybsze dla twojego procesora. Na przykład, jeśli dodawanie ośmiobitowe jest najszybsze, po prostu zrób sumę wszystkich bajtów i jeszcze raz, aż wynik zmieści się w jednym bajcie. Następnie użyj jednej instrukcji, aby określić pozostałość po podzieleniu przez trzy.

(Uwaga: zakładamy tutaj liczby całkowite bez znaku . Przy podpisanym numerze wymaga nieco więcej uwagi. Na przykład 129 to wielokrotność 3, ale -127 nie, chociaż bity 10000001 oznaczają dla byłego jako bajt niepodpisany i ten ostatni jako bajt podpisany).


0

Powtarzane odejmowanie, choć nie jest specyficzne dla danych binarnych, zawsze stanowi pewny sposób na obliczenie dzielenia z resztą (a zatem, jeśli liczba jest wielokrotnością liczby 3).


2
Powtarzające się odejmowanie to zły pomysł. Podział z resztą jest znacznie szybszy.
Yuval Filmus

3
prawdopodobnie bardzo kosztowne w procesorze, ale jest to inny algorytm :-), który nie zasługuje na -1 :-(
Stephane Rolland
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.