Ver Mensaje Individual
  #11 (permalink)  
Antiguo 30/07/2014, 10:38
Pantaláimon
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 18 años, 4 meses
Puntos: 32
Respuesta: Buscando números primos, con la criba de Eratóstenes

No me acordaba que había participado aquí. Con lo que me gustan las frikadas numéricas. Aquí una vuelta de tuerca al algoritmo sin perder la esencia (ansi C):

Código C:
Ver original
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <stdlib.h>
  4.  
  5. int main(void) {
  6.    unsigned top = 1000000000;
  7.    unsigned rtop = sqrt(top);
  8.    unsigned char* nums = calloc( top, sizeof *nums);
  9.    unsigned primsTop = 2.2 * (top / log(top)); /* apaño para ahorrar memoria */
  10.    unsigned* prims = calloc( primsTop, sizeof *prims);
  11.    unsigned n; /* contador primos */
  12.    unsigned i, i2, ii;
  13.    unsigned j, k, l, x;
  14.  
  15.    k = x = nums[4] = nums[6] = nums[8] = 1;
  16.    i = l = n = prims[0] = 2;
  17.    prims[1] = 3;
  18.    l = 5;
  19.    i2 = i + i;
  20.    ii = i * i;
  21.  
  22.    /* calculo de la tabla */
  23.    for (i = 3; i <= rtop; i += 2, i2 += 4) {
  24.       /* El primer primo de la tabla es el primero con valor 0 */
  25.       if(nums[i]) continue;
  26.  
  27.       /* todo numero j tal que l <= j <= i*i-1 con nums[j] == 0 es primo */
  28.       ii = i*i;
  29.       for (j = l; j < ii; j += 2 )
  30.          if(nums[j] == 0)
  31.             prims[n++] = j;
  32.       l = ii+2;
  33.      
  34.       /* Dado k que va de x a n-1, se descartan los compuestos i*prims[k]    *
  35.        * donde se ve que i == prims[x]                                       *
  36.        * (Es una forma de evitar descartar números que ya están descartados) */
  37.       for (k = x; k < n; ++k) {
  38.          j = i*prims[k];
  39.          if (j >= top) break;
  40.          nums[j] = 1;
  41.       }
  42.      
  43.       /* a partir de aquí, se descartan los compuestos de la manera común */
  44.       if (j < top) j += i2;
  45.       for (; j < top; j += i2) {
  46.          if(!nums[j])
  47.             nums[j] = 1;
  48.       }
  49.       ++x;
  50.    }
  51.  
  52.    /* calcular resto de primos */
  53.    for (i = prims[n-1]+2; i < top; i += 2) {
  54.       if (nums[i] == 0) {
  55.          ++n;
  56.          /* prims[n++] = i; */
  57.       }
  58.    }
  59.    
  60.    printf("%d primos\n", n);
  61.    free(nums);
  62.    free(prims);
  63.  
  64.    return 0;
  65. }

Un saludo!
__________________
github.com/xgbuils | npm/xgbuils