Calcular uma sequência inteira derivada de fatores primos

10

Crie uma função, expressão ou programa que faça o seguinte:

  1. Pegue os fatores primos de qualquer número e some-os. Por exemplo, os fatores primos de 28 são 2 2 7, somados a 11.
  2. Multiplique o resultado pelo número de fatores primos para o número fornecido. Por exemplo, 28 tem 3 fatores primos que somam 11. 11 * 3 é 33.
  3. Repita o processo recursivamente, armazenando a lista resultante (que começa com o número original), até chegar a um número que já está incluído na lista. Pare sem adicionar esse número final, para que a lista não contenha duplicatas. A progressão para 28 é 28 33, porque 33 resulta em 28 novamente.
  4. Conte os elementos na lista resultante. No caso de 28, a resposta é 2.

Aqui estão os resultados para 0<n<=10, para que você possa verificar seu algoritmo.

2 1 1 10 1 11 1 9 5 10

(Como apontou balpha, a resposta para higley(1)2 é da lista 1 0. Eu originalmente tinha 1, devido a um erro no meu algoritmo original escrito em J.)

Como sou um SOB vaidoso e ainda não o encontrei no OEIS , vamos chamá-lo de "Higley Sequence", pelo menos durante a rodada deste código de golfe. Como um bônus adicional, encontre os dois primeiros ncom o menor higley(n)onde nnão é primo e n>1. (Acho que existem apenas dois, mas não posso provar.)

Esse é o código padrão do golfe, portanto, como sempre, o menor número de pressionamentos de teclas vence, mas eu peço que você promova respostas inteligentes em outros idiomas, mesmo que sejam detalhadas.

Gregory Higley
fonte
4
Por que highley(1) == 1? Como não temos fatores primos, a lista resultante em 4) é [1, 0], pelo highley(1) == 2que vejo.
balpha
Podemos assumir que o número de entrada e os valores intermediários não serão maiores que 2 ^ 31-1 (isto é, cabe em um número inteiro de 32 bits)?
Peter Taylor
@ Peter Taylor Claro.
precisa
Caso alguém ache útil, as sequências OEIS que estão vagamente relacionadas e podem fornecer alguma inspiração são A001414, A001222 e A002217.
Peter Taylor
11
Como você não comentou, presumo que não tenha notado: provei que existem apenas dois pontos de correção não principais e o adicionei como um apêndice ao meu post.
Peter Taylor

Respostas:

6

J, 47 45

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

É possível que isso seja muito mais curto sem o uso ^:_, mas meu cérebro já está suficientemente frito.

Edit: (47-> 45) Dia do cupom duplo.

Uso:

   higley =: #@((~.@,(+/@{:*+/@:*/)@(2&p:)@{:)^:_)`2:@.(=&1)
   higley 1
2
   higley"0 (1 + i. 10)
2 1 1 10 1 11 1 9 5 10
Jesse Millikan
fonte
Uau! Solução AJ mais curta que uma solução GolfScript. O primeiro que eu já vi. (Eu sou um grande fã de J.)
Gregory Higley
3
Você pode encurtar isso consideravelmente usando um algoritmo um pouco diferente:, com #@((~.@,((+/*#)@:q:)@{:)^:_)`2:@.(=&1)38 caracteres.
Gregory Higley
Uau, tentei descobrir como fazê-lo com q: mas estava tentando manipulá-lo na minha solução 2 p: para que não o entendesse. Óbvio em retrospecto.
Jesse Millikan
O fato de você poder olhar para aquela explosão de personagens e dizer " óbvia em retrospecto " simplesmente me surpreende. Um dia desses eu deveria verificar Golfscript ou J.
Casey
@ Casey Eu me senti da mesma maneira ao mesmo tempo, mas quanto mais você aprende e usa, mais isso "pula em você", embora eu ainda veja as coisas que preciso resolver. Uma coisa útil a saber sobre J é que, se você adicionar um. ou: depois de um símbolo, ele cria um novo símbolo, por exemplo, {, {., e {:todas as coisas médios diferentes, mas {-(por exemplo) é definitivamente uma sequência de duas coisas, {e -.
Gregory Higley
5

Golfscript, 68 67 62 61 caracteres

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

Esta é uma expressão: assume na pilha e deixa o resultado na pilha. Para transformá-lo em um programa que usa nstdin e imprime o resultado em stdout, substitua o líder [por~

O coração disso é [.2@{1$1$%{)}{\1$/1$}if}*;;](28 caracteres), que leva o número superior da pilha e (por um algoritmo incrivelmente ineficiente) gera uma lista de seus principais fatores. Equivalente ao pseudocódigo no estilo C:

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

O 0+pouco antes {+}*é tratar do caso especial n==1, porque o Golfscript não gosta de dobrar uma operação binária na lista vazia.

Um dos fixpoints não principais é 27; Descobri isso sem usar o programa considerando o mapeamento (p a -> a 2 p), que é um ponto de correção se a == p (a-1) / 2 e tentando pequeno a. ( a==1fornece a correção dos números primos).

A pesquisa no programa gera um segundo ponto de correção: 30 = (2 + 3 + 5) * 3


Apêndice: prova de que existem apenas dois pontos de fixação não principais

Notação: sopfr(x)é a soma dos fatores primos de x, com repetição (A001414). Omega(x)é o número de fatores primos de x(A001222). Portanto, a função sucessora de Higley éh(x) = sopfr(x) Omega(x)

Suponha que tenhamos um ponto de fixação N = h(N)que é um produto de n=Omega(N)números primos.

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

Teoria básica dos números: ndivide-se em p_0 ... p_{n-1}, portanto, w=Omega(n)esses números primos são os fatores primos de n. Wlog, consideraremos o último w. Para que possamos dividir os dois lados ne obter

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

ou

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

Dado que todos os números primos p_0para p_{n-w-1}são maiores do que 1, aumentando qualquer um deles aumenta as LHS mais do que o RHS. Portanto, para um dado dado n, podemos enumerar todas as soluções candidatas.

Em particular, não pode haver soluções se o LHS for maior que o RHS, configurando todos os primos "livres" para 2. Ou seja, não há soluções se

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

Como sopfr(n) <= n(com igualdade apenas para n = 4 ou n primo), podemos fazer uma afirmação mais fraca de que não há pontos de fixação se

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

Mantendo-se wfixo, podemos selecionar diferentes valores de nsatisfação w=Omega(n). O menor né esse 2^w. Observe que se 2^{n-w}for pelo menos 3 (ou seja n-w>1, se for verdade se n>2), o aumento nenquanto mantém wconstante aumentará o LHS mais que o RHS. Observe também que, para w>2o menor possível, na desigualdade é satisfeita e não há pontos de fixação.

Isso nos deixa com três casos: w = 0e n = 1; w = 1e né primo; ou w = 2e né semi-prime.

Case w = 0. n = 1, assim Ncomo qualquer prime.

Case w = 1. Se n = 2, em seguida, N = 2pe exigimos p = p + 2, que não tem soluções. Se n = 3então temos pq = p + q + 3e duas soluções, (p=2, q=5)e (p=3, q=3). Se n = 5, em seguida 2^4 > 3 * 5 - 2 * 1, por isso não há mais soluções com w = 1.

Case w = 2. Se n = 4, em seguida, N = 4pqe exigimos pq = p + q + 4. Isso tem solução inteira p=2, q=6, mas não há soluções principais. Se n = 6, em seguida 2^4 > 3 * 6 - 2 * 2, por isso não há mais soluções com w = 2.

Todos os casos estão esgotados; portanto, os únicos fixpoints não principais são 27 e 30.

Peter Taylor
fonte
11
Encontrei esses dois pontos de correção usando lápis e papel: 27 e 30. Concordo com o OP, parece que esses são os únicos dois.
precisa saber é o seguinte
11
A próxima pergunta interessante pode ser. Existem infinitamente muitos higley (x) = 2? Que tal uma maneira de gerar higley arbitrário (x), como higley (x) = 100?
precisa saber é o seguinte
Muito agradável! Eu sou do tipo J, mas talvez precise aprender o GolfScript.
Gregory Higley
@mellamokb Acho que há uma série de perguntas interessantes com essa sequência. Por exemplo, se considerarmos a sequência de números gerados para cada um nantes de ser contada, existe um não primo ndepois de 49 para o qual a sequência não termina em 28?
Gregory Higley
2
Outra pergunta interessante a ser feita é se existe uma função simples ncom limites higley(n)acima. (Isso permitiria simplificar consideravelmente o loop - apenas repita os f(n)tempos e depois descarte as duplicatas).
Peter Taylor
4

Ruby, 92 caracteres

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}

Esta solução assume que higley (1) é realmente 2, não 1 (veja o comentário de balpha acima):

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

Oitava - 109 caracteres

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