Strona główna » Algorytmy » Teoria Liczb » Liczby Anielskie
 

Liczby Anielskie

Wstęp

Liczby Anielskie jest to zjawisko, które polega na widzeniu bardzo często tej samej liczby. Każda liczba ma swoje znaczenie, które można znaleźć na wielu różnych stronach w Internecie. Powiązane z liczbami są niektóre godziny, których numer godziny jest równy minutom. Przykładową godziną Anielską jest 12:12. Istnieją również godziny Półanielskie. W tym przypadku numer godziny jest równy liczbie minut zapisanej wstecz. Przykładową taką godziną będzie 12:21.

Ile godzin Anielskich?

Cel i przygotowanie

Zadanie polega na znalezieniu wszystkich możliwych godzin Anielskich i Półanielskich dla standardowego 24 godzinnego zegarka używanego na całym świecie. Wszystkie godziny zostaną wypisane w formacie HH:MM i zostaną rozdzielone przecinkiem. Do napisania takiego programu przydatna będzie funkcja numLength(), która policzy ile pozycji ma liczba:

Kod:
  1. int numLength(int a) {
  2.   int length = 0;
  3.   do {
  4.     a /= 10;
  5.     length++;
  6.   } while(a > 0);
  7.   return length;
  8. }

Kolejna funkcja, która będzie potrzebna to writeNum(), która będzie pilnowała, że liczby zawsze będą wypisywane jako dwucyfrowe. Funkcja ta będzie przyjmowała dwa argumenty: a - liczba, która ma zostać wypisana oraz pos - ile cyfr ma zostać wypisanych. Jeśli liczba nie będzie korzystała ze wszystkich pos pozycji to przed liczbą a zostanie wypisana odpowiednia ilość zer.

  1. void writeNum(int a, int pos){
  2.   for(int i = 0; i < pos - numLength(a); i++)
  3.     cout << "0";
  4.   cout << a;
  5. }

(2.) Oblicz ile miejsc nie wykorzysta liczba a i (3.) wypisz tyle zer. (3.) Potem wypisz liczbę a.

Wypisywanie godzin Anielskich

Do wypisywanie posłuży bezargumentowa funkcja godzinyAnielskie(). Nie zwraca żadnego wyniku, ponieważ wszystkie rezultaty są bezpośrednio wypisywane na ekran.

  1. void godzinyAnielskie () {
  2.   for(int h = 0; h < 24; h++){
  3.     int m = h;
  4.     if(m >= 0 && m < 60){
  5.       writeNum(h, 2);
  6.       cout << ":";
  7.       writeNum(m, 2);
  8.       cout << ", ";
  9.     }
  10.     int modwr = ((m % 10) * 10) + (m / 10);
  11.     if(modwr != m && modwr >= 0 && modwr < 60){
  12.       writeNum(h, 2);
  13.       cout << ":";
  14.       writeNum(modwr, 2);
  15.       cout << ", ";
  16.     }
  17.   }
  18. }

(2.) Dla każdej prawidłowej numeru godziny: (3.) przypisz minutom numer godziny i (4.) sprawdź czy taka liczba minut jest możliwa i jeśli tak to (5. - 8.) wypisz godzinę. Następnie (10.) oblicz liczbę minut zapisaną wstecz. (11.) Ponownie sprawdź czy taka liczba minut jest możliwa oraz czy liczba zapisana wstecz jest różna od niej zapisanej normalnie. (12. - 15.) Jeśli tak jest to wypisz godzinę.

Testowanie

Powyższa funkcją można przetestować wywołując funkcję godzinyAnielskie().

  1. int main () {
  2.   godzinyAnielskie();
  3.   system("pause");
  4.   return 0;
  5. }

Uogólnienie przypadku

Wprowadzenie

Kolejne zadanie polega na sprawdzeniu godzin anielskich dla dowolnego zegara. Założenie jest takie, że funkcja godzinyAnielskie() będzie przyjmować dwa argumenty, które będą określały górne zakresy wartości godziny i minuty. W ten sposób będzie możliwość zasymulowania zegara 12 godzinnego oraz całkowicie nowych systemów mierzenia czasów w których np. to godziny mogą przyjmować wartości od 0 do 59, a minuty będą z zakresu od 0 do 23.

W uogólnionym przypadku wartości godzin i minut mogą przyjmować dowolne wartości i nie zawsze będą to wartości dwucyfrowe, dlatego pomocna okaże się funkcja liczbaWstecz(), która zwróci wartość liczby a zapisaną wstecz.

  1. int liczbaWstecz(int a, int pos){
  2.   int aWstecz = 0;
  3.   for(int i = 0; i < pos; i++){
  4.     aWstecz *= 10;
  5.     aWstecz += a % 10;
  6.     a /= 10;
  7.   }
  8.   return aWstecz;
  9. }

(1.) Funkcja liczbaWstecz() przyjmuje jeden argument a, a zwróci liczbę a zapisaną wstecz. (2.) Przygotuj zmienną do której będzie zapisywany wynik. (3.) Dla każdej pozycji: (4.) przygotuj miejsce, (5.) dopisz ostatnią cyfrę z liczby a i (6.) usuń ją z tej samej liczby. (8.) Na koniec zwróć wartość zmiennej aWstecz.

Główna funkcja

Podczas dostosowywania funkcji godzinyAnielskie() można założyć, że obydwa argumenty, o ile nie są podane, powinny odpowiadać standardowemu 24 godzinnemu zegarkowi.

  1. void godzinyAnielskie (int maxGodzina = 24, int maxMinuta = 60) {
  2.   int dlGodzina = numLength(maxGodzina);
  3.   if(dlGodzina != numLength(maxMinuta)) {
  4.     cout << "Niepoprawne argumenty";
  5.     return;
  6.   }

(1.) Ustalenie domyślnych wartości jeśli nowe nie zostaną podane. Kolejny etap polega na sprawdzeniu czy dane mają sens. Długość minut oraz godzin musi być równa, ponieważ inaczej nie da rady porównać w żaden sposób podanych danych. (2.) oblicz jaką długość przyjmują godziny, a następnie (3.) sprawdź czy tyle samo co minuty. Jeśli nie to (4.) wypisz komunikat o niepoprawnych danych i (5.) zakończ działanie funkcji.

  1.   for(int h = 0; h < maxGodzina; h++){
  2.     int m = h;
  3.     if(m >= 0 && m < maxMinuta){
  4.       writeNum(h, dlGodzina);
  5.       cout << ":";
  6.       writeNum(m, dlGodzina);
  7.       cout << ", ";
  8.     }
  9.     int modwr = liczbaWstecz(m, dlGodzina);
  10.     if(modwr != m && modwr >= 0 && modwr < maxMinuta){
  11.       writeNum(h, dlGodzina);
  12.       cout << ":";
  13.       writeNum(modwr, dlGodzina);
  14.       cout << ", ";
  15.     }
  16.   }
  17. }

W pozostałej części funkcji zmieniają się: (7.) zakres sprawdzanych godzin, (9.) i (16.) zakres minut. Ponadto przy każdym wywołaniu funkcji writeNum() wartość dwa należy zmienić na wartość zmiennej dlGodzina. W przeciwnym razie program nie będzie prawidłowo wypisywał godzin dla innych systemów mierzenia czasu.

Testowanie funkcji

W celu przetestowania funkcji należy wywołać funkcje godzinyAnielskie() z różnymi wartościami argumentów. Nie trzeba za każdym razem podawać obu argumentów, dlatego, aby odczytać wszystkie godziny anielskie dla zegarka 12 godzinnego wystarczy wpisać w dowolnym miejscu w kodzie:

  1. godzinyAnielskie(12);

Jednak zakładając, że zarówno minuty jak i godziny mogą przyjmować wartości od 0 do 16 to wystarczy wpisać:

  1. godzinyAnielskie(16, 16);

W ten sposób otrzyma się wszystkie godziny Anielskie prawidłowego dla tego systemu czasu. W tym przypadku jest to:

  1. 00:00, 01:01, 01:10, 02:02, 03:03, 04:04, 05:05, 06:06, 07:07, 08:08, 09:09, 10:10, 10:01, 11:11, 12:12, 13:13, 14:14, 15:15