Results 1 to 19 of 19

Thread: Vampire Numbers

  1. #1
    Beginner's Avatar
    Beginner is offline Member
    Join Date
    Apr 2010
    Posts
    25
    Rep Power
    0

    Default Vampire Numbers

    This is an exercise in the book "Thinking in Java" and it says I need to find all the 4 digit Vampire Numbers

    I have indeed finished the exercise and produced working code:

    Java Code:
    import java.util.Arrays;
    
    class Vampire {
    	public static void main(String[] args) {
    		for(int i=11; i<100; i++) {
    			for(int j=i; j<100; j++) {
    				int k = i * j;
    				
    				String kStr = Integer.toString(k);
    				String checkStr = Integer.toString(i) + Integer.toString(j);
    				
    				//if(kStr.length() != 4) break;
    				
    				char[] kChar = kStr.toCharArray();
    				char[] checkChar = checkStr.toCharArray();
    				
    				Arrays.sort(kChar);
    				Arrays.sort(checkChar);
    				
    				boolean isVampire = Arrays.equals(kChar, checkChar);
    				
    				if(isVampire) {
    					System.out.println(i + " * " + j + " = " + k);
    				}
    			}
    		}
    	}
    }
    If you try and run this, it will run perfectly and find all the 4 digit vampire numbers. However, I commented out the line "if(kStr.length() != 4) break;" because if you include that line, it somehow misses some of the vampire numbers. That line of code will supposedly decrease the processing time because it will skip all non-4 digit numbers, because as the exercise asked, I need to find only the 4-digit numbers. Can anyone find out why that line of code doesn't work? Try running the code without that line, then try running it with that line.

  2. #2
    Sno's Avatar
    Sno
    Sno is offline Senior Member
    Join Date
    Apr 2010
    Posts
    195
    Rep Power
    5

    Default

    so --
    i = 11
    j = 11
    k = 121
    kStr = 121
    checkStr = 1111

    if(kStr.length() != 4) break; (Right now that would be false) Whats the point of this line?

    shouldn't it be
    Java Code:
    if(kStr.length() != 4){
     break;
    } 
    else {
    				
    char[] kChar = kStr.toCharArray();
    char[] checkChar = checkStr.toCharArray();
    				
    Arrays.sort(kChar);
    Arrays.sort(checkChar);
    				
    boolean isVampire = Arrays.equals(kChar, checkChar);
    				
    if(isVampire) {
    System.out.println(i + " * " + j + " = " + k);
    }
    :rolleyes: ~ Sno ~ :rolleyes:
    '-~ B.S. Computer Science ~-'

  3. #3
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,764
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by Beginner View Post
    If you try and run this, it will run perfectly and find all the 4 digit vampire numbers. However, I commented out the line "if(kStr.length() != 4) break;" because if you include that line, it somehow misses some of the vampire numbers. That line of code will supposedly decrease the processing time because it will skip all non-4 digit numbers, because as the exercise asked, I need to find only the 4-digit numbers. Can anyone find out why that line of code doesn't work? Try running the code without that line, then try running it with that line.
    If you break from the inner loop if the product k doesn't have four digits you may stop the search too early, e.g. 15x15 has only three digits (225); if you break out of the loop you'll never find 15x93 which is a Vampire number. You can break out of the loop when k has more than four digits (which is never going to happen).

    kind regards,

    Jos

    edit: you can start at j=Math.max(1000/i, i)
    Last edited by JosAH; 06-29-2010 at 05:22 PM.

  4. #4
    Beginner's Avatar
    Beginner is offline Member
    Join Date
    Apr 2010
    Posts
    25
    Rep Power
    0

    Default

    Quote Originally Posted by JosAH View Post
    If you break from the inner loop if the product k doesn't have four digits you may stop the search too early, e.g. 15x15 has only three digits (225); if you break out of the loop you'll never find 15x93 which is a Vampire number. You can break out of the loop when k has more than four digits (which is never going to happen).

    kind regards,

    Jos
    Thanks for pointing that out Jos! What I wanted to do was not break, but it was continue, I mis-analyzed it. Thank you for saving me from headaches :)

  5. #5
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,764
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by Sno View Post
    so --
    i = 11
    j = 11
    k = 121
    kStr = 121
    checkStr = 1111

    if(kStr.length() != 4) break; (Right now that would be false) Whats the point of this line?
    You do realize that this for loop body:

    Java Code:
    if (<condition>) break;
    <statement>;
    ... is identical to this for loop body?

    Java Code:
    if (<condition>)
       break;
    else
       <statement>;
    kind regards,

    Jos

  6. #6
    Sno's Avatar
    Sno
    Sno is offline Senior Member
    Join Date
    Apr 2010
    Posts
    195
    Rep Power
    5

    Default

    Well the way he had it,

    I was taught, that if you did not have brackets, it would only effect the line that it is on, and the one below,

    two lines below it wouldn't consider it to be part of the if statement.

    so I figured his if statement was only affecting the break, and not dealing with anything else.
    :rolleyes: ~ Sno ~ :rolleyes:
    '-~ B.S. Computer Science ~-'

  7. #7
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,764
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by Beginner View Post
    Thanks for pointing that out Jos! What I wanted to do was not break, but it was continue, I mis-analyzed it. Thank you for saving me from headaches :)
    Yep, the 'continue' statement will skip the failing calculations; also read my first reply (I edited it afterwards) for a tighter lowerbound on the loop variable j.

    kind regards,

    Jos

  8. #8
    Beginner's Avatar
    Beginner is offline Member
    Join Date
    Apr 2010
    Posts
    25
    Rep Power
    0

    Default

    Good thinking! That will certainly eliminate all the 3 Digit results

  9. #9
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,764
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by Beginner View Post
    Good thinking! That will certainly eliminate all the 3 Digit results
    Yep, and there won't be any five digit results (both i and j < 100) so the entire if (<condtion>) break; statement can go.

    kind regards,

    Jos

  10. #10
    toylord is offline Member
    Join Date
    Jul 2010
    Posts
    5
    Rep Power
    0

    Default

    Quote Originally Posted by JosAH View Post
    Yep, and there won't be any five digit results (both i and j < 100) so the entire if (<condtion>) break; statement can go.

    kind regards,

    Jos
    Hi guys, I have the solution to the exercise. Let me know if you want it posted.

    Yeamin.

  11. #11
    toylord is offline Member
    Join Date
    Jul 2010
    Posts
    5
    Rep Power
    0

    Default

    Quote Originally Posted by toylord View Post
    Hi guys, I have the solution to the exercise. Let me know if you want it posted.

    Yeamin.
    Sorry, I meant the solution as printed on the Solution Guide by B. Eckel.

  12. #12
    Singing Boyo is offline Senior Member
    Join Date
    Mar 2009
    Posts
    552
    Rep Power
    6

    Default

    Quote Originally Posted by toylord View Post
    Sorry, I meant the solution as printed on the Solution Guide by B. Eckel.
    You do realize they solved it right? :)
    If the above doesn't make sense to you, ignore it, but remember it - might be useful!
    And if you just randomly taught yourself to program, well... you're just like me!

  13. #13
    toylord is offline Member
    Join Date
    Jul 2010
    Posts
    5
    Rep Power
    0

    Default

    Quote Originally Posted by Singing Boyo View Post
    You do realize they solved it right? :)
    I do sir! It's just that the the solution to the exercise is done a bit differently I suppose therefore I thought it might be worthwhile for others if i pasted it in.

    Regards
    Yeamin.

  14. #14
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,764
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by toylord View Post
    I do sir! It's just that the the solution to the exercise is done a bit differently I suppose therefore I thought it might be worthwhile for others if i pasted it in.
    Well, go ahead then, post your solution; maybe we can all learn from it. The OP's solution is quite simple: it searches 9000 possibilites for only 7 results; can your solution do better?

    kind regards,

    Jos

  15. #15
    toylord is offline Member
    Join Date
    Jul 2010
    Posts
    5
    Rep Power
    0

    Default

    Here it is:

    Java Code:
    public class E10_Vampire {
    
    public static void main(String[] args) {
    
    int[] startDigit = new int[4];
    int[] productDigit = new int[4];
    
    for(int num1 = 10; num1 <= 99; num1++)
    for(int num2 = num1; num2 <= 99; num2++) {
    
    // Pete Hartley's theoretical result:
    // If xy is a vampire number then
    // xy == x+y (mod 9)
    if((num1 * num2) % 9 != (num1 + num2) % 9)
    continue;
    int product = num1 * num2;
    startDigit[0] = num1 / 10;
    startDigit[1] = num1 % 10;
    startDigit[2] = num2 / 10;
    startDigit[3] = num2 % 10;
    productDigit[0] = product / 1000;
    productDigit[1] = (product % 1000) / 100;
    productDigit[2] = product % 1000 % 100 / 10;
    productDigit[3] = product % 1000 % 100 % 10;
    
    int count = 0;
    
    for(int x = 0; x < 4; x++)
    for(int y = 0; y < 4; y++) {
    
    if(productDigit[x] == startDigit[y]) {
    count++;
    productDigit[x] = -1;
    startDigit[y] = -2;
    if(count == 4)
    System.out.println(num1 + " * " + num2
    + " : " + product);
    }
    }
    }
    }
    } /* Output:
    15 * 93 : 1395
    21 * 60 : 1260
    21 * 87 : 1827
    27 * 81 : 2187
    30 * 51 : 1530
    35 * 41 : 1435
    80 * 86 : 6880
    *///:~

  16. #16
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,764
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by toylord View Post
    Java Code:
    for(int num1 = 10; num1 <= 99; num1++)
    for(int num2 = num1; num2 <= 99; num2++) {
    
    // Pete Hartley's theoretical result:
    // If xy is a vampire number then
    // xy == x+y (mod 9)
    if((num1 * num2) % 9 != (num1 + num2) % 9)
    continue;
    So we can conclude that your loop boundary conditions are weaker than what I suggested and your test for avoiding calculations that can never succeed are stronger than in the code OP's code (there is no such condition there).

    kind regards,

    Jos

  17. #17
    toylord is offline Member
    Join Date
    Jul 2010
    Posts
    5
    Rep Power
    0

    Default

    Quote Originally Posted by JosAH View Post
    So we can conclude that your loop boundary conditions are weaker than what I suggested and your test for avoiding calculations that can never succeed are stronger than in the code OP's code (there is no such condition there).

    kind regards,

    Jos
    Well it is not my solution. It is the official solution to the exercise by Bruce Eckel himself. I have my own solution but it's pretty similar to the one that 'beginner' suggested.

    Regards

  18. #18
    srinivas463 is offline Member
    Join Date
    Aug 2011
    Posts
    1
    Rep Power
    0

    Default srinivas

    Quote Originally Posted by Beginner View Post
    This is an exercise in the book "Thinking in Java" and it says I need to find all the 4 digit Vampire Numbers

    I have indeed finished the exercise and produced working code:

    Java Code:
    import java.util.Arrays;
    
    class Vampire {
    	public static void main(String[] args) {
    		for(int i=11; i<100; i++) {
    			for(int j=i; j<100; j++) {
    				int k = i * j;
    				
    				String kStr = Integer.toString(k);
    				String checkStr = Integer.toString(i) + Integer.toString(j);
    				
    				 if(kStr.length() != 4) continue;
    				
    				char[] kChar = kStr.toCharArray();
    				char[] checkChar = checkStr.toCharArray();
    				
    				Arrays.sort(kChar);
    				Arrays.sort(checkChar);
    				
    				boolean isVampire = Arrays.equals(kChar, checkChar);
    				
    				if(isVampire) {
    					System.out.println(i + " * " + j + " = " + k);
    				}
    			}
    		}
    	}
    }
    If you try and run this, it will run perfectly and find all the 4 digit vampire numbers. However, I commented out the line "if(kStr.length() != 4) break;" because if you include that line, it somehow misses some of the vampire numbers. That line of code will supposedly decrease the processing time because it will skip all non-4 digit numbers, because as the exercise asked, I need to find only the 4-digit numbers. Can anyone find out why that line of code doesn't work? Try running the code without that line, then try running it with that line.



    HI ...
    you just put CONTINUE instead BREAK.
    then it will give perfect result

  19. #19
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,458
    Rep Power
    20

Similar Threads

  1. Counting numbers up and down
    By radio in forum New To Java
    Replies: 4
    Last Post: 05-06-2011, 04:03 PM
  2. Sum of 4 numbers...!?
    By xmenus in forum New To Java
    Replies: 7
    Last Post: 02-14-2010, 04:36 PM
  3. How to Spell out numbers?
    By syntrax in forum New To Java
    Replies: 5
    Last Post: 10-22-2009, 04:34 PM
  4. printing two smallest numbers from a series of numbers
    By trofyscarz in forum New To Java
    Replies: 2
    Last Post: 10-15-2008, 12:46 AM
  5. random numbers
    By carlos123 in forum New To Java
    Replies: 1
    Last Post: 12-22-2007, 03:56 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •