Strona główna » Algorytmy » Artykuły » Redukcja do Cyfry
 

Redukcja do Cyfry

Wstęp

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.

Implementacja

Bezpośrednia

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.

  1. static int RedukujLiczbe(int a)
  2. {
  3.   while (a > 9)
  4.   {
  5.     int suma = 0;
  6.     while (a > 0)
  7.     {
  8.       suma += a % 10;
  9.       a /= 10;
  10.     }
  11.     a = suma;
  12.   }
  13.   return a;
  14. }

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.

Szybka

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.

  1. static int RedukujLiczbe(int a)
  2. {
  3.   if (a == 0) return 0;
  4.   a = a % 9;
  5.   return (a == 0) ? 9 : a;
  6. }

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ć:

Dowód

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

Testowanie funkcji

Do przetestowania powyższego kodu można skorzystać z poniższego fragmentu programu:

  1. static void Main(string[] args)
  2. {
  3.   Console.WriteLine("Podaj liczbę:\n a = ");
  4.   int a = Convert.ToInt32(Console.ReadLine());
  5.   int wynik = RedukujLiczbe(a);
  6.   Console.WriteLine("Po redukcji otrzymujemy: {0}", wynik);
  7.   Console.ReadKey();
  8. }
Zadania
Zadanie 1
Kod źródłowy Zadanie 1Kod źródłowy Zadanie 1Kod źródłowy Zadanie 1