1

can you help me with the following exercise pls? (it's not homework, just an exercise in the book I'm using.)

"An integer is said to be a perfect number if its factors, including one (but not the number itself), sum to the number. For example, 6 is a perfect number, because 6 = 1 + 2 + 3. Write method Perfect that determines whether parameter value is a perfect number. Use this method in an app that determines and displays all the perfect numbers between 2 and 1000. Display the factors of each perfect number to confirm that the number is indeed perfect."

so here's what i got so far:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Perfect_Numbers2
{
    class Program
    {
        static bool IsItPerfect(int value)
        {
            int x = 0;

            int counter = 0;

            bool IsPerfect = false;

            List<int> myList = new List<int>();

            for (int i = value; i <= value; i++)
            {
                for (int j = 1; j < value; j++)
                {
                    // if the remainder of i divided by j is zero, then j is a factor of i
                    if (i%j == 0) {
                        myList[counter] = j; //add j to the list
                        counter++;
                    }
                    for (int k = 0; k < counter; k++)
                    {
                        // add all the numbers in the list together, then
                        x = myList[k] + myList[k + 1]; 
                    }
                    // test if the sum of the factors equals the number itself (in which case it is a perfect number)
                    if (x == i) {
                        IsPerfect = true;
                    }
                }
                Console.WriteLine(i);
            }
            return IsPerfect;
        }
        static void Main(string[] args)
        {
            bool IsItAPerfectNum = false;

            for (int i = 2; i < 1001; i++)
            {
                IsItAPerfectNum = IsItPerfect(i);
            }
        }
    }
}

how would you do it? is my code fixable? how would you fix it? thanks!

im getting an error at line myList[counter] = j; (index was out of range) and besides it's not displaying the perfect numbers like it's supposed to....

EDIT = I made some changes;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Perfect_Numbers2
{
class Program
{
    static bool IsItPerfect(int value)
    {
        int x = 0;

        int counter = 0;

        bool IsPerfect = false;

        List<int> myList = new List<int>();

        for (int i = value; i <= value; i++)
        {
            for (int j = 1; j < i; j++)
            {
                if (i%j == 0)  // if the remainder of i divided by j is zero, then j is           a factor of i
                {
                    myList.Add(j); //add j to the list


                }
                x = myList.Sum();
                if (x == i)                        // test if the sum of the factors       equals the number itself (in which case it is a perfect number)
                {
                    IsPerfect = true;
                }

        }
            Console.WriteLine(i);
        }
        return IsPerfect;
    }
    static void Main(string[] args)
    {
        bool IsItAPerfectNum = false;

        for (int i = 2; i < 1001; i++)
        {
            IsItAPerfectNum = IsItPerfect(i);
            Console.WriteLine(IsItAPerfectNum);
            Console.ReadKey(true);
        }
    }
  }
  }

now i can cycle through all the numbers until 1000 and it displays if it's perfect or not (true or false) [which isn't what the exercise called for, but it's a step in the right direction (the exercise says that it should display only the perfect numbers)].

In any case, what's strange is that it says true at number 24, which isn't a perfect number.... http://en.wikipedia.org/wiki/Perfect_numbers#Examples

why is 24 different?

thanks very much

false
  • 10,264
  • 13
  • 101
  • 209
user2723261
  • 541
  • 2
  • 7
  • 12

6 Answers6

18

can you help me with the following exercise please?

Yes. Rather than showing you where your error is, I'll teach you how to find your error. Even better, the same technique will lower the chances of you causing the error in the first place.

The key here is to break the problem down into small parts where each small part can be tested independently. You have already started to do this! You have two methods: Main and IsItPerfect. You should have at least three more methods. The methods you should have are:

  • IsDivisor -- takes two integers, returns true if the first divides the second.
  • GetAllDivisors -- takes an integer, returns a list of all the divisors
  • Sum -- takes a list of integers, returns the sum

Your method IsPerfect should be calling GetAllDivisors and Sum and comparing the sum to the original number, and that's all it should be doing. Your method GetAllDivisors should be calling IsDivisor, and so on.

You can't find the bug easily because your method is doing too much. If you're not getting the correct result out and you have four methods instead of one then you can test each method independently to make sure that it works, or fix it if it does not.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 1
    I realize this is not the point of your answer but what's wrong with Linq .Sum() ? Why do you recommend that OP implement it themselves? – Rotem Aug 29 '13 at 21:33
  • 7
    @Rotem: Because this is a beginner doing this work as an exercise. Writing your own implementation of simple helper methods builds character, and it encourages you to think of those helper methods as non-magical pieces of code that real people had to design, implement and ship. – Eric Lippert Aug 29 '13 at 23:14
  • Breaking your code into smaller chunks brings you closer to [SSCCE](http://sscce.org/) (Short, Self Contained, Correct (Compilable), Example) code. Not only are SSCCEs easier for you to debug, but they are also easier for respondents to debug. A big chunk of the SO community is unwilling to answer non-SSCCE questions (and lack of SSCCE is specifically mentioned as a close reason). – Brian Aug 30 '13 at 15:08
0

Some help with the 24 issue you are having: 24 is returning true as you are actually checking if it is perfect on every additional factor. So 24 gets flipped to true here:

Factors of 24 | Total so far
    1                1
    2                3
    3                6
    4                10
    6                16
    8                24     <-- returns true
    12               36     <-- should be false, but flag is never reset
Matthew
  • 9,851
  • 4
  • 46
  • 77
0

Your first for loop will be executed exactly once.

for (int i = value; i <= value; i++)

For example for value = 6

for (int i = 6; i <= 6; i++)
dlev
  • 48,024
  • 5
  • 125
  • 132
Max
  • 108
  • 1
  • 14
0

I have just now completed the same exercise which is from a really great book called visual c# 2012 by Mr Deitel.

The way i started to tackle is, i started off with figuring out how to work out the factorials of numbers and then slowly kept building on from there.

Since you are following the same book, i would suggest you not to use things that are not covered up to that chapters exercise, like list collections which you have used, As this will make the exercise unnecessarily difficult. and negates the learning methodology set out by of the author.

here is my code which i hope can help you in some way.

class Program
{

    static  int factorTotal = 1;

    static void Main(string[] args)
    {

            int count = 1;
            while (count <= 10000)
            {
                bool isPerfect = IsPerfectNumber(count);

                if (isPerfect && (factorTotal >1))
                {
                    Console.WriteLine("Is Perfect: {0}", factorTotal);

                }              

                factorTotal = 1;
                count++;
            }               


    } // end main

    static bool IsPerfectNumber(int n)
    {
        int temp;
        int counter = 2;

        bool IsPerfect = false;

        while (counter <= (n - 1))
        {
            temp = n % counter;
            if (temp == 0)  // if true than factor found
            {

                factorTotal = factorTotal + counter;
            }

            counter++;
        }

        if ((factorTotal) == n)
            IsPerfect = true;

        else
            IsPerfect = false;

        return IsPerfect;
    }

}//end class
0

under the Main method of you console application copy and paste below code. I explained few things at the end of the code...

=====================================================================

{
        Console.WriteLine("perfect numbers/n");
        Console.Write("Enter upper limit: ");
        int iUpperLimit = int.Parse(Console.ReadLine());
        string sNumbers = "";
        List<int> lstFactor = new List<int>();

        for(int i = 1;i<=iUpperLimit;i++)
        {
            for(int k = 1;k<i;k++)
            {
                if (i % k == 0)
                {
                    lstFactor.Add(k); //this collect all factors
                }
                if (k == i-1)
                {
                    if (lstFactor.Sum() == i) //explain1
                    {
                        sNumbers += " " + i;
                        lstFactor.Clear(); //explain2
                        break;
                    }
                    else
                    {
                        lstFactor.Clear(); //explain2
                    }
                }
            }
        }

        Console.WriteLine("\nperfect numbers are: " + sNumbers);
        Console.ReadKey();
    }
}

======================================================================= note that i is a number that we test and k is its factors.

explain1 => we add all factors collected and check if they are equal to i (we simply check if i is perfect number)

explain2 => we have to clear our list before we can check if the next number i is a perfect number or not so that factors of the previous number does not interfere with factors of the current number.

0
    int start=1;
    int end=50;

    for(int a=end ; a > start ;a--)
    {
        int b=1;
        int c=0;
        bool x=false;

        for(int i=1 ; i < a ;i++)
        {
            b=a/i;
                if(b*i==a)
                {
                    c+=i;
                }
                if(c==a & i==a/2)
                {
                    x=true;
                }
        }
        if(x==true)
        Console.Write("{0} is : {1}",a,x);
    }
seyed
  • 1
  • 3