Calcola una sequenza intera derivata da fattori primi


10

Creare una funzione, un'espressione o un programma che procede come segue:

  1. Prendi i fattori primi di qualsiasi numero e sommali. Ad esempio, i fattori primi di 28 sono 2 2 7, sommati a 11.
  2. Moltiplicare il risultato per il numero di fattori primi per il numero dato. Ad esempio, 28 ha 3 fattori primi che si sommano a 11. 11 * 3 è 33.
  3. Ripeti il ​​processo in modo ricorsivo, memorizzando l'elenco risultante (che inizia con il numero originale), fino a raggiungere un numero già incluso nell'elenco. Arrestare senza aggiungere quel numero finale, in modo che l'elenco non contenga duplicati. La progressione per 28 è 28 33, perché 33 risulta nuovamente in 28.
  4. Contare gli elementi nell'elenco risultante. Nel caso di 28, la risposta è 2.

Ecco i risultati per 0<n<=10, quindi puoi controllare il tuo algoritmo.

2 1 1 10 1 11 1 9 5 10

(Come sottolineato da Balpha, la risposta per higley(1)è 2, dall'elenco 1 0. Inizialmente avevo 1, a causa di un bug nel mio algoritmo originale scritto in J.)

Dato che sono un presuntuoso SOB e non l'ho trovato su OEIS , chiamiamolo "Higley Sequence", almeno per la durata di questo round di code golf. Come bonus aggiuntivo, trova i primi due ncon il più basso higley(n)dove nnon è primo e n>1. (Penso che ce ne siano solo due, ma non posso provarlo.)

Questo è il golf di codice standard, quindi come al solito vincono il minor numero di tasti, ma ti chiedo per favore di dare una risposta intelligente in altre lingue, anche se sono prolissi.


4
Perché lo è highley(1) == 1? Uno non ha fattori primi, quindi l'elenco risultante in 4) è [1, 0], così highley(1) == 2come la vedo io.
balpha,

Possiamo supporre che il numero di input e i valori intermedi non saranno maggiori di 2 ^ 31-1 (ovvero si inserisce in un numero intero a 32 bit con segno)?
Peter Taylor,

@Peter Taylor Sicuro.
Gregory Higley,

Nel caso in cui qualcuno lo trovi utile, le sequenze OEIS vagamente correlate e che possono fornire qualche ispirazione sono A001414, A001222 e A002217.
Peter Taylor,

1
dato che non hai commentato suppongo che non l'abbia notato: ho dimostrato che ci sono solo i due punti fissi non primi e l'ho aggiunto come appendice al mio post.
Peter Taylor,

Risposte:


6

J, 47 45

#@((~.@,[:(+/@{:*+/@:*/)2 p:{:)^:_)`2:@.(=&1)

È possibile che questo sarebbe molto più breve senza usare ^:_, ma il mio cervello è già sufficientemente fritto.

Modifica: (47-> 45) Giorno doppio coupon.

Uso:

   higley =: #@((~.@,(+/@{:*+/@:*/)@(2&p:)@{:)^:_)`2:@.(=&1)
   higley 1
2
   higley"0 (1 + i. 10)
2 1 1 10 1 11 1 9 5 10

Wow! Una soluzione AJ più corta di una soluzione GolfScript. Il primo che ho visto. (Sono un grande fan di J.)
Gregory Higley,

3
Puoi accorciarlo considerevolmente usando un algoritmo leggermente diverso:, #@((~.@,((+/*#)@:q:)@{:)^:_)`2:@.(=&1)che è di 38 caratteri.
Gregory Higley,

Wow, ho provato a capire come farlo con q: ma stavo cercando di gestirlo nella mia soluzione 2 p: quindi non l'ho capito. Ovvio a posteriori.
Jesse Millikan,

Il fatto che tu possa vedere quell'esplosione di personaggi e dirlo " ovvio a posteriori " mi fa semplicemente impazzire. Uno di questi giorni dovrei dare un'occhiata a Golfscript o J.
Casey il

@Casey Mi sono sentito allo stesso modo in una volta, ma più J impari e usi, più "salta fuori da te", anche se vedo ancora cose che devo risolvere. Una cosa utile da sapere su J è che se aggiungi a. o: dopo un simbolo, si crea un nuovo simbolo, ad esempio, {, {., e {:tutte le cose cattive diverse, ma {-(per esempio) è sicuramente una sequenza di due cose, {e -.
Gregory Higley,

5

Golfscript, 68 67 62 61 caratteri

[.]({[.2@{1$1$%{)}{\1$/1$}if}*;;].,*0+{+}*.2$?@@.@+\@)!}do;,(

Questa è un'espressione: prende nlo stack e lascia il risultato nello stack. Per trasformarlo in un programma che prende nda stdin e stampa il risultato su stdout, sostituisci il comando [con~

Il cuore di esso è [.2@{1$1$%{)}{\1$/1$}if}*;;](28 caratteri) che prende il numero più alto nello stack e (con un algoritmo incredibilmente inefficiente) genera un elenco dei suoi fattori primi. Pseudocodice C-style equivalente:

ps = [], p = 2;
for (int i = 0; i < n; i++) {
    if (n % p == 0) {
        ps += p;
        n /= p;
    }
    else p++;
}

Il 0+poco prima {+}*è quello di gestire il caso speciale n==1, perché Golfscript non ama piegare un'operazione binaria sulla lista vuota.

Uno dei punti di fissaggio non primi è 27; Ho trovato questo senza usare il programma considerando la mappatura (p a -> a 2 p), che è un punto fisso se a == p (a-1) / 2 , e provando in piccolo a. ( a==1dà il punto fisso dei numeri primi).

La ricerca con il programma genera un secondo punto fisso: 30 = (2 + 3 + 5) * 3


Appendice: prova che esistono solo due punti fissi non primi

Notazione: sopfr(x)è la somma dei fattori primi di x, con ripetizione (A001414). Omega(x)è il numero di fattori primi di x(A001222). Quindi la funzione successore di Higley èh(x) = sopfr(x) Omega(x)

Supponiamo di avere un punto fisso N = h(N)che è un prodotto di n=Omega(N)numeri primi.

N = p_0 ... p_{n-1} = h(N) = n (p_0 + ... + p_{n-1})

Teoria dei numeri di base: si ndivide in p_0 ... p_{n-1}, quindi w=Omega(n)di quei numeri primi sono i fattori primi di n. Wlog li prenderemo per essere gli ultimi w. Quindi possiamo dividere entrambe le parti per ne ottenere

p_0 ... p_{n-w-1} = p_0 + ... + p_{n-1}

o

p_0 ... p_{n-w-1} = p_0 + ... + p_{n-w-1} + sopfr(n)

Dato che tutti i numeri primi p_0a p_{n-w-1}sono maggiori di 1, aumentando uno di essi aumenta i LHS più del destro. Quindi, per un dato momento n, possiamo elencare tutte le soluzioni candidate.

In particolare, non ci possono essere soluzioni se l'LHS è maggiore dell'RHS impostando tutti i numeri primi "liberi" su 2. Vale a dire non ci sono soluzioni se

2^{n-w} > 2 (n-w) + sopfr(n)

Poiché sopfr(n) <= n(con l'uguaglianza solo per n = 4 o n primo), possiamo rendere l'affermazione più debole che non ci sono punti fissi se

2^{n-w} > 3 n - 2 w

Tenendo wfisso possiamo selezionare diversi valori di nsoddisfacente w=Omega(n). Il più piccolo nè tale 2^w. Si noti che se 2^{n-w}è almeno 3 (cioè se n-w>1, il che è vero se n>2), aumentando ntenendo wcostante si aumenterà l'LHS più dell'RHS. Si noti inoltre che per w>2e prendendo il più piccolo possibile nla disuguaglianza è soddisfatta e non ci sono punti fissi.

Questo ci lascia con tre casi: w = 0e n = 1; w = 1ed nè primo; o w = 2ed nè semi-primo.

Caso w = 0. n = 1, quindi Nè un numero primo.

Caso w = 1. Se n = 2quindi N = 2pe richiediamo p = p + 2, che non ha soluzioni. Se n = 3poi abbiamo pq = p + q + 3e due soluzioni, (p=2, q=5)e (p=3, q=3). Se n = 5poi 2^4 > 3 * 5 - 2 * 1, quindi non ci sono ulteriori soluzioni con w = 1.

Caso w = 2. Se n = 4quindi N = 4pqe abbiamo bisogno pq = p + q + 4. Questa ha una soluzione intera p=2, q=6, ma nessuna soluzione primaria. Se n = 6poi 2^4 > 3 * 6 - 2 * 2, quindi non ci sono ulteriori soluzioni con w = 2.

Tutti i casi sono esauriti, quindi gli unici punti fissi non primi sono 27 e 30.


1
Ho trovato questi due punti fissi usando carta e matita: 27 e 30. Concordo con OP, sembra che siano gli unici due.
mellamokb,

1
La prossima domanda interessante potrebbe essere. Ci sono infiniti higley (x) = 2? Che ne dici di un modo per generare arbitrario higley (x), come higley (x) = 100?
mellamokb,

Molto bella! Sono un ragazzo di tipo J ma forse dovrei imparare GolfScript.
Gregory Higley,

@mellamokb Penso che ci siano una serie di domande interessanti con questa sequenza. Ad esempio, se consideriamo la sequenza di numeri generati per ciascuno nprima che venga contata, ci sono dei non primi ndopo 49 per i quali detta sequenza non termina con 28?
Gregory Higley,

2
Un'altra domanda interessante da porsi è se esiste una semplice funzione di ncui limiti higley(n)sopra. (Ciò consentirebbe di semplificare notevolmente il ciclo - solo iterare i f(n)tempi e quindi scartare i duplicati).
Peter Taylor,

4

Rubino, 92 caratteri

f=->i{r=[i];(x=s=0;(2..i).map{|j|(s+=j;x+=1;i/=j)while i%j<1};r<<i=s*x)until r.uniq!;r.size}

Questa soluzione presuppone che higley (1) sia in realtà 2, non 1 (vedi il commento di balpha sopra):

(1..10).map &f
=> [2, 1, 1, 10, 1, 11, 1, 9, 5, 10]

2

Ottava - 109 caratteri

l=[input('')];while size_equal(unique(l),l);n=factor(l(1));l=[sum(n)*length(n) l];endwhile;disp(length(l)-1);

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.