3

I am missing something but I can't find what it is. I have also been given a input2.c file and it has a print_prim function which I am not allowed to change.

For n=10 it is always printing

4, 5, 7, 9, 

I know there is an i+2 in print_prim function but I can't solve it. Again, I am not allowed to change print_prim function. Can anyone see what am i missing?


main.c


#include <stdio.h>
#include <stdlib.h> 
#include "input2.h"

int main() {
    int n = lese_int();
    int laenge = n-1; 
    int *array;  
    array = malloc(sizeof(int) * laenge);  
    for (int i = 2; i <= n; i++) {
        array[i] = 1;  
    }

    for(int i=0;i<=n;i++) {
        if(array[i] == 1){
            for(int j = i ; i*j <= n ; j++){
                array[i*j] = 0;
            }   
        } 
    }
    print_prim(array, laenge);
    free(array); 
    return 0;
}

print_prim function

void print_prim(int *array, int laenge) {
    for (int i=0; i<laenge; i++) {
        if (array[i] == 1) {
            printf("%d, ", i+2);
        }
    }
    printf("\n");
}
keser
  • 2,472
  • 1
  • 12
  • 38

2 Answers2

2

All you need is a normal sieve shifted by 2 elements.

int main() {
  int n;
  scanf("%d", &n);

  int *a = (int*)malloc(sizeof(int) * (n - 1));
  for (int i = 0; i < n - 1; i++ ) a[i] = 1;

  for (int i = 2; i*i <= n; i++) {
    if (a[i-2] == 1) {
      for (int j = i * i; j <= n; j+=i ) a[j-2] = 0;
    }
  }

  print_prim(a, n - 1);

  free(a);
  return 0;
}

Explanation:

  • Allocate n-1 elements to represent numbers from 2 to n inclusive.
  • Initialize all elements with 1. Why? Because looking at print_prim, it prints values which are equal to 1. So, all our primes need to be shifted by 2 and its value should be 1.
  • Starting with 2, we mark all multiples of prime numbers as 0. The ones that stay 1 are primes. See https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes for details.
  • Since, print_prim is shifted by 2, we need to pass n-1 as the second argument for inclusive printing.
Mukul Gupta
  • 2,310
  • 3
  • 24
  • 39
  • Thanks Mukul, It's pretty nice. Can you please explain your approach? I think they are a little bit different. – keser Oct 24 '18 at 13:57
  • Inline fors are hard to expand. If you want to add more lines to that code, you will need curl braces, but a novice programmer doesn't notice it. – José Manuel Ramos Oct 24 '18 at 14:01
  • @aomerk, The code shifts by two elements just to ensure the `print_prim` function works as expected. – José Manuel Ramos Oct 24 '18 at 14:02
  • @JoséManuelRamos I don't think you are as helpful as you think you are. Please help people other than me. – keser Oct 24 '18 at 14:42
  • @MukulGupta sorry but the part I couldn't understand was, I was looping until j \* i and so on. Your math is little bit different. i \* i , j =i+i and j+= i – keser Oct 24 '18 at 14:43
  • @aomerk The math is the same. Instead of multiplication, I've used addition. In your case you should have done `i*j - 2` as you are using values of `j` from `i`. In fact, we could also start from `i*i` in the inner loop in my case. I'll edit it because it's more optimal. – Mukul Gupta Oct 24 '18 at 14:56
-1

Reformatting the code

A common step to help you is to format to us

#include <stdio.h>
#include <stdlib.h> 
#include "input2.h"

int main ( void )
{
  int n = lese_int();
  int laenge = n - 1; 
  int *array;

  array = malloc( sizeof( int ) * laenge );

  for ( int i = 2; i <= n; i++ )
  {
    array[i] = 1;
  }

  for ( int i = 0; i <= n; i++ )
  {
    if ( array[i] == 1 )
    {
      for ( int j = i; i * j <= n; j++ )
      {
        array[ i * j ] = 0;
      }
    }
  }

  for ( int i = 0; i < laenge; i++ )
  {
    printf( "%d, ", array[i] );
  }

  printf( "\n" );
  print_prim( array, laenge );
  free( array );
  return ( 0 );
}

And the print_prim function is:

void print_prim ( int *array, int laenge )
{
  for ( int i = 0; i < laenge; i++ )
  {
    if ( array[i] == 1 )
    {
      printf( "%d, ", i + 2 );
    }
  }
  printf( "\n" );
}

Note: this style is personal and it's not intended to make a religion-like flamming wars using spacing like me, or curl braces down.


Errors found when reading:

You use C99. Take that into account prior to change something. (know your language)

You make a memory allocation of n - 1 elements, but you try to access from the element 2 to the element n, both including, in the first for loop. (know how memory allocation works)

Arrays start at zero (insert joke), so, you can't reach the element n nor the element n - 1.

print_prim only prints the value plus 2 of the array element that contains 1. In other words: try to locate all the positions in the array which contains 1, and increment that position with 2. (know how to read-debugging)


I reccomend you to study how the language works instead of trial'n'error based programming. It will save you lot's of hours and you will learn more.