Recursion Coin Change - java

Need help figuring out how to print the individual coins such as quarters = 3, pennies = 1, instead of just giving me 4 coins for 76 cents. I tried setting 4 counters, but that just repeatedly printed out the coin names and answers were wrong.
import java.util.Scanner;
public class Money
{
public static void main(String args[])
{
int[] coins = { 1, 5, 10, 25};
Scanner scan = new Scanner(System.in);
System.out.print("Enter Change (In Cents): ");
int sum = scan.nextInt();
int counter1 = 0;
int counter2 = 0;
int counter3 = 0;
int counter4 = 0;
String quarter = "";
Money minCoin = new Money();
System.out.println(minCoin.findMinCoins(coins, sum, counter1, counter2, counter3, counter4));
System.out.println(counter4);
}
private int findMinCoins(int[] coins, int sum, int counter1, int counter2, int counter3, int counter4)
{
if (sum <= 0 || coins.length == 0)
{
return 0;
}
for (int i = coins.length - 1; i >= 0; i--)
{
if(coins[i] == 1 && coins[i] != 5)
{
counter1++;
}
if(coins[i] == 5)
{
counter2++;
}
if(coins[i] == 10)
{
counter3++;
}
if(coins[i] == 25)
{
counter4++;
}
if (coins[i] <= sum)
{
System.out.println("Pennies: " + counter1);
System.out.println("Nickels: " + counter2);
System.out.println("Dimes: " + counter3);
System.out.println("Quarters: " + counter4);
return 1 + findMinCoins(coins, sum - coins[i], counter1, counter2, counter3, counter4);
}
}
return 0;
}
}

Try this:
import java.util.Scanner;
public class Money
{
public static void main(String[] args) {
int[] coins = {1, 5, 10, 25};
Scanner scan = new Scanner(System.in);
System.out.print("Enter Change (In Cents): ");
int sum = scan.nextInt();
int counter1 = 0;
int counter2 = 0;
int counter3 = 0;
int counter4 = 0;
String quarter = "";
Money minCoin = new Money();
System.out.println(minCoin.findMinCoins(coins, sum, counter1, counter2, counter3, counter4));
System.out.println(counter4);
}
private int findMinCoins(int[] coins, int sum, int counter1, int counter2, int counter3, int counter4) {
if (sum <= 0 || coins.length == 0) {
return 0;
}
for (int i = coins.length - 1; i >= 0; i--) {
if (coins[i] == 25 && sum >= coins[i]) {
counter4++;
}
else if (coins[i] == 10 && sum >= coins[i]) {
counter3++;
}
else if (coins[i] == 5 && sum >= coins[i]) {
counter2++;
}
else if (coins[i] == 1 && sum >= coins[i]) {
counter1++;
}
if (coins[i] <= sum) {
System.out.println("Pennies: " + counter1);
System.out.println("Nickels: " + counter2);
System.out.println("Dimes: " + counter3);
System.out.println("Quarters: " + counter4);
return 1 + findMinCoins(coins, sum - coins[i], counter1, counter2, counter3, counter4);
}
}
return 0;
}
}

I suspect you have misunderstood how arguments passed to Java methods work. You are passing in the 'counter' values and then iterating them inside the method and expecting their values in the calling method to have changed. That's not how Java works. See here for more details.
If you're not expecting to get the values back from the method (because you're printing them inside) then there's no point making them arguments. Best to make it a local variable inside the scope of the method.
You might find it a bit easier if you order from largest to smallest and return an array from your change calculator. Then you won't need individual variables for your counters.
Something like the following:
int[] coins = {25, 10, 5, 1};
String[] names = {"Quarters", "Dimes", "Nickles", "Pennies"};
int[] change = getChange(coins, total);
for (int i = 0; i < change.length; i++) {
System.out.println(names[i] + ":" + change[i]);
}
private int[] getChange(int[] coins, int total) {
int[] result = new int[coins.length];
for (int i = 0; i < coins.length; i++) {
result[i] = total / coins[i];
total -= result[i] * coins[i];
}
return result;
}
Note that this takes advantage of Java's integer division rounding down. So if you start with 76 cents it will return 3 quarters (76/25 -> 3). Note also that the second statement in the loop could be total %= coins[i] which would have the same effect but might be more understandable. Either way the code is saying 'remove from the total the value of the current denomination`.

Related

To find out Armstrong number in between numbers

Below is my code.
package com.ofss.java.examples;
import java.util.Scanner;
class ArmstrongNumber {
public static void main(String[] args) {
int c = 0, a;
int n1, n2;//Range in which armstrong number need to find
Scanner s = new Scanner(System.in);
System.out.println("Enter the first number");
n1 = s.nextInt();
System.out.println("Enter the second number");
n2 = s.nextInt();
for (int i = n1; i <= n2; ++i) {
while (i > 0) {
a = i % 10;
System.out.println(a);
i = i / 10;
System.out.println(i);
c = c + (a * a * a);
System.out.println(c);
}
if (i == c)
System.out.println(c + "armstrong number");
else
System.out.println(c + "Not armstrong number");
}
}
}
I am getting incorrect results after executing. Code runs for infinite number till you stops it. It must print number between 151-154 (153 as armstrong).
Also, it is incorrectly printing 153 as not Armstrong number.
Armstrong Number
...is a number that is the sum of its own digits each raised to the power of the number of digits.
You should not change i since this is also used in
for (int i = n1; i <= n2; ++i)
Or you will probably never exit that loop eiter since you expect i to be negative at the end of the first iteration. Hard to increment until it reach n2.
Use a different variable to keep track of i safely.
int j = i;
while(j > 0) ...
About Armstrong number:
Armstrong number is a number that is the sum of its own digits each raised to the power of the number of digits
You need to put each digit to the power of the length of the number (the number of digit).
153 = 1^3 + 5^3 + 3^3
1634 = 1^4 + 6^4 + 3^4 + 4^4
Here is the method for it :
public static boolean isArmstrongNumber(int number){
int power = Integer.toString(number).length(); //just to get the number of digit...
int tmp = number;
int digit , sum = 0;
while(tmp > 0){
digit = tmp % 10;
sum += Math.round(Math.pow(digit , power));
tmp /= 10;
}
return sum == number;
}
Using this check from 0 to 10.000 gives :
0
1
2
3
4
5
6
7
8
9
153
370
371
407
1634
8208
9474
Same as Wikipedia :
The sequence of base 10 narcissistic numbers starts: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407, 1634, 8208, 9474, ...
Note that using a method remove the risk of forgetting to reset your variable like c in your case. Correcting this would give you a few more "correct" results (well the one with 3 digits)
You can also use less mathematics to read the number and use char[], remember that you need to substract '0' value to get the numeric value for a character :
public static boolean isArmstrongNumber(int number){
char[] digits = Integer.toString(number).toCharArray();
int power = digits.length;
int sum = 0;
for(char c : digits){
int digit = c - '0';
sum += Math.round(Math.pow(digit, power));
}
return sum == number;
}
There are two things.
you are updating i everytime as you have used it in while, so use different variable than i for this calculation.
int num = i;
c is used to compare sum of cube is same as number but you are not resetting it once the one iteration is over. so make c=0 inside for loop.
c = 0;
Also while printing you are using c, there should be i which is correct and real number.
Below is the working code you may try.
public static void main(String[] args)
{
int c = 0, a;
int n1, n2;//Range in which armstrong number need to find
Scanner s = new Scanner(System.in);
System.out.println("Enter the first number");
n1 = s.nextInt();
System.out.println("Enter the second number");
n2 = s.nextInt();
for (int i = n1; i <= n2; ++i)
{
int num = i;
while (num > 0)
{
a = num % 10;
num = num / 10;
c = c + (a * a * a);
}
if (i == c)
System.out.println(i + "armstrong number");
else
System.out.println(i + "Not armstrong number");
c = 0;
}
}
public class ArmstrongNumber {
private final int n1, n2;
public ArmstrongNumber(int n1, int n2) {
this.n1 = n1;
this.n2 = n2;
}
protected static boolean isArmstrong(int n) {
if(n < 0)
return false;
int remaining=n;
int sumCube=0;
while (remaining>0) {
int d = remaining % 10;
sumCube += cube(d);
remaining /= 10;
}
return n == sumCube;
}
private static int cube(int d) {
return d*d*d;
}
public Integer[] find() {
List<Integer> results = new ArrayList<>();
for (int i = n1; i <= n2; ++i)
{
if (isArmstrong(i))
results.add(i);
}
return results.toArray(new Integer[0]);
}
}
There are lot of things to improve in your code. One of the working logics as below:
for (int i = n1; i <= n2; ++i) {
int sum = 0, remainder = 0, digits = 0, temp = 0;
temp = i;
while (temp != 0) {
digits++;
temp = temp / 10;
}
temp = i;
while (temp != 0) {
remainder = temp % 10;
sum = sum + (int) Math.pow(remainder, digits);
temp = temp / 10;
}
if (i == sum)
System.out.println(i + " is an Armstrong number.");
else
System.out.println(i + " isn't an Armstrong number.");
}

How can I use values stored in an array to another method to do a calculation?

static void diceRoll(int[] val) {
for (int i=0;i<6;i++) {
int roll1 = (int) ((Math.random() * 1000 % 6 + 1));
int roll2 = (int) ((Math.random() * 1000 % 6 + 1));
int roll3 = (int) ((Math.random() * 1000 % 6 + 1));
int roll4 = (int) ((Math.random() * 1000 % 6 + 1));
int total =0;
if ((roll1 < roll2) && (roll1 < roll3) && (roll1 < roll4)) {
total= roll2 + roll3 + roll4;
} else if ((roll2 < roll1) && (roll2 < roll3) && (roll2 < roll4)) {
total= roll1 + roll3 + roll4;
} else if ((roll3 < roll1) && (roll3 < roll2) && (roll3 < roll4)) {
total = roll1 + roll2 + roll4;
} else if ((roll4 < roll1) && (roll4 < roll2) && (roll4 < roll3)) {
total = roll1 + roll2 + roll3;
}
}
}
static void calculateBonus(int[] bonusVal){
int bonus=0;
int[] val= new int[6];
for (int i=0;i<6;i++)
for(int j=0;j<6;j++)
if (val[i] > 10 && val[i] != 11) {
bonusVal[j] = (val[i] - 10) / 2;
} else if (val[i] < 10) {
bonusVal[j] = ((val[i] / 2) - 5);
} else if (val[i] == 10 || val[i] == 11) {
bonusVal[j] = 0;
}
}
public static void main(String[]args){
Scanner sc = new Scanner(System.in);
//Declaring variables
int level;
String choice = null;
//Getting the Level value
System.out.println("Enter the Level value :");
level = sc.nextInt();
while ((level<=0)||(level>20)){
System.out.println("Invalid input.Please enter a number between 1-20.");
System.out.println("Enter the Level value : ");
level = sc.nextInt();
}
do{
int[] val= new int[6];
int _str= val[0];
int con= val[1];
int dex= val[2];
int _int= val[3];
int wis= val[4];
int _cha= val[5];
int [] bonusVal=new int[6];
int bonus1= bonusVal[0];
int bonus2= bonusVal[1];
int bonus3= bonusVal[2];
int bonus4= bonusVal[3];
int bonus5= bonusVal[4];
int bonus6= bonusVal[5];
//Printing the Level
System.out.println("\n\n\n\n\nLevel : [ "+level+" ]");
//Displaying out put
System.out.println("_Str : ["+_str+" ]"+"["+bonus1+"]");
System.out.println("Dex : ["+dex+" ]"+"["+bonus2+"]");
System.out.println("Con : ["+con+" ]"+"["+bonus3+"]");
System.out.println("Int : ["+_int+" ]"+"["+bonus4+"]");
System.out.println("Wis : ["+wis+" ]"+"["+bonus5+"]");
System.out.println("_Cha : ["+_cha+" ]"+"["+bonus6+"]");
//Calculating the Hit points
double hp = (((Math.random()*1000 %6+1)+bonus3)*level);
//Print the Hit points
System.out.println("HP : ["+hp+"]");
//Give the chance to re-roll or continue
System.out.println("Type r if you want to re-roll or any other character if you want to continue :");
choice = sc.next();
}
while (choice.equals("r"));;
}
}
I think i had made mistakes in the second method .I want to figure out how can i use above stored values in the array to calcuate bonus and store the values for bonus in another array.This is the program i have so far.I still didnt got the output i neede.I need to get 6 values from dice roll method and store them in an array.and then i want to call the values to calculate bonus and store those bonus values in another array.
I think you want to do something like below. I haven't compiled the code, let me know if you face any issues in compiling.
static int[] calculateBonus(int[] val) {
int[] bonusVal = new int[val.length];
for(int j=0; j < val.length; j++) {
if (val[j] > 10 && val[j] != 11) {
bonus[j] = (val[j] - 10) / 2;
} else if (val[j] < 10) {
bonus[j] = ((val[j] / 2) - 5);
} else if (val[j] == 10 || val[j] == 11) {
bonus[j] = 0;
}
}
return bonusVal;
}
You need to return an array from the first method to start with, right now it doesn't work with an array at all.
Change it to the below to return an array and have a new array variable
static int[] diceRoll() {
final int rolls = 6;
int[] result = new int[rolls];
//the for loop...
at the end of the for loop you store the value in the array and then at the end return the array so the end of the method will look like
result[i] = total;
}
return result;
}
The calculateBonus will use this returned array as input and it will also work internally with an array and not an int as you have now. I also added that it will return an array.
static int[] calculateBonus(int[] val){
int count = val.length;
int[] bonus = new int[count];
for(int j=0;j<count;j++) {
if (val[j] > 10 && val[j] != 11) {
bonus[j] = (val[j] - 10) / 2;
} else if (val[j] < 10) {
bonus[j] = ((val[j] / 2) - 5);
} else if (val[j] == 10 || val[j] == 11) {
bonus[j] = 0;
}
}
return bonus;
}
A simple run
public static void main(String[] args) {
int[] values = diceRoll();
int[] bonus = calculateBonus(values);
for(int i=0; i<bonus.length; i++) {
System.out.println(bonus[i]);
}
}
Update
Below is a new version of the two methods that addresses the questions I asked in the comment and also clean up the code some.
Main difference is that I use a ArrayList in the diceRole method and that calculateBonus now uses double.
static int[] diceRoll() {
int[] result = new int[6];
for (int i=0;i<6;i++) {
List<Integer> list = new ArrayList<>();
for (int j = 0; j < 4; j++) {
list.add(new Integer((int) ((Math.random() * 1000 % 6 + 1))));
}
Collections.sort(list); //list is now in ascending order
int total =0;
for (int j = 1; j < list.size(); j++) {
total += list.get(j).intValue();
}
result[i] = total;
}
return result;
}
static double[] calculateBonus(int[] val) {
int count = val.length;
double[] bonus = new double[count];
for(int j=0;j<count;j++) {
double value = 0.0;
if (val[j] > 11) {
value = (val[j] - 10.0) / 2.0;
} else if (val[j] < 10.0) {
value = ((val[j] / 2.0) - 5.0);
}
bonus[j] = value;
}
return bonus;
}

Java - Arrays/Loops

I wanted to display the second highest and second lowest number in a given random array values ranges from(0 to 999999) and also the way the highest number will be printed in tagalog word and the shortest number will be printed in Spanish word. Here is by far is my work,can you cite or add some code for it to work? I'm having a hard time on my Main method and connecting all of them.
package demo;
import java.util.Scanner;
public class MachineProject {
public static void main(String[] args) {
int number = 5;
Scanner in = new Scanner(System.in);
int[] array=new int[5];
System.out.println("Input 6 numbers between 0 and 999,999 :");
number = in.nextInt();
for (int i=0;i<5;i++) {
array[i]=in.nextInt();
}
if(number>=0 && number<=999999){
if(number==0){
System.out.print("NUMBER AFTER CONVERSION:\tZERO");
} else {
System.out.print("NUMBER AFTER CONVERSION:\t");
convertNumberToWordsTagalog(((number / 100) % 10), " HUNDRED");
convertNumberToWordsSpanish((number % 100), " ");
}
} else{
System.out.print("NUMBER OUT OF RANGE");
}
System.out.print("\nPlease type a number between 0 and 999 OR type -1 to exit: ");
number = in.nextInt();
}
public static final String[] unitsSpanish = {
"", "uno", "dos", "tres", "cuatro", "cinco", "seis", "siete",
"ocho", "nueve", "diez", "once", "doce", "trece", "catorce",
"quince", "dieciseis", "diecisiete", "dieciocho", "diecinueve"
};
public static final String[] tensSpanish = {
"", // 0
"", // 1
"veinte", // 20
"treinta", // 30
"cuarenta", // 40
"cincuenta", // 50
"sesenta", // 60
"setenta", // 70
"ochenta", // 80
"noventa" // 90
};
public static final String[] unitsTagalog = {
"", "isa", "dalawa", "tatlo", "apat", "lima", "anim", "pito",
"walo", "siyam", "sampu", "labing isa", "labing dalawa", "labing tatlo", "labing apat",
"labing lima", "labing anim", "labing pito", "labing walo", "labing siyam"
// 0-19
};
public static final String[] tensTagalog = {
"", // 0
"", // 1
"dalawampu", // 20
"tatlumpu", // 30
"apat-na-pu", // 40
"limampu", // 50
"anim-na-pu", // 60
"pitumpu", // 70
"walumpu", // 80
"siyam-na-pu" // 90
};
public static String convertNumberToWordsTagalog(final int num) {
if (num < 20) {
return unitsTagalog[num];
}
if (num < 100) {
return tensTagalog[num / 10] + ((num % 10 != 0) ? " " : "") + unitsTagalog[num % 10];
}
if (num < 1000) {
return unitsTagalog[num / 100] + " daan" + ((num % 100 != 0) ? " " : "") + convertNumberToWordsTagalog(num % 100);
}
return convertNumberToWordsTagalog(num / 1000) + " libo" + ((num % 1000 != 0) ? " " : "") + convertNumberToWordsTagalog(num % 1000);
}
public static String convertNumberToWordsSpanish(final int num) {
if (num < 20) {
return unitsSpanish[num];
}
if (num < 100) {
return tensSpanish[num / 10] + ((num % 10 != 0) ? " " : "") + unitsSpanish[num % 10];
}
if (num < 1000) {
return unitsSpanish[num / 100] + " cien" + ((num % 100 != 0) ? " " : "") + convertNumberToWordsSpanish(num % 100);
}
return convertNumberToWordsSpanish(num / 1000) + " mil" + ((num % 1000 != 0) ? " " : "") + convertNumberToWordsSpanish(num % 1000);
}
static void SecondSmallest(int arr[]) {
Scanner in = new Scanner(System.in);
//Input size of an array
int n = in.nextInt();
//Array declaration
int arr1[] = new int[n];
//Taking an input value of an array
for (int j = 0; j < arr1.length; j++) {
arr1[j] = in.nextInt();
}
//Initialize with max value of integer
int smallest = Integer.MAX_VALUE;
int secondSmallest = Integer.MAX_VALUE;
//Traverse an array
for (int i = 0; i < arr1.length; i++) {
if (smallest > arr1[i]) {
secondSmallest = smallest;
smallest = arr1[i];
}
if (arr1[i] > smallest && arr1[i] < secondSmallest) {
secondSmallest = arr1[i];
}
}
in.close();
System.out.println("Second smallest number is " + secondSmallest);
}
public static void SecondHighest(int arr[], int second_max) {
int max = 0, temp, numbers;
Scanner in = new Scanner(System.in);
numbers = in.nextInt();
for (int i = 0; i < numbers; i++) {
if (i == 0) {
max = in.nextInt();
} else {
temp = in.nextInt();
if (temp > max) {
second_max = max;
max = temp;
}
else if(temp>second_max)
{
second_max=temp;
}
}
}
in.close();
System.out.println("Second highest number :" + second_max);
}
}
In your code you store the numbers into an array, but you never use it.
The same for
System.out.print("\nPlease type a number between 0 and 999 OR type -1 to exit: ");
number = in.nextInt();
If you want to just find the min and max, you don't need to store every value.
You can look for min and max while the user inputs the numbers.
public static void main(String[] args) {
final int MAX_VALUE = 999999;
int min = Integer.MAX_VALUE;
int second_min = Integer.MAX_VALUE;
int second_max = Integer.MIN_VALUE;
int max = Integer.MIN_VALUE;
final Scanner in = new Scanner(System.in);
System.out.println("How many numbers do you want to insert? (0 or a negative number to exit)");
int n = in.nextInt();
if (n <= 0) {
System.out.println("Goodbye");
System.exit(0);
}
System.out.println("Input "+n+" integers between 0 and " + MAX_VALUE + " :");
int val; // this integer will be used to check the input
for (int i = 0; i < n; i++) {
do {
val = in.nextInt();
if ((val < 0) || (val > MAX_VALUE)) {
System.out.println("Error: NUMBER OUT OF RANGE");
System.out.println("Please insert a valid number");
}
} while ((val < 0) || (val > MAX_VALUE));
// Now we're sure that val contains a valid number
if (val < min) {
second_min = min;
min = val;
} else if (val < second_min) {
second_min = val;
}
if (val > max) {
second_max = max;
max = val;
} else if (val > second_max) {
second_max = val;
}
}
in.close();
System.out.print("Min (in Spanish):\t");
if (min == 0) {
System.out.println("Zero");
} else {
System.out.println(convertNumberToWordsSpanish(min));
}
System.out.println("Second smallest number: " + second_min);
System.out.println("Second highest number: " + second_max);
System.out.print("Max (in Tagalog):\t");
if (max == 0) { // Keep in mind that the user could input N zeros
System.out.println("Zero");
} else {
System.out.println(convertNumberToWordsTagalog(max));
}
}
If you need to store the numbers into an array, you could remove the code for searching min and max, and use Arrays.sort() so
final int min = array[0];
final int second_min = array[1];
final int second_max = array[n-2];
final int max = array[n-1];

Can't figure out the error Luhn check

Its supose to tell me if a card is valid or invalid using luhn check
4388576018402626 invalid
4388576018410707 valid
but it keeps telling me that everything is invalid :/
Any tips on what to do, or where to look, would be amazing. I have been stuck for a few hours.
It would also help if people tell me any tips on how to find why a code is not working as intended.
im using eclipse and java
public class Task11 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter a credit card number as a long integer: ");
long number = input.nextLong();
if (isValid(number)) {
System.out.println(number + " is valid");
} else {
System.out.println(number + " is invalid");
}
}
public static boolean isValid(long number) {
return (getSize(number) >= 13) && (getSize(number) <= 16)
&& (prefixMatched(number, 4) || prefixMatched(number, 5) || prefixMatched(number, 6) || prefixMatched(number, 37))
&& (sumOfDoubleEvenPlace(number) + sumOfOddPlace(number)) % 10 == 0;
}
public static int sumOfDoubleEvenPlace(long number) {
int result = 0;
long start = 0;
String digits = Long.toString(number);
if ((digits.length() % 2) == 0) {
start = digits.length() - 1;
} else {
start = digits.length() - 2;
}
while (start != 0) {
result += (int) ((((start % 10) * 2) % 10) + (((start % 10) * 2) / 2));
start = start / 100;
}
return result;
}
public static int getDigit(int number) {
return number % 10 + (number / 10);
}
public static int sumOfOddPlace(long number) {
int result = 0;
while (number != 0) {
result += (int) (number % 10);
number = number / 100;
}
return result;
}
public static boolean prefixMatched(long number, int d) {
return getPrefix(number, getSize(d)) == d;
}
public static int getSize(long d) {
int numberOfDigits = 0;
String sizeString = Long.toString(d);
numberOfDigits = sizeString.length();
return numberOfDigits;
}
public static long getPrefix(long number, int k) {
String size = Long.toString(number);
if (size.length() <= k) {
return number;
} else {
return Long.parseLong(size.substring(0, k));
}
}
}
You should modiffy your isValid() method to write down when it doesn't work, like this:
public static boolean isValid(long number) {
System.err.println();
if(getSize(number) < 13){
System.out.println("Err: Number "+number+" is too short");
return false;
} else if (getSize(number) > 16){
public static boolean isValid(long number) {
System.err.println();
if(getSize(number) < 13){
System.out.println("Err: Number "+number+" is too short");
return false;
} else if (getSize(number) > 16){
System.out.println("Err: Number "+number+" is too long");
return false;
} else if (! (prefixMatched(number, 4) || prefixMatched(number, 5) || prefixMatched(number, 6) || prefixMatched(number, 37)) ){
System.out.println("Err: Number "+number+" prefix doesn't match");
return false;
} else if( (sumOfDoubleEvenPlace(number) + sumOfOddPlace(number)) % 10 != 0){
System.out.println("Err: Number "+number+" doesn't have sum of odd and evens % 10. ");
return false;
}
return true;
}
My guess for your problem is on the getPrefix() method, you should add some logs here too.
EDIT: so, got more time to help you (don't know if it's still necessary but anyway). Also, I corrected the method I wrote, there were some errors (like, the opposite of getSize(number) >= 13 is getSize(number) < 13)...
First it will be faster to test with a set of data instead of entering the values each time yourself (add the values you want to check):
public static void main(String[] args) {
long[] luhnCheckSet = {
0, // too short
1111111111111111111L, // too long (19)
222222222222222l // prefix doesn't match
4388576018402626l, // should work ?
};
//System.out.print("Enter a credit card number as a long integer: ");
//long number = input.nextLong();
for(long number : luhnCheckSet){
System.out.println("Checking number: "+number);
if (isValid(number)) {
System.out.println(number + " is valid");
} else {
System.out.println(number + " is invalid");
}
System.out.println("-");
}
}
I don't know the details of this, but I think you should work with String all along, and parse to long only if needed (if number is more than 19 characters, it might not parse it long).
Still, going with longs.
I detailed your getPrefix() with more logs AND put the d in parameter in long (it's good habit to be carefull what primitive types you compare):
public static boolean prefixMatched(long number, long d) {
int prefixSize = getSize(d);
long numberPrefix = getPrefix(number, prefixSize);
System.out.println("Testing prefix of size "+prefixSize+" from number: "+number+". Prefix is: "+numberPrefix+", should be:"+d+", are they equals ? "+(numberPrefix == d));
return numberPrefix == d;
}
Still don't know what's wrong with this code, but it looks like it comes from the last test:
I didn't do it but you should make one method from sumOfDoubleEvenPlace(number) + sumOfOddPlace(number)) % 10 and log both numbers and the sum (like i did in prefixMatched() ). Add logs in both method to be sure it gets the result you want/ works like it should.
Have you used a debugger ? if you can, do it, it can be faster than adding a lot of logs !
Good luck
EDIT:
Here are the working functions and below I provided a shorter, more efficient solution too:
public class CreditCardValidation {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int count = 0;
long array[] = new long [16];
do
{
count = 0;
array = new long [16];
System.out.print("Enter your Credit Card Number : ");
long number = in.nextLong();
for (int i = 0; number != 0; i++) {
array[i] = number % 10;
number = number / 10;
count++;
}
}
while(count < 13);
if ((array[count - 1] == 4) || (array[count - 1] == 5) || (array[count- 1] == 3 && array[count - 2] == 7)){
if (isValid(array) == true) {
System.out.println("\n The Credit Card Number is Valid. ");
} else {
System.out.println("\n The Credit Card Number is Invalid. ");
}
} else{
System.out.println("\n The Credit Card Number is Invalid. ");
}
in.close();
}
public static boolean isValid(long[] array) {
int total = sumOfDoubleEvenPlace(array) + sumOfOddPlace(array);
if ((total % 10 == 0)) {
for (int i=0; i< array.length; i++){
System.out.println(array[i]);}
return true;
} else {
for (int i=0; i< array.length; i++){
System.out.println(array[i]);}
return false;
}
}
public static int getDigit(int number) {
if (number <= 9) {
return number;
} else {
int firstDigit = number % 10;
int secondDigit = (int) (number / 10);
return firstDigit + secondDigit;
}
}
public static int sumOfOddPlace(long[] array) {
int result = 0;
for (int i=0; i< array.length; i++)
{
while (array[i] > 0) {
result += (int) (array[i] % 10);
array[i] = array[i] / 100;
}
}
System.out.println("\n The sum of odd place is " + result);
return result;
}
public static int sumOfDoubleEvenPlace(long[] array) {
int result = 0;
long temp = 0;
for (int i=0; i< array.length; i++){
while (array[i] > 0) {
temp = array[i] % 100;
result += getDigit((int) (temp / 10) * 2);
array[i] = array[i] / 100;
}
}
System.out.println("\n The sum of double even place is " + result);
return result;
}
}
I also found a solution with less lines of logic. I know you're probably searching for an OO approach with functions, building from this could be of some help.
Similar question regarding error in Luhn algorithm logic:
Check Credit Card Validity using Luhn Algorithm
Link to shorter solution:
https://code.google.com/p/gnuc-credit-card-checker/source/browse/trunk/CCCheckerPro/src/com/gnuc/java/ccc/Luhn.java
And here I tested the solution with real CC numbers:
public class CreditCardValidation{
public static boolean Check(String ccNumber)
{
int sum = 0;
boolean alternate = false;
for (int i = ccNumber.length() - 1; i >= 0; i--)
{
int n = Integer.parseInt(ccNumber.substring(i, i + 1));
if (alternate)
{
n *= 2;
if (n > 9)
{
n = (n % 10) + 1;
}
}
sum += n;
alternate = !alternate;
}
return (sum % 10 == 0);
}
public static void main(String[] args){
//String num = "REPLACE WITH VALID NUMBER"; //Valid
String num = REPLACE WITH INVALID NUMBER; //Invalid
num = num.trim();
if(Check(num)){
System.out.println("Valid");
}
else
System.out.println("Invalid");
//Check();
}
}

(Java) Statistical analysis assignment

I'm currently working on a program designed to perform some statistical analysis. Specifically, I want it to store some random integers (say 10, between min and max inclusive) in an array, compute the min, max, mode, and a few other values through separate methods, and give the user a menu with which to either choose a method (and loop back to the menu, if they do so) or exit.
My biggest problems right now are that the main program requires two inputs to carry out any method (doesn't do anything after putting in the first), and also that each method returns 0 or 0.0.
Here is my code:
import java.util.Random;
public class Stats extends Main
{
int sampleSize;
double count;
double ave;
double sum;
int min;
int max;
int mode;
int evenCount;
int oddCount;
int countMatching;
//Constructor: use an RNG to generate sampleSize integers between minValue and maxValue. Store the numbers in an array named 'data'.
public Stats()
{
sampleSize = 10;
data = new int[sampleSize];
for (int i = 0; i < sampleSize; i++)
{
Random rand = new Random();
data[i] = rand.nextInt((max - min + 1) + min);
}
return;
}
//Method: return the sample set's max value
public int getMax()
{
max = data[0];
for(int i = 0; i < sampleSize; i++)
{
if (data[i] > max)
max = data[i];
}
return max;
}
//Method: return the min value
public int getMin()
{
min = data[0];
for(int i = 0; i < sampleSize; i++)
{
if (data[i] < min)
min = data[i];
}
return min;
}
//Method: return the average value
public double getAve()
{
count = sampleSize;
sum = 0;
for(int i = 0; i < sampleSize; i++)
{
sum = sum + data[i];
}
ave = sum / count;
return ave;
}
//Method: return the mode; in case of a tie, choose the smallest value
public int getMode()
{
int popularity1 = 0;
int popularity2 = 0;
int array_item;
for(int i = 0; i < sampleSize; i++)
{
array_item = data[i];
for(int j = 0; j < sampleSize; j++)
{
if(array_item == data[j])
popularity1++;
}
if(popularity1 >= popularity2)
{
mode = array_item;
popularity2 = popularity1;
}
}
return mode;
}
//Method: return the count of even numbers
public int getEven()
{
int evenCount = 0;
for (int i = 0; i < sampleSize; i++)
{
if (data[i] % 2 == 0)
evenCount++;
}
return evenCount;
}
//Method: return the count of odd numbers
public int getOdd()
{
int oddCount = 0;
for (int i = 0; i < sampleSize; i++)
{
if (data[i] % 2 != 0)
oddCount++;
}
return oddCount;
}
//Display all numbers, formatted in columns (hint: pg. 158)
public void displaySampleSet()
{
for (int i = 0; i < sampleSize; i++)
{
}
}
//Return the count of numbers in the sample set that match the input parameter
public int countMatching(int match)
{
int countMatching = 0;
return match;
}
//Create a list of private variable(s) that belong to the Stats class
private int[] data;
}
And here is the main program:
import java.util.*;
public class Main
{
public static void main(String[] args)
{
int input;
int stats;
Scanner keyboard = new Scanner(System.in);
Stats g = new Stats();
System.out.println("Welcome to the Stats Program!");
System.out.println();
System.out.println("Main Menu");
System.out.println();
System.out.println("1) Get max value");
System.out.println("2) Get min value");
System.out.println("3) Get the mean");
System.out.println("4) Get the mode");
System.out.println("5) Get the count of even numbers");
System.out.println("6) Get the count of odd numbers");
System.out.println("7) Display the sample set");
System.out.println("8) Return the count of numbers in the sample set that match the input parameter");
System.out.println("9) Exit");
System.out.println();
stats = keyboard.nextInt();
while (stats != 9)
{
if (stats == 1)
{
g.getMax();
input=keyboard.nextInt();
System.out.println("Max is: " + g.getMax());
}
else if (stats == 2)
{
g.getMin();
input=keyboard.nextInt();
System.out.println("Min is: " + g.getMin());
}
else if (stats == 3)
{
g.getAve();
input=keyboard.nextInt();
System.out.println("Mean is: " + g.getAve());
}
else if (stats == 4)
{
g.getMode();
input=keyboard.nextInt();
System.out.println("Mode is: " +g.getMode());
}
else if (stats == 5)
{
g.getEven();
}
else if (stats == 6)
{
g.getOdd();
}
else if (stats == 7)
{
g.displaySampleSet();
}
else if (stats == 8)
System.out.println("");
System.out.println("View other stats?");
System.out.println("");
System.out.println("1) Max 2) Min 3) Mean 4) Mode 5) Count of evens 6) Count of odds 7) Sample set numbers 8) Count of numbers that match input parameter 9) Exit");
stats = keyboard.nextInt();
}
System.out.println("Thank you for using the Stats Program. See you next time!");
}
}
Both programs are incomplete, but I'm still getting values for each method (after two inputs), loops after they execute, and the exit works as intended.
Any tips or parts that are glaringly wrong/missing? I'd really like to understand this.
Thanks in advance!
When you create a Stats, the data array is immediately initialised in the constructor using the max and min fields. But these are zero at this point (because you leave them blank, and Java initialises blank int declarations to zero). You then call your random number generator:
data[i] = rand.nextInt((max - min + 1) + min);
min and max are zero, so this evaluates to:
data[i] = rand.nextInt(1);
and Random.nextInt() returns values up to, but not including, the input (see the docs).
So your 'random' data will always be zeros; therefore the minimum, maximum and average will also be zero.

Categories