1. ## 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. 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);
}```

3. Originally Posted by Beginner
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 04:22 PM.

4. Originally Posted by JosAH
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. Originally Posted by Sno
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. 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.

7. Originally Posted by Beginner
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. Good thinking! That will certainly eliminate all the 3 Digit results

9. Originally Posted by Beginner
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. Member
Join Date
Jun 2010
Posts
5
Rep Power
0
Originally Posted by JosAH
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. Member
Join Date
Jun 2010
Posts
5
Rep Power
0
Originally Posted by toylord
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. Senior Member
Join Date
Mar 2009
Posts
552
Rep Power
8
Originally Posted by toylord
Sorry, I meant the solution as printed on the Solution Guide by B. Eckel.
You do realize they solved it right? :)

13. Member
Join Date
Jun 2010
Posts
5
Rep Power
0
Originally Posted by Singing Boyo
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. Originally Posted by toylord
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. Member
Join Date
Jun 2010
Posts
5
Rep Power
0
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 x·y is a vampire number then
// x·y == 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. Originally Posted by toylord
Java Code:
```for(int num1 = 10; num1 <= 99; num1++)
for(int num2 = num1; num2 <= 99; num2++) {

// Pete Hartley's theoretical result:
// If x·y is a vampire number then
// x·y == 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. Member
Join Date
Jun 2010
Posts
5
Rep Power
0
Originally Posted by JosAH
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. Member
Join Date
Aug 2011
Posts
1
Rep Power
0

## srinivas

Originally Posted by Beginner
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. The thread is over a year old. Locking up here.

db

#### Posting Permissions

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