any java programmers out there?

The assignment, from

__Thinking in Java__by Bruce Eckel:

Avampire numberhas 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

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.

ReplyDeleteimport 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;

}

}

}

}

}

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

ReplyDeleteSorry for bad English.

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

ReplyDeleteMy 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");

}

}

Here is my version:

ReplyDeletepublic 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));

}

}

public class VampNumbers {

ReplyDelete//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));

}

}

}

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

ReplyDeleteimport 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");

}

}

}