Wprowadzenie
Rozważ ciąg liczb całkowitych f zdefiniowany w następujący sposób:
- f (2) = 2
- Jeśli n jest nieparzystą liczbą pierwszą, to f (n) = (f (n-1) + f (n + 1)) / 2
- Jeśli n = p · q jest złożony, to f (n) = f (p) · f (q)
Nietrudno dostrzec, że f (n) = n dla każdego n ≥ 2 , a zatem obliczenie f nie byłoby bardzo interesującym wyzwaniem. Przekręćmy definicję: połowę pierwszego przypadku i dwukrotność drugiego przypadku. Otrzymujemy nową sekwencję g zdefiniowaną następująco:
- g (2) = 1
- Jeśli n jest nieparzystą liczbą pierwszą, to g (n) = g (n-1) + g (n + 1)
- Jeśli n = p · q jest złożony, to g (n) = g (p) · g (q)
Zadanie
Twoim zadaniem jest przyjęcie liczby całkowitej n ≥ 2 jako wartości wejściowej i uzyskanie g (n) jako wartości wyjściowej. Nie musisz się martwić przepełnieniem liczb całkowitych, ale powinieneś być w stanie poprawnie obliczyć g (1025) = 81 , a twój algorytm powinien teoretycznie działać dla dowolnie dużych danych wejściowych.
Możesz napisać pełny program lub funkcję. Wygrywa najniższa liczba bajtów.
Przykład
Twierdziłem powyżej, że g (1025) = 81 , więc obliczmy to ręcznie. Pierwotna faktoryzacja 1025 daje
1025 = 5*5*41 => g(1025) = g(5)*g(5)*g(41)
Ponieważ 41 jest liczbą pierwszą, otrzymujemy
g(41) = g(40) + g(42)
Następnie obliczamy czynniki pierwsze 40 i 42 :
40 = 2*2*2*5 => g(40) = g(2)*g(2)*g(2)*g(5) = g(5)
42 = 2*3*7 => g(42) = g(2)*g(3)*g(7) = g(3)*g(7)
Za te małe liczby pierwsze otrzymujemy
g(3) = g(2) + g(4) = 1 + 1 = 2
g(5) = g(4) + g(6) = 1 + 2 = 3
g(7) = g(6) + g(8) = 2 + 1 = 3
To znaczy że
g(41) = g(40) + g(42) = g(5) + g(3)*g(7) = 3 + 2*3 = 9
i
g(1025) = g(5)*g(5)*g(41) = 3*3*9 = 81
Przypadki testowe
Oto wartości od g do 50 .
2 -> 1
3 -> 2
4 -> 1
5 -> 3
6 -> 2
7 -> 3
8 -> 1
9 -> 4
10 -> 3
11 -> 5
12 -> 2
13 -> 5
14 -> 3
15 -> 6
16 -> 1
17 -> 5
18 -> 4
19 -> 7
20 -> 3
21 -> 6
22 -> 5
23 -> 7
24 -> 2
25 -> 9
26 -> 5
27 -> 8
28 -> 3
29 -> 9
30 -> 6
31 -> 7
32 -> 1
33 -> 10
34 -> 5
35 -> 9
36 -> 4
37 -> 11
38 -> 7
39 -> 10
40 -> 3
41 -> 9
42 -> 6
43 -> 11
44 -> 5
45 -> 12
46 -> 7
47 -> 9
48 -> 2
49 -> 9
50 -> 9
źródło
15, 21, 25, 29, 33, 41
i wiele innych, ale nie mogę znaleźć żadnego prawdziwego wzoru na to, dlaczego).a(2*n) = a(n)
i obowiązuje,a(2*n+1) = a(n) + a(n+1)
jeśli2*n+1
jest liczbą pierwszą. W przypadku wielu innych liczb nieparzystych sekwencje prawdopodobnie zgadzają się przypadkowo.Odpowiedzi:
Haskell, 69 bajtów
Przykład użycia:
(#2) 1025
->81
Parametr
a
jest zliczany, dopóki się nie podzielix
lub nie osiągniex
(tzn.x
Jest liczbą pierwszą). Jest o jeden bajt krótszy do testowaniaa > x
i dodawania kolejnego warunku (a < x
) do testu modułu zamiast testowaniaa == x
, ponieważ ten pierwszy wiąże sięa
zx+1
, co pomaga w wywołaniu rekurencyjnym. Porównać:źródło
Galaretka , 18 bajtów
Wypróbuj online!
Jest to w zasadzie tylko bezpośrednie tłumaczenie specyfikacji. (Po zastanowieniu się trochę, podejrzewam, że jeśli istnieje zamknięta formuła znalezienia sekwencji, byłoby to więcej bajtów niż bezpośrednie podejście).
Wyjaśnienie
Mamy dwie wzajemnie rekurencyjne funkcje. Oto funkcja pomocnika (która oblicza g (n) dla liczby pierwszej n ):
A oto główny program, który oblicza g (n) dla dowolnego n :
Oczywiście, jeśli wywołujemy program główny na liczbach pierwszych, wszystko nie działa
Ç
, oprócz , więc w tym przypadku zwraca g (n) . Reszta programu obsługuje zachowanie dla złożonego n .źródło
JavaScript (ES6), 59 bajtów
Test
Pokaż fragment kodu
źródło
Python 2,
8569 bajtówźródło
Galaretka , 13 bajtów
Wypróbuj online!
Jak to działa
źródło
Clojure, 126 bajtów
Tak! Jest prawie dwa razy dłuższy niż odpowiedź w Pythonie!
Niegolfowany i wyjaśnienie:
źródło
(.indexOf (for [...] ...) x)
!(t 1025)
, może toif
miało być:when
? Ale potemnth
rzuca pustą listęIndexOutOfBoundsException
.Mathematica, 83 bajty
Nienazwana funkcja rekurencyjna jednego dodatniego argumentu liczby całkowitej, zwracająca liczbę całkowitą. Ostatecznie wcale nie tak krótko.
Tr[#0/@({#-1,#+1}/2)]
(w przypadku, gdy wejście jest liczbą pierwszą) wywołuje funkcję na obu członach uporządkowanej pary{(#-1)/2,(#+1)/2}
i dodaje wyniki; to jest w porządku, ponieważ funkcja ma taką samą wartość co(#-1)/2
i#-1
, na przykład. Podobnie,1##&@@#0/@Divisors@#~Part~{2,-2}
wywołuje funkcję na drugim najmniejszym dzielniku#
i jego uzupełniającym dzielniku (dzielnik drugiej dużej) i mnoży odpowiedzi razem.źródło
#0
w tej odpowiedzi .Clojure, 120 bajtów
Zastosowania
:when
dostać dzielnikin
,F
tonil
jeśli nie zostanie znaleziony taki dzielnik (n
to pierwsze).źródło
Python 2 , 62 bajty
Wypróbuj online!
źródło