May 31, 2007

i'm learning java..

Everyone who reads this for my fitness or ramblings or whatever, please indulge me for a second while I do this..

any java programmers out there?

The assignment, from Thinking in Java by Bruce Eckel:
A vampire number has an even number of digits and is formed by multiplying a pair of numbers containing half the number of digits as the results. The digits are taken from the original number in any order. Pairs of trailing zeros are not allowed. Examples include:
1260=21*60
1827=21*87
2187=27*81
Write a program that finds all the 4-digit vampire numbers."


so I wrote this from scratch. It works, and produces the correct result, but I'm sure there is a more elegant way of doing it- especially with getArrayOfDigits(). I don't know if there are any java developers who read my blog, but if there are, a little criticism would be appreciated.

import static net.mindview.util.Print.*;
// the print() method is identical to System.out.println().

public class Exercise10 {

public static void main(String[] args) {

for (int i=1000; i<10000;i++ )
{
if(i%100==0) continue; //weed out the numbers with two trailing zeros
int[] result = isVampire(i);
if(result != null) {
print(result[0] + "*" + result[1] + "=" + i + ". It's a vampire number");
}
}
}


private static int[] getArrayOfDigits(int i) {
//I am sure this can be done better
int[] a = {0,0,0,0};

a[0] = ((int)i/1000);
i=i-a[0]*1000;
a[1] = ((int)i/100);
i=i-a[1]*100;
a[2] = ((int)i/10);
a[3]=i-a[2]*10;

return a;

}


private static int[] isVampire(int i) {

int[] arr = getArrayOfDigits(i);

for(int a=0; a<=3;a++) {

for (int b=0;b<=3 ;b++ ) {
if(a==b) continue;

for (int c=0;c<=3 ;c++ ) {
if(a==c) continue;
if(b==c) continue;

for (int d=0;d<=3 ;d++ ) {
if(a==d) continue;
if(b==d) continue;
if(c==d) continue; //this series of continues can probably be done better, too.

if(GetTestNumber(arr[a],arr[b]) * GetTestNumber(arr[c],arr[d]) == i) {
int[] done={GetTestNumber(arr[a],arr[b]), GetTestNumber(arr[c],arr[d])};
return done;
}
}
}
}
}

return null;

}


private static int GetTestNumber(int a, int b) {
return ((a*10)+b);
}

}


thanks..
-steve

6 comments:

  1. I actually have the same book and have been a programmer for 3 days now :-) I have no idea which way is better but I took a very different approach so I thought I would share it. I converted the numbers to a string and then use the built in toCharArray() method. I also started with the two 2 digit numbers.

    import static net.mindview.util.Print.*;
    import java.util.*;

    public class Vampire {

    public static boolean isVampire(int mult1, int mult2) {

    int whole = (mult1 * mult2);

    String wholeString = Integer.toString(whole);
    String mult1String = Integer.toString(mult1);
    String mult2String = Integer.toString(mult2);

    String multString = mult1String + mult2String;

    char[] wholeArray = wholeString.toCharArray();
    char[] multArray = multString.toCharArray();

    //used to keep track of where we are in the array. increments every time we get a match
    int removeChar = 0;

    //arrays used to make sure we discard chars when we match them up
    int[] iArray = {5, 5, 5, 5};
    int[] jArray = {5, 5, 5, 5};

    //main loop to test each char in wholeArray against char in multArray 1 by 1
    iLoop:
    for(int i = 0; i < 4; i++) {

    //no reason to keep checking once we miss a match
    if((removeChar < i)) {
    break;
    }

    for(int p = 0; p < 4; p++) {

    //if this array spot already has a match skip it. not an efficiency thing. it avoids dups.
    if(i == iArray[p]) {
    continue iLoop;
    }
    }

    jLoop:
    for(int j = 0; j < 4; j++) {

    for(int q = 0; q < 4; q++) {

    //if this array spot already has a match skip it. not an efficiency thing. it avoids dups.
    if(j == jArray[q]) {
    continue jLoop;
    }
    }

    if(wholeArray[i] == multArray[j]) {

    //load the char array position when we find a match so we skip those later
    iArray[removeChar] = i;
    jArray[removeChar] = j;
    removeChar++;
    //these array locations can't be used again so continue in the outer loop
    continue iLoop;

    }
    }
    }

    //if we replace all the 5s in the array we have a vampire
    if(iArray[3] != 5) {
    return true;
    } else {
    return false;
    }
    }

    public static void main(String[] args) {

    //lists that vampire numbers will be added to and checked for twins
    ArrayList<Integer> twinListx = new ArrayList<Integer>();
    ArrayList<Integer> twinListy = new ArrayList<Integer>();

    //main loop. check every 2 digit number with ever 2 digit number
    for(int x = 10; x < 100; x++) {

    //secondary main loop. label used for twin continues
    yLoop:
    for(int y = 10; y < 100; y++) {

    //we only want 4 digit vampires
    if(((x * y) < 1000)||((x * y) > 9999))
    continue;

    //check to see if y and x exist in the same position in the opposite arrays - this removes duplicate results
    for(int g = 0; (twinListx.size() != 0)&&(g < twinListx.size()); g++) {
    if((twinListx.get(g) == y)&&(twinListy.get(g) == x))
    continue yLoop;
    }

    //use isVampire method to see if the combo makes a vampire
    if(isVampire(x, y)) {
    print((x * y) + " = " + x + " * " + y + " is a vampire number!");
    twinListx.add(x);
    twinListy.add(y);
    } else {
    continue;
    }
    }
    }
    }

    }

    ReplyDelete
  2. Steve, I saw that exercise and I think your approach is simpler than shanegary. You use only the knowledge until that chapter.

    Sorry for bad English.

    ReplyDelete
  3. This is late response, but for future reference to other people starting out like me, it might be helpful to see more different solution.

    My solution is similar to flasfs
    but what I did was convert the
    fangs and vampire number to char
    array, then sorted them, and
    compared.

    BTW : this method is brute force.

    Here is the code :



    //package random_practice;
    /* This program produces all fangs and its corresponding vampire number
    from fang degree 2( ex 15 * 93) to the variable fangDeg (see below)
    */

    import java.util.Arrays;


    public class Main {

    public static void print(Object obj){
    System.out.print(obj);
    }
    public static void print() {
    System.out.println();
    }
    static public boolean vampSrch(int f, int s, int res){

    /* Convert f and s int char array as well as res to char array */
    String str = Integer.toString(f);
    str += Integer.toString(s);
    char[] C = new char[5];
    C = str.toCharArray();
    Arrays.sort(C);
    String str2 = Integer.toString(res);
    char[] C2 = new char[str2.length() + 1];
    C2 = str2.toCharArray();
    //Sort array to start test
    Arrays.sort(C2);

    //check if worth testing
    if( C.length != C2.length) return false;
    //test each character to similarity
    for(int i = 0; i < C.length ; i++)
    if( C[i] != C2[i])
    return false;

    return true;



    }
    public static void main(String[] args)
    {
    int i = 10;
    int j = 10;

    //change this if you want to find a n variable degree fang
    int fangsDeg = 2;// 2nd degreed fangs

    int totFangs = 0;
    int iLim = 1;
    int maxLim = 1;

    while(fangsDeg > 0){
    iLim *= 10;
    fangsDeg--;
    }

    maxLim = iLim * 100 - 1;

    while(i <= iLim )
    {

    if( i*j > maxLim ){
    i++;
    j = 10;
    }
    if( vampSrch(i,j,i*j)){
    print(i + "*" + j + " = " + i*j + "\n");
    totFangs++;
    //Check for no repeat
    if( i / 10 > j/10)
    break;
    }
    j++;

    }

    print("\nThe total number of fangs is " + totFangs + "\n\n");
    }
    }

    ReplyDelete
  4. Here is my version:

    public class Main {

    static boolean VampN(int x, int y) {
    if( Integer.toString(x*y).length()==4 ) {
    int[] d = {x*y/1000,(x*y-(x*y/1000)*1000)/100,(x*y-(x*y/100)*100)/10,x*y-(x*y/10)*10};
    int[] di = {0,0,0,0};

    for (int i=0; i<4; i++)
    if(x/10 == d[i] && di[i] == 0) {
    di[i]=1;
    break;
    }
    for (int i=0; i<4; i++)
    if(x-(x/10)*10 == d[i] && di[i] == 0) {
    di[i]=1;
    break;
    }
    for (int i=0; i<4; i++)
    if(y/10 == d[i] && di[i] == 0) {
    di[i]=1;
    break;
    }
    for (int i=0; i<4; i++)
    if(y-(y/10)*10 == d[i] && di[i] == 0) {
    di[i]=1;
    break;
    }
    for (int i=0; i<4; i++)
    if(di[i]==0) return false;
    }
    else
    return false;
    return true;
    }

    public static void main(String[] args) {
    // TODO code application logic here
    for( int i=10; i<=99; i++)
    for(int j=10; j<=99; j++)
    if (VampN(i, j))
    System.out.println(i+" x "+j+" = "+(i*j));
    }

    }

    ReplyDelete
  5. public class VampNumbers {

    //method to join two single digits into a two digit number
    static int join(int x, int y){
    return(x * 10) + y;
    }

    //method to print vampire number if two derived numbers are equal to original
    static void printVamp(int i, int x, int y){
    if((x*y)==i){
    System.out.println(i + " is a vampire number");
    }
    }

    public static void main(String[] args) {
    for(int i = 1000; i <=9999; i++){

    //break 4 digit number into single digits
    int a = i / 1000;
    int b = (i % 1000) / 100;
    int c = ((i % 1000) % 100) / 10;
    int d = ((i % 1000) % 100) % 10;

    //send all variations of multiplication to the printVamp method
    printVamp(i, join(a, b), join(c, d));
    printVamp(i, join(a, b), join(d, c));
    printVamp(i, join(a, c), join(b, d));
    printVamp(i, join(a, c), join(d, b));
    printVamp(i, join(a, d), join(b, c));
    printVamp(i, join(a, d), join(c, b));
    printVamp(i, join(b, a), join(c, d));
    printVamp(i, join(b, a), join(d, c));
    printVamp(i, join(b, c), join(d, a));
    printVamp(i, join(b, d), join(c, a));
    printVamp(i, join(c, a), join(d, b));
    printVamp(i, join(c, b), join(d, a));
    }
    }
    }

    ReplyDelete
  6. I prefer simple very simple and easy to understand coding. I hope this helps :)

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    /**
    *
    * @author Abhinav Mathur
    */
    class NewClass3
    {
    public static void main(String args[]) throws IOException
    {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    int e=0;
    System.out.print("Enter 1st two digit number = ");
    int a = Integer.parseInt(br.readLine());
    System.out.print("Enter 2nd two digit number = ");
    int b = Integer.parseInt(br.readLine());
    int c=a*b;
    int f=c;
    int d=a*100+b;
    for(int i=0;i<4;i++)
    {
    int num1=d%10;
    d=d/10;
    c=f;
    for(int j=0;j<4;j++)
    {
    int num2=c%10;
    c=c/10;
    if(num1==num2)
    {
    e++;
    }
    }
    }
    if(e==4)
    {
    System.out.println("VAMPIRE NUMBER");
    }
    else{
    System.out.print("NOT A VAMPIRE NUMBER");
    }
    }
    }


    ReplyDelete