Napisz algorytm, który pozwoli zredukować liczbę do jednej cyfry poprzez ciągłe sumowanie cyfr kolejnych wyników. Zastanów się jak możnaby napisać optymalny algorytm, który rozwiąże podane zadanie.
Najprostsze rozwiązanie polega na napisaniu funkcji, która zsumuje wszystkie cyfry podanej liczby. Jeśli suma nie będzie cyfrą to proces ten powtarzamy, aż do uzyskania pojedynczej cyfry. Jest to bezpośrednie podejście, które pozwala na uzyskanie wyniku dla dowolnej liczby. Można to zaimplementować używając zarówno rekurencji jak i zwykłej pętli.
Zaletą powyższego kodu jest jego prostota - łatwo wyszczególnić kolejne etapy. Wadą jest jednak liniowy czas działania programu. Dla bardzo dużych liczb pewne jest to, że pętla wywoła się co najmniej dwa razy.
Przyjrzyjmy się jednak poniższemu kodu funkcji RedukujLiczbe(). W tym przypadku wynik jest zwracany bezpośrednio po sprawdzeniu zaledwie dwóch warunków dla dowolnej liczby.
Na pierwszy rzut oka wydaje się, że to niemożliwe, aby wszystkie powyższe operacje udało się zastąpić przy pomocy jednej operacji dzielenia (dokładniej modulo). Poniższy dowód powinien trochę wyjaśnić:
Przyjmijmy, że liczba a jest dowolna i składa się z n cyfr. Możemy ją zapisać jako sumę cyfr a = 10n-1cn-1 + 10n-2cn-2 + .. + 10c1 + c0. Wykonajmy teraz operację modulo:
10n-1cn-1 + 10n-2cn-2 + .. + 10c1 + c0 = k (mod 9)
Stosując operację modulo na sumę stosujemy ją do każdego czynnika oddzielnie:
(10n-1cn-1 mod 9) + (10n-2cn-2 mod 9) + .. + (10c1 mod 9) + (c0 mod 9) = k (mod 9)
Jak wiadomo 10 mod 9 = 1. Podobnie będzie dla 100 mod 9 = 1 itd. W ten sposób znikną wszystkie 10k, ale zostaną cyfry modulo 9:
(cn-1 mod 9) + (cn-2 mod 9) + .. + (c1 mod 9) + (c0 mod 9) = k (mod 9)
To z kolei będzie się równać:
a mod 9 = cn-1 + cn-2 + .. + c1 + c0 mod 9 = k mod 9
Do przetestowania powyższego kodu można skorzystać z poniższego fragmentu programu: