locked
Lucky Number Logaritm Question RRS feed

  • 问题

  • Hi,

    I am trying to write a algoritm for to check if a given number is a lucky number or not.
    I understand the logic behind it but i get totally stuck in written the algoritm and how to handle this bool type method.

    Lucky number (7):
     A lucky number is a number where the repeated sum of the numbers is equal to 7.

    For example the number given in   12345    (1+2+3+4+5 = 15     1+5=6     =>>>  12345 is not a lucky number since its not 7)
    For example the number given in  12346     (1+2+3+4+6 = 16     1+6=7     =>>>  12346 is a lucky number, the sum of the repeated numbers equals 7)

    What i have thought of so far trying to write this algoritm:

    - So i have tried a boolean method (the result has to check if the number is a lucky number or not, so boolean method)
    - When i give in a number the number of calcultions is already set, so FOR loop will be used.
    - starting the Total=0;
    - Total = Total + Number 
    -  I do not understand how i will split the numbers so it will first sum everything up 4+5+5 = 14    then it will count that number 14  to 1+4 = 5 ==> is not a lucky number)
    Is this a loop in a loop, if so how do i actually manage that? I have no idea.

    I also get a error "cannot convert ulong to bool", I know this has to be a boolean method cause the outcome will be true or not but how to handle the ulong value in this process?


     public bool LuckyNumber(ulong Number)
        {
          ulong Totaal = 0;
          for (ulong i = 1; i <= Number; i++)
          {
            Totaal = Totaal + Number;
          }
          return Totaal;
        }


    Any help appreciated.
    Thanks in advance

    • 已编辑 Chrisznl 2009年12月18日 15:41
    2009年12月18日 15:37

答案

  • You're going to need either an array or a list either way, because you want to take a single number (say 12345) and split it into a bunch of numbers (1, 2, 3, 4, 5). Here's what a method would have to look like if you didn't want to use an array or list:

    static void SplitNumber(ulong inNum, out ulong splitNumber1, out ulong splitNumber2, out ulong splitNumber3, etc... You would need to have as many of these as you could possibly have digits, which is 20 for ulong. Lists are easy to work with though, they're exactly what they sound like. A List<ulong> is a list of ulong variables.

    Basically how split number works is it breaks off the last digit using % 10, you got that part right, and then divides the original number by 10. For example:

    number = 4563
    List<ulong> =

    After first loop:
    number = 456
    List<ulong> = 3

    After second loop:
    number = 45
    List<ulong> = 3, 6

    After third loop:
    number = 4
    List<ulong> = 3, 6, 5

    And now the number is less than 10, so the loop stops, and we add the final number on
    List<ulong> = 3, 6, 5, 4

    You can see that the list is backwords, and this is what would happen if we used results.Add(number % 10), because that adds the number onto the end. Instead we use results.Insert(0, number % 10). Insert inserts the number at the specified index. We use the index 0 to say we want to insert right at the front. So now when we loop we always add to the front:

    3
    6, 3
    5, 6, 3
    4, 5, 6, 3

    The Sum method is easier. You can see that it takes a list of ulongs, which we got from SplitNumber. It loops through the numbers in the list, adding each one to the total (result), then returns the total. The foreach loop is an easy way to loop through every item in a list, it is equivalent to this:

    for (int i = 0; i < numbers.Count; i++)
        result += numbers[i];

    which is also equivalent to this:

    int i = 0;
    while(i < numbers.Count)
    {
        result += numbers[i];
        i++;
    }

    To clarify a few more things, in case you don't get them:
    The [] brackets are used to specify the index you want, so for our example, numbers[0] = 4, numbers[1] = 5, numbers[2] = 6 and numbers[3] = 3.
    result += numbers[i] is the same as result = result + numbers[i]
    i++ is the same as i += 1 is the same as i = i + 1
    • 已标记为答案 Chrisznl 2009年12月18日 17:03
    2009年12月18日 16:55

全部回复


  •         static void Main(string[] args)
            {
                Int32 i = 12345; //or use whatever value you'd like here.
                Int32 sum = SumDigits(i);

                Console.WriteLine("{0} is {1} magic number.", i, sum == 7 ? "a" : "not a");
                Console.ReadLine();

            }
            public static Int32 SumDigits(Int32 value)
            {
                Int32 sum = 0;
                String sValue = value.ToString();
                Char[] cArray = sValue.ToCharArray();

                foreach (Char c in cArray)
                    sum += Convert.ToInt32(c.ToString());

                if (sum >= 10)
                    sum = SumDigits(sum);

                return sum;
            }
    • 已建议为答案 JediJohn82 2009年12月18日 19:07
    2009年12月18日 15:59
  • Hello, thanks for replying!

    I am not into arrays yet, so i have no clue what the above means to be honest.


    Is there no way with normal loops (for, while, etc) to solve this problem?

    And since its true or false the income i suppose this method has to be a boolean or not?
    This is mainly to get more insight into the mather (writting "simple algoritms" with for & while loops) , and im really breaking my head on this one.


    I am using a seperate class to put in all the algoritms so no need for the Main method, i am trying to get everything into 1 method. (atleast thats the intention)

    Regards Chris.
    2009年12月18日 16:08
  • The other way to split the number up is to use modulo so you don't have to convert:

    static bool IsLuckyNumber(ulong number)
    {
        while (number >= 10)
        {
            List<ulong> splitNumbers = SplitNumber(number);
            number = Sum(splitNumbers);
        }
    
        return number == 7;
    }
    
    static List<ulong> SplitNumber(ulong number)
    {
        List<ulong> results = new List<ulong>();
    
        while (number >= 10)
        {
            results.Insert(0, number % 10);
            number /= 10;
        }
        results.Insert(0, number);
    
        return results;
    }
    
    static ulong Sum(List<ulong> numbers)
    {
        ulong result = 0;
    
        foreach (ulong number in numbers)
            result += number;
    
        return result;
    }
    [Edit] Changed > 10 to >= 10
    2009年12月18日 16:09
  • If you want you can try to explain to me what each part of my algorithm is doing, and I'll tell you what you got right and wrong.
    2009年12月18日 16:23
  • If you want you can try to explain to me what each part of my algorithm is doing, and I'll tell you what you got right and wrong.

    Hello Scotty, that would great and very helpfull indeed. Getting the grasp how to write these things seems to prove quite a obstacle.

    But i have never seen the <List> and insert function before though, so i am not sure whats that about :)
    Quite confusing, anyway way to exclude this? (yes i am being annoying.....)

    static List<ulong> SplitNumber(ulong number)
    {
        List<ulong> results = new List<ulong>();
    
        while (number > 10)
        {
            results.Insert(0, number % 10);
            number /= 10;
        }
        results.Insert(0, number);
    
        return results;
    }
    


    I assume that if you still have a number greater then 10 you are going to divide it by 10.
    123 /10   remaining by %10 would  be 3 so that number would be seperate for 1 value already?

    static ulong Sum(List<ulong> numbers)
    {
        ulong result = 0;
    
        foreach (ulong number in numbers)
            result += number;
    
        return result;
    }
    

    Not exactly sure what is happening here. Although i have written a PSD on paper with some logic that also contains a total or result + the number.

    Basicly you are summing up every number in here if i am correct. Number 123 would be 1+2+3 in here or?
    So it takes the value then goes on to the next number in the list and on...


    Thanks again for all the input.

    2009年12月18日 16:36
  • You're going to need either an array or a list either way, because you want to take a single number (say 12345) and split it into a bunch of numbers (1, 2, 3, 4, 5). Here's what a method would have to look like if you didn't want to use an array or list:

    static void SplitNumber(ulong inNum, out ulong splitNumber1, out ulong splitNumber2, out ulong splitNumber3, etc... You would need to have as many of these as you could possibly have digits, which is 20 for ulong. Lists are easy to work with though, they're exactly what they sound like. A List<ulong> is a list of ulong variables.

    Basically how split number works is it breaks off the last digit using % 10, you got that part right, and then divides the original number by 10. For example:

    number = 4563
    List<ulong> =

    After first loop:
    number = 456
    List<ulong> = 3

    After second loop:
    number = 45
    List<ulong> = 3, 6

    After third loop:
    number = 4
    List<ulong> = 3, 6, 5

    And now the number is less than 10, so the loop stops, and we add the final number on
    List<ulong> = 3, 6, 5, 4

    You can see that the list is backwords, and this is what would happen if we used results.Add(number % 10), because that adds the number onto the end. Instead we use results.Insert(0, number % 10). Insert inserts the number at the specified index. We use the index 0 to say we want to insert right at the front. So now when we loop we always add to the front:

    3
    6, 3
    5, 6, 3
    4, 5, 6, 3

    The Sum method is easier. You can see that it takes a list of ulongs, which we got from SplitNumber. It loops through the numbers in the list, adding each one to the total (result), then returns the total. The foreach loop is an easy way to loop through every item in a list, it is equivalent to this:

    for (int i = 0; i < numbers.Count; i++)
        result += numbers[i];

    which is also equivalent to this:

    int i = 0;
    while(i < numbers.Count)
    {
        result += numbers[i];
        i++;
    }

    To clarify a few more things, in case you don't get them:
    The [] brackets are used to specify the index you want, so for our example, numbers[0] = 4, numbers[1] = 5, numbers[2] = 6 and numbers[3] = 3.
    result += numbers[i] is the same as result = result + numbers[i]
    i++ is the same as i += 1 is the same as i = i + 1
    • 已标记为答案 Chrisznl 2009年12月18日 17:03
    2009年12月18日 16:55
  • Actually, you don't need to use the fancy datastructures.  To be more in line with an intro to programming class (sans data structures):

    public void Test()
    {
        bool doWeHaveLuck;
    
        doWeHaveLuck = this.IsLucky(6);          // false
        doWeHaveLuck = this.IsLucky(7);          // true
        doWeHaveLuck = this.IsLucky(12345);   // false
        doWeHaveLuck = this.IsLucky(12346);   // true
    }
    
    private bool IsLucky(int value)
    {
        if (value < 0)
        {
            return false;    
        }
    
        do
        {
            value = Reduce(value);
        } while (value > 10);
    
        return (value == 7);
    }
    
    private int Reduce(int number)
    {
        int result = 0;
        int wholeNumber;
    
        if (number < 10)
        {
            return number;
        }
    
        do
        {
            int remainder = number % 10;
            number = number / 10;
            result += remainder;
        } while (number > 0);
    
        return result;
    }



    Michael Fischer

    2009年12月18日 21:31
  • bool IsLucky(int value)
    {
        return value%9==7;
    }
    2009年12月22日 16:25
  • Ah, someone that paid more attention in math.  Nice shortcut. 

    Doesn't really let Chrisznl practice writing algorithms though! :)

    Michael Fischer
    2009年12月22日 17:24
  • I guess not. I like this one:
    bool IsLucky(int value)
    {
        if (value == 7) return true;
        if (value < 10) return false;
    
        return IsLucky((from c in value.ToString() select c).Sum(c => c - '0'));
    }
    2009年12月23日 9:07