Permutacyjna liczba pierwsza to taka liczba naturalna, która jest liczbą pierwszą i każda permutacja jej cyfr tworzy również liczbą pierwszą. Takie liczby znane są również pod nazwą absolutne liczby pierwsze. Dla przypomnienia: liczba pierwsza to taka liczba naturalna, która jest podzielna tylko przez samą siebie oraz jeden. Liczbą pierwszą nie jest 1.
Najmniejszą permutacyjną liczba pierwszą jest 2. Do tej grupy liczb należą wszystkie liczby pierwsze jednocyfrowe, ponieważ ich jedyna permutacja to ich oryginalna wartość. Przykładowej dwucyfrowej permutacyjnej liczby pierwszej jest 17, ponieważ zarówno 17 jak i 71 są liczbami pierwszymi. Jako przykład trzycyfrowej takiej liczby można podać 113, która wraz z permutacjami 131 i 311 jest permutacyjną liczbą pierwszą.
Pierwsze 10 wyrazów permutacyjnych liczb pierwszych to: 2, 3, 5, 7, 11, 13 ,17, 31, 37, 71, ...
W przypadku sprawdzania specjalnych właściwości znalezionej liczby pierwszej należy pamiętać, że należy sprawdzić wszystkie jej permutacje czy też są liczbami pierwszymi. Kod realizujący takie sprawdzenie wygląda następująco:
(1.) Funkcja isPermutablePrime() przyjmuje jeden argument a, który określa liczbę do sprawdzenia, a wynikiem działania funkcji jest wartość logiczna sprawdzanego warunku. Nowe permutacje będzie łatwiej tworzyć jeśli liczba będzie zapisana jako lista cyfr, dlatego: (2.) alokacja pamięci pod cyfry i (3. - 6.) zapisanie na liście kolejnych cyfr (w kolejności odwrotnej). Następnie (7.) pobierany jest wynik sprawdzania wszystkich permutacji, (8.) dealokowana jest zarezerwowana pamięć i (9.) zwracany jest wynik.
Wszystkie kombinacje sprawdza funkcja permute(). Przyjmuje ona trzy argumenty: data - tablica z cyframi do permutowania, l - określa ile już wykonano zamian oraz r - ile zamian powinno zostać wykonanych.
(2.) Jeśli została uzyskana nowa permutacja to: (3. - 7.) zamień tablicę cyfr na liczbę i (8.) zwróć wynik testu pierwszości odczytanej liczby. (9.) Jednak jeśli permutacja nie jest ukończona to (10.) dla każdej cyfry na liście: (11.) przeprowadź zamiany dla i-tej cyfry z ostatnią. (12.) Sprawdź wynik dotychczasowych permutacji i jeśli któraś z permutacji liczb nie jest pierwsza to (13.) zwróć fałsz. Jeśli jednak (14.) znalezione dotychczas permutacje są pierwsze to wycofaj zmiany permutacji. Jeśli pętla for zakończy się i nie zostanie zwrócony fałsz to znaczy, że wszystkie permutacje są pierwsze i wtedy (17.) zwróć prawdę.
Powyższe funkcje korzystały z dwóch funkcji pomocniczej. Jedna z nich zamieniała dane na wybranych pozycjach:
Druga isPrime() sprawdzała czy podana liczba jest liczbą pierwszą:
Przy pomocy poniższej funkcji można wypisać wszystkie permutacyjne liczby pierwsze z zakresu [2, 1000].
Pozostaje jednak pytanie ile jest unikalnych permutacji liczb pierwszych. Założenie polega na tym, że jeśli została już wcześniej wypisana permutacja jakieś liczby pierwszej to już dalsze permutacje tej liczby pierwszej nie będą wypisywane. Przykładowo jeśli zostanie już wypisane 113 to żadna z permutacji 131 i 113 nie zostanie wypisana.
Wtedy pierwsze 10 wyrazów permutacyjnych liczb pierwszych to: 2, 3, 5, 7, 11, 13 ,17, 37, 79, 113, ...
Jednym ze sposobów na rozwiązanie tego zadania byłoby zapisać wszystkie znalezione permutacyjne liczby pierwsze, a następnie przed wypisaniem kolejnej znalezionej sprawdzić czy nie jest permutacją którejś z poprzednich. Takie rozwiązanie jest prawidłowe, ale mało efektywne.
Zdecydowanie lepszym pomysłem jest zapamiętywanie minimalnej wartości wszystkich znalezionych permutacji, a następnie wypisanie liczby tylko pod warunkiem, że wypisywana liczba jest równa minimalnej znalezionej permutacji. Początkowo za minimalną wartość można przyjąć podaną liczbę. Powyższy kod wymaga drobnej poprawki, aby realizował nowe zadanie.
Przede wszystkim funkcja permute() musi przyjmować dodatkowy argument min, który będzie sprawdzaną liczbą. Jeśli okaże się, że któraś z permutacji jest mniejsza od min to znaczy, że nie będzie to najmniejsza permutacyjna liczba pierwsza z danej grupy permutacji.
(1.) Funkcje permute() musi przyjmować dodatkowy argument min. (8.) Tym razem wyliczona permutacja musi nie tylko spełnić test pierwszości, ale również jej wartość musi być większa bądź równa podanemu argumentowi min. Oczywiście w trakcie (12.) rekurencyjnego wywołania funkcji należy pamiętać, że funkcja potrzebuje podania dodatkowego argumentu.
Funkcja isPermutablePrime() potrzebuje (3.) zapamiętać wartość a, która dalej jest modyfikowana oraz (9.) należy podać tę wartość funkcji permute() jako dodatkowy argument.
Funkcję można przetestować przy pomocy poprzednio podanej funkcji main().
Napisz program, który będzie działał na zasadzie drugiego zadania, ale będzie wypisywał nie minimalną, ale maksymalną wartość permutacji znalezionej permutacyjnej liczby pierwszej.
Wynik działania funkcji powinien być następujący (w przypadku zakresu [2, 1000]):