Una svolta di una banale sequenza


15

introduzione

Considera una sequenza di numeri interi f definita come segue:

  1. f (2) = 2
  2. Se n è un numero primo dispari, allora f (n) = (f (n-1) + f (n + 1)) / 2
  3. Se n = p · q è composto, allora f (n) = f (p) · f (q)

Non è molto difficile vedere che f (n) = n per ogni n ≥ 2 , e quindi calcolare f non sarebbe una sfida molto interessante. Diamo una svolta alla definizione: dimezza il primo caso e raddoppia il secondo caso. Otteniamo una nuova sequenza g definita come segue:

  1. g (2) = 1
  2. Se n è un numero primo dispari, allora g (n) = g (n-1) + g (n + 1)
  3. Se n = p · q è composito, g (n) = g (p) · g (q)

L'obiettivo

Il tuo compito è prendere un intero n ≥ 2 come input e produrre g (n) come output. Non devi preoccuparti di overflow di numeri interi, ma dovresti essere in grado di calcolare g (1025) = 81 correttamente e il tuo algoritmo dovrebbe teoricamente funzionare per input arbitrariamente grandi.

È possibile scrivere un programma completo o una funzione. Vince il conteggio dei byte più basso.

Esempio

Ho affermato sopra che g (1025) = 81 , quindi calcoliamolo a mano. La fattorizzazione primaria di 1025

1025 = 5*5*41 => g(1025) = g(5)*g(5)*g(41)

Dal momento che 41 è primo, otteniamo

g(41) = g(40) + g(42)

Successivamente, calcoliamo le prime fattorizzazioni di 40 e 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)

Per questi piccoli numeri primi otteniamo

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

Ciò significa che

g(41) = g(40) + g(42) = g(5) + g(3)*g(7) = 3 + 2*3 = 9

e

g(1025) = g(5)*g(5)*g(41) = 3*3*9 = 81

Casi test

Ecco i valori di g fino a 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

Stranamente simile a A002487 , eppure non (diverso da 15, 21, 25, 29, 33, 41, e un sacco di più, ma non riesco a trovare alcun modello reale per il perché.)
Gabriel Benamy,

@GabrielBenamy Beh, anche la mia sequenza è soddisfacente a(2*n) = a(n), e a(2*n+1) = a(n) + a(n+1)vale se 2*n+1è ottima. Per molti altri numeri dispari le sequenze probabilmente concordano per coincidenza.
Zgarb,

Restituire True invece di 1 è accettabile?
Dennis,

@Dennis la sfida riguarda la valutazione di una funzione numerica, non un problema decisionale, quindi suppongo di no.
Pavel,

1
@Pavel C'è comunque un forte supporto a favore e, almeno in Python, True agisce come 1 a tutti gli effetti.
Dennis,

Risposte:


7

Haskell, 69 byte

x#a|x<3=1|a>x=a#2+(x-1)#2|mod x a<1,a<x=a#2*div x a#2|b<-a+1=x#b
(#2)

Esempio di utilizzo: (#2) 1025->81

Il parametro aviene conteggiato fino a quando non si divide xo raggiunge x(ovvero xè primo). Esso è un byte più corta per verificare a > xe aggiungere un ulteriore condizione ( a < x) per il test di modulo, invece di test per a == x, perché gli ex si lega aa x+1, che aiuta nella chiamata ricorsiva. Confrontare:

|a==x=(x+1)#2+(x-1)#2|mod x a<1=
|a>x=a#2+(x-1)#2|mod x a<1,a<x=

4

Gelatina , 18 byte

‘;’Ñ€Sµ1n2$?
ÆfÇ€P

Provalo online!

Questa è fondamentalmente solo una traduzione diretta delle specifiche. (Dopo averci pensato un po ', sospetto che se esiste una formula chiusa per trovare la sequenza, sarebbe più byte dell'approccio diretto.)

Spiegazione

Abbiamo due funzioni reciprocamente ricorsive. Ecco la funzione helper (che calcola g (n) per prime n ):

‘;’Ñ€Sµ1n2$?
           ?  If
        n2$     the input is not equal to 2 (parsed as a group due to $)
      µ       then do all the following (parsed as a group due to µ):
‘;’             Find the list [n+1, n-1];
   р           Call the main program on each element (i.e. [g(n+1),g(n-1)]);
     S          and return the sum of the list (i.e. g(n+1)+g(n-1)).
              Otherwise:
       1        Return 1.

Ed ecco il programma principale, che calcola g (n) per qualsiasi n :

ÆfÇ€P
Æf            Factorize the input into its prime factors;
  ǀ          Call the helper function on each element of that list;
    P         Then take the product.

Chiaramente, se chiamiamo il programma principale su un numero primo, tutto è no-op tranne il Ç, quindi in questo caso restituisce g (n) . Il resto del programma gestisce il comportamento del composito n .


4

JavaScript (ES6), 59 byte

f=(n,d=2)=>n-2?d<n?n%d?f(n,d+1):f(n/d)*f(d):f(n-1)+f(n+1):1

Test


3

Python 2, 85 69 byte

g=lambda n,k=3:(n&~-n<1)or n%k and g(n,k+2)or(g(k+1)+g(k-1))*g(n/k,k)

3

Gelatina , 13 byte

Æfḟ2µ‘,’߀€SP

Provalo online!

Come funziona

Æfḟ2µ‘,’߀€SP  Main link. Argument: n

Æf             Yield the array of prime factors of n.
  ḟ2           Remove all occurrences of 2.
    µ          Begin a new, monadic chain. Argument: A (array of odd prime factors)
     ‘         Increment all elements of A.
       ’       Decrement all elements of A.
      ,        Pair; yield [A+1, A-1].
        ߀€    Map the main link over all elements of A+1 and A-1.
           S   Column-wise reduce by addition.
            P  Reduce by multiplication.

3

Clojure, 126 byte

(defn t[n](if(= n 2)1(let[a(+(.indexOf(for[b(range 2 n)](mod n b)2)0))](if(> a 1)(*(t(/ n a))(t a))(+(t(dec n))(t(inc n)))))))

Sìì! È quasi il doppio della risposta di Python!

Ungolfed e una spiegazione:

(defn trivial [n]
  ; Define the function.
  (if (= n 2) 1
  ; If the number is 2, return 1
    (let [a (+ 2 (.indexOf (for [b (range 2 n)] (mod n b)) 0))]
      ; Let a be the lowest prime factor of n
      (if (> a 1)
        ; The .indexOf function returns -1 if a is a prime, so -1 + 2 = 1.
        ; Checks if a is a prime.
        (* (trivial (/ n a)) (trivial a))
        ; If a is prime, return the trivial(a/n) * trivial(a).
        (+ (trivial (dec n)) (trivial (inc n)))))))
        ; Else, return trivial(n-1) + trivial(n + 1).

Bene, non sapevo che tu potessi fare (.indexOf (for [...] ...) x)!
NikoNyrh,

L'attuale versione a 118 byte restituisce 11 per (t 1025), forse che ifdoveva essere :when? Ma poi vengono nthlanciati elenchi vuoti IndexOutOfBoundsException.
NikoNyrh,

@NikoNyrh Sì, non dovrebbe succedere - l'ho provato anche io e il codice non è valido. Tornerà alla versione originale.
clismique,

2

Mathematica, 83 byte

Which[#<4,#-1,PrimeQ@#,Tr[#0/@({#-1,#+1}/2)],0<1,1##&@@#0/@Divisors@#~Part~{2,-2}]&

Funzione ricorsiva senza nome di un argomento intero positivo, che restituisce un numero intero. Non così corto, alla fine. Tr[#0/@({#-1,#+1}/2)](nel caso in cui l'ingresso sia primo) chiama la funzione su entrambi i membri della coppia ordinata {(#-1)/2,(#+1)/2}e aggiunge i risultati; questo va bene poiché la funzione ha lo stesso valore in (#-1)/2e #-1, ad esempio. Allo stesso modo, 1##&@@#0/@Divisors@#~Part~{2,-2}chiama la funzione sul secondo divisore più piccolo #e il suo divisore complementare (il secondo divisore più grande) e moltiplica le risposte insieme.


Come funzionano le funzioni ricorsive senza nome?
Pavel,

1
Dai un'occhiata alla sezione su #0in questa risposta .
Greg Martin,

2

Clojure, 120 byte

(defn g[n](if(= n 2)1(if-let[F(first(for[i(range 2 n):when(=(mod n i)0)]i))](*(g F)(g(/ n F)))(+(g(dec n))(g(inc n))))))

usi :when per ottenere divisori di n, Fè nilse tale divisore non viene trovato ( nè primo).


Desidera litigare, signore? E 'acceso. (Competizione amichevole?)
clismique il

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.