Valor primo absoluto C++

Iniciado por Morx, 8 Noviembre 2018, 16:00 PM

0 Miembros y 2 Visitantes están viendo este tema.

Morx

Buenas.
Me encontre con el ejercicio siguiente:
PROBLEMA: Definiremos número primo absoluto a un número primo que las sucesivas sumas de sus dígitos (hasta llegar a un número de un solo dígito) también son números primos.

EJEMPLO: 29 es un número primo
La suma de sus dígitos 2 + 9 = 11 también es un número primo
La suma de los dígitos de 11 1 + 1 = 2 también es un número primo
Por lo tanto, 29 es un número primo absoluto.
Evidentemente los números primos de una sola cifra son todos primeros absolutos.

Como se podria crear una lista con todos los primos absolutos desde 1 hasta un numero en cuestion?


Citar#include <iostream>

using namespace std;

unsigned suma_digitos (unsigned n){
    unsigned suma=0;
    cin >> n;
    while (n>0){
        suma= suma+n%10;
        n= n/10;}
}


bool primero(int n){
    if(n==1||n==2)
        return true;

    for(int i=2;i<n/2;i++){
          if(n%i==0)
              return false;
    }

   return true;
}

int main (){

    unsigned n;

    cout << "Digite un numero " <<endl;
    cin >> n;

    if (primero(n) and suma_digitos(primero(n))) cout << suma_digitos(n);
        else cout << suma_digitos(n);


    return 0;
}

AlbertoBSD

#1
Derterminar si un numero es Primo


Cita de: Morx en  8 Noviembre 2018, 16:00 PM
Como se podria crear una lista con todos los primos absolutos desde 1 hasta un numero en cuestion?

Bienvenido al mundo de los numeros primos, la respuesta te la estas dando tu mismo.

Primero necesitas determinar los numero Primos que existen desde 2 hasta el numero en cuestion.

Una vez definida esa lista necesitas procesar los digitos de cada uno de esos numeros y detenerminar si suma es un numero primo hasta llegar a un solo digito.

Por lo cual tu primer problema es detenerminar si un numero es primo o no.

Metodos para lo mismo hay muchos, desde exhaustivos, probabilisticos.

Lo ideal para estar 100% seguro de que es primo o no, es ir contruyendo una lista de numeros primos, y probar todos los numero siguientes contra esa lista. Por ejemplo emepzamos con el 2, primer numero primo.

Luego 3, ¿es tres divisible entre 2? en otras palabras ¿ 3 modulo 2 es 0 ?  Si la respuesta a esta ultma es negativa podemos agregar 3 a nuestra lista de numeros primos.

Luego 4, ¿Es cuatro divisible entre 2? si 4 % 2 es 0, entonces 4 No es numero primo.

Luego 5 es cinco divisible entre 2, como 5%2 no es 0, y como 5 % 3 no es 0, entonces agregamos 5 a nuestra lista de numeros primos.

Asi sucedivamnete hasta el numero N, entonces ya con la lista definida de numeros primos, procedes a simplificar la suma de sus digiitos como mencionaste hasta llegar a un numero de un solo digito, con lo cual tienes tu problema resulto.


#include<stdio.h>
#include<stdlib.h>
#include<string.h>

unsigned int *primos = NULL;
int n_primos = 0;

int agregar_numero(unsigned int numero);
int es_primo(unsigned int numero);
int es_primo_absoluto(unsigned int numero);

int main() {
unsigned int i,j;
unsigned int N = 0xFFFFFF;
agregar_numero(2);
printf("El numero %i es primo y ademas es Primo Absoluto\n",2);
i = 3;
while(i < N) {
j = 0;
if(es_primo(i)) {
printf("El numero %i es primo\n",i);
agregar_numero(i);
if(es_primo_absoluto(i)){
printf("El numero %i es primo y ademas es Primo Absoluto\n",i);
}
}
i+=2; //Vamos de 2 en 2 por que no necesitamos evaluar los numeros pares, es decir solo 3, 5, 7, 9 .... Asi evistamos llamdas inecesarias a la funcion es_primo, haciendo nuestro programa un tanto mas eficiente
}
return 0;
}

int agregar_numero(unsigned int numero) {
primos = realloc(primos,sizeof(int) * (n_primos+1));
primos[n_primos] = numero;
n_primos++;
}

int es_primo(unsigned int numero) { //Esta funcion solo determina correctamente si es primo o no, cuando ya hemos EVALUADO todos los numeros PREVIOS a este numero
int es_primo = 1;
int j = 0;
while(j < n_primos && primos[j] < (numero/2) && es_primo) {
es_primo = (numero % primos[j++] == 0) ? 0 : 1 ;
}
return es_primo;
}

int es_primo_absoluto(unsigned int numero) {
int retornar;
char temporal[20] = {0};
unsigned suma = 0;
int len,i;
sprintf(temporal,"%u",numero);
len = strlen(temporal);
if(len == 1) {
switch(numero) {
case 2:
case 3:
case 5:
case 7:
retornar = 1;
break;
default:
retornar = 0;
break;
}
}
else {
i = 0;
while(i < len) {
suma = temporal[i++] - '0';
}
if(es_primo(suma)) {
retornar = es_primo_absoluto(suma);
}
else {
retornar = 0;
}
}
return retornar;
}


Saludos

Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

Morx

Cita de: AlbertoBSD en  8 Noviembre 2018, 17:17 PM
Derterminar si un numero es Primo



Gracias Alberto por la ayuda. En este momento llevo hecho este codigo. Me faltaria mostrar todos los numeros primos absolutos hasta un numero en cuestion.
EJEMPLO:
INTRODUCE UN MAXIMO: 100
2 3 5 7 11 23 29 41 43 47 61 83.

#include <iostream>

using namespace std;

bool es_primo(unsigned n){
    bool primo=n==2;
    if(n>2){
    unsigned divisor=2;
    while(n%divisor!=0 and divisor*divisor<n) divisor++;
    primer=n%divisor!=0;}
    return primo;
}

unsigned suma_digitos (unsigned n){
    int suma=0;
    while (n>0){
        suma = suma + n%10;
        n = n/10;}
        return suma;
    }



int main()
{
    unsigned numero, suma;

    cout << "Digite un numero: ";
    cin >> numero;

    suma = suma_digitos(numero);

    while (suma >= 10){
        cout << suma<< endl;
        suma=suma_digitos(suma);
        cout << suma<< endl;
    }



    return 0;
}


K-YreX

#3
Ya tienes lo más complicado. Tienes una función que te dice si un número es primo y tienes otra función que te devuelve la suma de los dígitos de un número.

Cuidado con esto en <es_primo(unsigned n){}>; es primo, no primer:

primer=n%divisor!=0;


Solo te falta hacer un bucle como el del main, pero en vez de mostrar la suma de los dígitos, tienes que comprobar que el número siga siendo primo. Entonces en el bucle mientras el número sea >= 10 y el número sea primo aboluto: si el número no es primo, entonces no es primo absoluto, sino el número es igual a la suma de sus cifras. Un ejemplo de cómo quedaría es:

Código (C++) [Seleccionar]

bool isAbsolutePrime(unsigned num){
bool absPrime = isPrime(num);
while(num >= 10 && absPrime){
num = sumDigits(num);
if(!isPrime(num))
absPrime = false;
}
return absPrime;
}


Y en el <main> puedes ejecutarlo como (los nombres de las funciones son distintos pero su contenido no).
Tendrías que adaptarlo a tu código o simplemente ahorrarte la función <isAbsolutePrime(unsigned)> y hacerlo en el <main> directamente.

Código (C++) [Seleccionar]

int main(){

unsigned max;
cout << "Introduce el limite maximo: ";
cin >> max;

for(size_t i = 0; i < max; i++)
if(isAbsolutePrime(i))
cout << i << "  ";

cout << endl;
return 0;
}
 
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;