Hi, recently i started taking lessons on c programming and my first assignment was to make programm which would name all the perfect multiperfect or superperfect numbers within a set (whose limits will be given as #define constants) and their percentage. Anyway apart from any logic errors (which i would be very glad if someone pointed out!!) i'm facing some compilation difficuties.

Specifically the code is

#include <stdio.h>
#define MAXM 6
#define MAXNUM 400000

main()
{ int n, sum, i, k, m, totdis, totsup, totmul, total, totper;


  totdis=0;
  total=0;
  totmul=0;
  totper=0;
  totsup=0;

  for (n = 1 ; n <= MAXNUM ; n++){
   for (m = 1 ; m <= MAXM ; m++){
    for (i = 1 ; i <= n ; i++){
     sum = 0;
     if (n % i == 0){
      sum = sum + i;
     }
    if (sum % n == 0){
     k = sum / n;
     totdis++;
      if (m == 1){
       if (k == 2){
        printf("%d is a (%d - %d) - perfect number, that is a perfect number\n",n, m, k);
        total++;
        totper++;
        totmul++;
       }
       else{
        printf("%d is a (%d - %d) - perfect number, that is a multiperfect number\n",n, m, k);
        total++;
        totmul++;
       }
      else if (m == 2 && k == 2){
       printf("%d is a (%d - %d) - perfect number, that is a superperfect number\n",n, m, k);
       total++;
       totsup++;
      }
      else{
       printf("%d is a (%d - %d) - perfect number\n",n, m, k);
       total++;
      }
     }
    }
   }
  }
 }

 printf("\nFound %d distinct (m-k)-perfect numbers (%10.10f % of %d) in %d occurencies \nFound %d perfect numbers \nFound %d multiperfect numbers (including perfect numbers)\nFound %d superperfect numbers \n",totdis, ((float)  totdis / (float) MAXNUM) * 100, n, total, totper, totmul, totsup);
}

and the compiler errors are

37 syntax error before "else"
52 syntax error before string constant

i'm using DevC++ for Windows Vista
If anyone could help i would really appreciate an advice, i'm still a newbie!

You cannot have an else if() after an else.

it needs to be something like:

if (condition1) {
 // code
} else if (condition2) {
// code 
} else {
// code
}

You can read a little more on this here:if else if

if i also write the same code without indentaion , then me also will get the compilation error. TIP: if you again want to write this type of code which have so many if else conditions then try to wrute the indented code. use codeblocks or notepad++ or dev c++ they will indent for you while you are writing. thanks.

@myk45 the "else if" in line 37 as well as the 'else' in line 42 refer to the first "if" condition in line 25. the second one in line 26 finishes with the "else" in line 32.

@nitin1 i used devc++ and it indeed assisted me as you say... I should follow the redirected cursor after conditions, thanks a lot

I find your code pretty difficult to read. Why don't you divide problems into a smaller problems by using functions? I don't really know the theory behind perfect numbers that well but on a quick attempt I would go for something like this, which is quite different and (in my opinion) easier to read.

Note that the m-superperfect number section is probably incorrect. This place mentioned some results for any k so I just included it.. I might look into it at some point (especially optimalization might be fun, though some are obvious and easy) but for now the point I'm trying to make it that you should structure your code better.

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>

#define UPPER_BOUNDARY (10000)
#define MAXIMUM_K      (6)
#define MAXIMUM_M      (3)

struct List
{
    int value;
    struct List* next;
};

// Functions to manipulate the list structure.
static void AddToList  (struct List** list, const int value);
static void RemoveList (struct List** list);

// Internal helper functions.
static struct List* GetDivisors     (const int n);
static int          Pow             (const int n, const int k);
static int          DivisorFunction (const int n, const int k);

// The functions you will need. (would be in the header normally)
bool IsPerfect      (const int n);
bool IsSuperPerfect (const int n);
bool IsMultiPerfect (const int n, const int k);
bool IsMSuperPerfect(const int n, const int m);
bool IsMKPerfect    (const int n, int m, const int k);


static void AddToList(struct List** list, const int value)
{
    assert (list != NULL);

    if (*list == NULL)
    {
        *list = (struct List*) malloc(sizeof(struct List));
        (*list)->value = value;
        (*list)->next  = NULL;
    }
    else
    {
        AddToList(&((*list)->next), value);
    }
}

static void RemoveList (struct List** list)
{
    assert (list != NULL);

    if (*list != NULL)
    {
        // First remove the rest..
        RemoveList(&((*list)->next));

        // .. and then remove this.
        free(*list);
    }
}

static struct List* GetDivisors (const int n)
{
    assert (n > 0);

    struct List* result = NULL;
    int i = 0;

    for (i = 1; i <= n; i++)
    {
        if (n % i == 0)
        {
            AddToList(&result, i);
        }
    }

    return result;
}

static int Pow (const int n, const int k)
{
    assert (k >= 0);

    if (k == 0)
    {
        return 1;
    }
    else
    {
        return n * Pow(n, k - 1);
    }
}

// When k = 0 you could interpret the function as "count the amount of divisors of n". (pow0)
// When k = 1 you could interpret the function as "take the sum of all divisors of n". (pow1)
// And so on.
static int DivisorFunction (const int n, const int k)
{
    assert (n > 0 && k >= 0);

    struct List* divisors = GetDivisors(n);
    struct List* iterator = NULL;
    int          result   = 0;

    for(iterator = divisors; iterator != NULL; iterator = iterator->next)
    {
        result += Pow(iterator->value, k);
    }

    RemoveList(&divisors);

    return result;
}


bool IsSuperPerfect (const int n)
{
    return IsMKPerfect(n, 2, 2);
}

bool IsMSuperPerfect (const int n, const int m)
{
    return IsMKPerfect(n, m, 2);
}

bool IsMKPerfect (const int n, int m, const int k)
{
    assert (n > 0 && m > 0 && k >= 2);
    int subresult = n;

    while (m --> 0)
    {
        // Take the sum of the divisors of our current subresult.
        subresult = DivisorFunction(subresult, 1);
    }

    return (subresult == (k * n));
}

// Determines whether or not n is k-multiperfect or not.
bool IsMultiPerfect (const int n, const int k)
{
    assert (n > 0 && k > 2);

    return IsMKPerfect(n, 1, k);

    //OR:
    //return DivisorFunction(n, 1) == (k * n);
}


// Determines whether or not n is a perfect number or not.
// Note that this would be multiperfect numbers with k = 2.
// k should be > 2 because of this for that function; I wanted
// implementation to be seperate.
bool IsPerfect (const int n)
{
    assert(n > 0);
    return IsMKPerfect(n,1,2);
    //Or:
    //return DivisorFunction(n, 1) == (2 * n);
}


int main(void)
{
    int n = 0,
        k = 0,
        m = 0,
        perfectFound        = 0,
        superPerfectFound   = 0,
        mSuperPerfectFound  = 0,
        mkPerfectFound      = 0;

    for (n = 1; n <= UPPER_BOUNDARY; n++)
    {
        // Find perfect numbers.
        if (IsPerfect(n))
        {
            printf("%10d is (1,2)-perfect. (perfect number)n", n);
            perfectFound++;
        }

        // Find superperfect numbers.
        if (IsSuperPerfect(n))
        {
            printf("%10d is (2,2)-perfect. (superperfect number)n", n);
            superPerfectFound++;
        }

        // Find m-superperfect numbers.
        for (m = 3; m <=  MAXIMUM_M; m++)
        {
            if (IsMSuperPerfect(n, m))
            {
               printf("%10d is (%d,2)-perfect. (m-superperfect number)n", n, m);
               mSuperPerfectFound++;
            }
        }

        // Find remaining m-k perfect numbers.
        for (m = 2; m <= MAXIMUM_M; m++)
        {
            for (k = 3; k <= MAXIMUM_K; k++)
            {
                if (IsMKPerfect(n, m, k))
                {
                    printf("%10d is (%d,%d)-perfect.n", n, m, k);
                    mkPerfectFound++;
                }
            }
        }
    }

    // Show an overview.
    printf("nnSearched %d numbers. Found %d special numbers:nn", UPPER_BOUNDARY, perfectFound + superPerfectFound + mSuperPerfectFound + mkPerfectFound);

    printf("%10d Perfect numbers. (%0.4f%%)n",                     perfectFound,       (double) perfectFound       / UPPER_BOUNDARY);
    printf("%10d Superperfect numbers. (%0.4f%%)n",                superPerfectFound,  (double) superPerfectFound  / UPPER_BOUNDARY);
    printf("%10d M-superperfect numbers. (%0.4f%%)n",              mSuperPerfectFound, (double) mSuperPerfectFound / UPPER_BOUNDARY);
    printf("%10d Miscellaneous (m,k)-perfect numbers. (%0.4f%%)n", mkPerfectFound,     (double) mkPerfectFound     / UPPER_BOUNDARY);

    return 0;
}

Example of the output with some smaller settings (takes a while to calculate):

         2 is (2,2)-perfect. (superperfect number)
         4 is (2,2)-perfect. (superperfect number)
         6 is (1,2)-perfect. (perfect number)
         8 is (2,3)-perfect.
        15 is (2,4)-perfect.
        16 is (2,2)-perfect. (superperfect number)
        21 is (2,3)-perfect.
        28 is (1,2)-perfect. (perfect number)
        42 is (2,6)-perfect.
        52 is (3,5)-perfect.
        64 is (2,2)-perfect. (superperfect number)
        84 is (2,6)-perfect.
        98 is (3,6)-perfect.
       160 is (2,6)-perfect.
       336 is (2,6)-perfect.
       496 is (1,2)-perfect. (perfect number)
       512 is (2,3)-perfect.
      1023 is (2,4)-perfect.
      1344 is (2,6)-perfect.
      4096 is (2,2)-perfect. (superperfect number)
      8128 is (1,2)-perfect. (perfect number)


Searched 10000 numbers. Found 21 special numbers:

         4 Perfect numbers. (0.0004%)
         5 Superperfect numbers. (0.0005%)
         0 M-superperfect numbers. (0.0000%)
        12 Miscellaneous (m,k)-perfect numbers. (0.0012%)

Process returned 0 (0x0)   execution time : 9.712 s
Press any key to continue.

Edited 4 Years Ago by Gonbe

This article has been dead for over six months. Start a new discussion instead.