ADAGAME4 Spoj Wrong Answer - java

Below is a Archive PROBLEM from SPOJ. Sample testCase is passing, but I am getting W/A on submission. I am missing some testCase(testCases). Need help to figure out what case I am missing and/or what I am doing wrong here.
Ada the Ladybug is playing Game of Divisors against her friend Velvet Mite Vinit. The game has following rules. There is a pile of N stones between them. The player who's on move can pick at least 1 an at most σ(N) stones (where σ(N) stands for number of divisors of N). Obviously, N changes after each move. The one who won't get any stones (N == 0) loses.
As Ada the Ladybug is a lady, so she moves first. Can you decide who will be the winner? Assume that both players play optimally.
Input
The first line of input will contain 1 ≤ T ≤ 10^5, the number of test-cases.
The next T lines will contain 1 ≤ N ≤ 2*10^7, the number of stones which are initially in pile.
Output
Output the name of winner, so either "Ada" or "Vinit".
Sample Input:
8
1
3
5
6
11
1000001
1000000
29
Sample Output:
Ada
Vinit
Ada
Ada
Vinit
Vinit
Ada
Ada
CODE
import java.io.*;
public class Main
{
public static int max_size = 2 * (int)Math.pow(10,7) + 1;
//public static int max_size = 25;
//public static int max_size = 2 * (int)Math.pow(10,6) + 1;
public static boolean[] dp = new boolean[max_size];
public static int[] lastPrimeDivisor = new int[max_size];
public static int[] numOfDivisors = new int[max_size];
public static void main(String[] args) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
preprocess();
int t = Integer.parseInt(br.readLine());
while(t > 0)
{
int n = Integer.parseInt(br.readLine());
if(dp[n] == true)
System.out.println("Ada");
else
System.out.println("Vinit");
t--;
}
}
public static void markLastPrimeDivisor()
{
for(int i = 0 ; i < max_size ; i++)
{
lastPrimeDivisor[i] = 1;
}
for(int i = 2 ; i < max_size ; i += 2)
{
lastPrimeDivisor[i] = 2;
}
int o = (int)Math.sqrt(max_size);
for(int i = 3 ; i < max_size; i++)
{
if(lastPrimeDivisor[i] != 1)
{
continue;
}
lastPrimeDivisor[i] = i;
if(i <= o)
{
for(int j = i * i ; j < max_size ; j += 2 * i)
{
lastPrimeDivisor[j] = i;
}
}
}
/*for(int i = 1 ; i < max_size ; i++)
System.out.println("last prime of " + i + " is " + lastPrimeDivisor[i]);*/
}
public static void countDivisors(int num)
{
int original = num;
int result = 1;
int currDivisorCount = 1;
int currDivisor = lastPrimeDivisor[num];
int nextDivisor;
while(currDivisor != 1)
{
num = num / currDivisor;
nextDivisor = lastPrimeDivisor[num];
if(nextDivisor == currDivisor)
{
currDivisorCount++;
}
else
{
result = result * (currDivisorCount + 1);
currDivisorCount = 1;
currDivisor = nextDivisor;
}
}
if(num != 1)
{
result = result * (currDivisorCount + 1);
}
//System.out.println("result for num : " + original + ", " + result);
numOfDivisors[original] = result;
}
public static void countAllDivisors()
{
markLastPrimeDivisor();
for(int i = 2 ; i < max_size ; i++)
{
countDivisors(i);
//System.out.println("num of divisors of " + i + " = " + numOfDivisors[i]);
}
}
public static void preprocess()
{
countAllDivisors();
dp[0] = dp[1] = dp[2] = true;
for(int i = 3 ; i < max_size ; i++)
{
int flag = 0;
int limit = numOfDivisors[i];
//If for any i - j, we get false,for playing optimally
//the current opponent will choose to take j stones out of the
//pile as for i - j stones, the other player is not winning.
for(int j = 1 ; j <= limit; j++)
{
if(dp[i - j] == false)
{
dp[i] = true;
flag = 1;
break;
}
}
if(flag == 0)
dp[i] = false;
}
}
}

There is a subtle bug in your countDivisors() function. It assumes
that lastPrimeDivisor[num] – as the name indicates – returns the
largest prime factor of the given argument.
However, that is not the case. For example, lastPrimeDivisor[num] = 2
for all even numbers, or lastPrimeDivisor[7 * 89] = 7.
The reason is that in
public static void markLastPrimeDivisor()
{
// ...
for(int i = 3 ; i < max_size; i++)
{
// ...
if(i <= o)
{
for(int j = i * i ; j < max_size ; j += 2 * i)
{
lastPrimeDivisor[j] = i;
}
}
}
}
only array elements starting at i * i are updated.
So lastPrimeDivisor[num] is in fact some prime divisor of num, but not
necessarily the largest. As a consequence, numOfDivisors[55447] is computed
as 8 instead of the correct value 6.
Therefore in countDivisors(), the exponent of a prime factor in num
must be determined explicitly by repeated division.
Then you can use that the divisors function is multiplicative. This leads to
the following implementation:
public static void countAllDivisors() {
// Fill the `somePrimeDivisor` array:
computePrimeDivisors();
numOfDivisors[1] = 1;
for (int num = 2 ; num < max_size ; num++) {
int divisor = somePrimeDivisor[num];
if (divisor == num) {
// `num` is a prime
numOfDivisors[num] = 2;
} else {
int n = num / divisor;
int count = 1;
while (n % divisor == 0) {
count++;
n /= divisor;
}
// `divisor^count` contributes to `count + 1` in the number of divisors,
// now use multiplicative property:
numOfDivisors[num] = (count + 1) * numOfDivisors[n];
}
}
}

Related

How output 10 integers per line in Java?

The problem is to display the first 50 prime numbers in 5 lines, each of which contains 10 numbers. I've created a program to output the first 50 prime numbers but I don't know how to split them so they output 10 numbers per line. I am a beginner level programmer and I really need help on this.
public class Lab4 {
public static void main(String[] args) {
int i = 0;
int num = 0;
String primeNumbers = " ";
for (i = 1; i <= 230; i++)
{
int counter = 0;
for (num = i; num >= 1; num--)
{
if (i % num == 0)
{
counter = counter + 1;
}
}
if (counter == 2)
{
primeNumbers = primeNumbers + i + " ";
}
}
System.out.println(primeNumbers);
}
}
You need to count how many items you already added and once you have 10 you need to put new line. Also I changed String to StringBuilder because concatenating in a loop is not very good, you can read about it here StringBuilder vs String concatenation
int i = 0;
int num = 0;
int lineCounter = 0;
StringBuilder primeNumbers = new StringBuilder();
for (i = 1; i <= 230; i++) {
int counter = 0;
for (num = i; num >= 1; num--) {
if (i % num == 0) {
counter = counter + 1;
}
}
if (counter == 2) {
primeNumbers.append(i).append(" ");
lineCounter++;
}
if (lineCounter == 10) {
primeNumbers.append(System.lineSeparator());
lineCounter = 0;
}
}
System.out.println(primeNumbers);
Just add this piece of code below after this line in your code: primeNumbers = primeNumbers + i + " ";
if (newLineCount == 10) {
primeNumbers += '\n';
newLineCount = 0;
}
newLineCount++;
Also init newLineCount before the loop: int newLineCount = 0;
Additionally, as mentioned in the comments, consider using StringBuilder instead of String, or even better ArrayList to store your numbers, then you can have method to print values from your ArrayList in whatever formatted way you want (with tabs, alignment, new lines...)
Here is the code that suits your needs. I haven't changed anything in your code, just added mine to suit your needs.
public class print_prime_numbers_10_per_line {
public static void main(String[] args) {
int i = 0;
int num = 0;
String primeNumbers = "";
for (i = 1; i <= 230; i++) {
int counter = 0;
for (num = i; num >= 1; num--) {
if (i % num == 0) {
counter = counter + 1;
}
}
if (counter == 2) {
primeNumbers = primeNumbers + i + " ";
}
}
String[] integerStrings = primeNumbers.split(" ");
int[] integers = new int[integerStrings.length];
for (int x = 0; x < integers.length; x++) {
integers[x] = Integer.valueOf(integerStrings[x]);
}
for (int g = 0; g < integers.length; g++) {
if (g % 11 == 0) {
System.out.println();
} else {
System.out.print(integers[g] + " ");
}
}
}
}

ADAPRIME spoj tle

PROBLEM. This is a problem from SPOJ problems section.
As you might already know, Ada the Ladybug is a farmer. She grows many vegetables and trees and she wants to distinguish between them. For this purpose she bought a funny signs, which contains a few digits. The digits on the sign could be arbitrarily permuted (yet not added/removed). Ada likes prime numbers so she want the signs to be prime (and obviously distinct). Can you find the number of signs with prime number which could be obtained?
NOTE: Number can't have leading zero!
Input
The first line of input will contain 1 ≤ T ≤ 10000, the number of test-cases.
The next T lines will contain 1 ≤ D ≤ 9, the number of digits on sign, followed by D digits 0 ≤ di ≤ 9
Output
For each test-case, output the number of distinct primes which could be generated on given sign.
Example Input
5
1 9
3 1 2 3
5 1 2 0 8 9
7 1 0 6 5 7 8 2
5 1 2 7 3 1
Example Output
0
0
11
283
15
APPROACH
For each input, I am first finding all the primes upto 9999999999. For each test case, I first sort the array whose max size can be 9. After sorting, I iteratively find the next permutation, and check if its prime or not(which i have done already, so it takes a constant time now). But I am getting TLE. I have no idea where can i optimize my code.
CODE
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
public class Main
{
public static int maxSize = (int)Math.pow(10,9);
public static boolean[] isPrime = new boolean[maxSize];
public static int count = 0;
public static void main(String[] args) throws IOException
{
//find all the primes till maxSize - 1
preProcess();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(br.readLine());
while(t > 0)
{
String[] strArr = br.readLine().split(" ");
int n = Integer.parseInt(strArr[0]);
int[] arr = new int[n];
for(int i = 0 ; i < n ; i++)
{
arr[i] = Integer.parseInt(strArr[i + 1]);
}
count = 0;
HashSet<Integer> set = new HashSet<>();
func(arr,0,n,set);
System.out.println(count);
t--;
}
}
public static void func(int[] arr,int pos,int n,HashSet<Integer> set)
{
Arrays.sort(arr);
while(true)
{
//ignoring the leading zeroes cases.
if(arr[0] != 0)
{
//parses the int array and produces the number.
int val = parseInt(arr, n);
//System.out.println("val = " + val);
if(isPrime[val] == true && set.contains(val) == false)
{
//System.out.println(val);
count++;
set.add(val);
}
}
int i = n - 2;
while(i >= 0 && arr[i] >= arr[i + 1])
{
i--;
}
if(i < 0)
return;
//finds the next greater number than arr[i]
int index = findJustGreater(arr, i + 1, n - 1, arr[i]);
swap(i,index,arr);
reverse(arr, i + 1, n - 1);
}
}
public static int findJustGreater(int[] arr,int l, int r,int key)
{
int low = l;
int high = r;
while(low < high)
{
if(high == low + 1)
{
if(arr[high] > key)
return high;
else
return low;
}
int mid = (low + high) / 2;
if(arr[mid] > key)
{
low = mid;
}
else
{
high = mid - 1;
}
}
return low;
}
public static void reverse(int[] arr,int i,int j)
{
while(i < j)
{
swap(i, j, arr);
i++;
j--;
}
}
public static void swap(int i,int j,int[] arr)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static int parseInt(int[] arr,int n)
{
int sum = 0;
for(int i = 0 ; i < n ; i++)
{
sum = sum * 10 + arr[i];
}
return sum;
}
public static void preProcess()
{
for(int i = 0 ; i < maxSize ; i++)
{
isPrime[i] = true;
}
for(int i = 4 ; i < maxSize ; i += 2)
isPrime[i] = false;
int o = (int)Math.sqrt(maxSize) + 1;
for(int i = 2 ; i <= o ; i++)
{
if(isPrime[i] == true)
{
for(int j = i * i ; j < maxSize ; j += 2 * i )
{
isPrime[j] = false;
}
}
}
}
}
THANKS FOR HELPING

Why doesn't my program run correctly?

for my school project I have to create a program that outputs perfect numbers based on how many perfect numbers the user(teacher) want. The user can pick any number from 1-4 and it should display however many number the user chooses. Here is my current code. Please ignore the sumupTo, factorial, isprime, and the testGoldbach methods, please only look at the Perfect numbers method/code.
import java.util.Scanner;
public class MyMathB
{
public static int sumUpTo(int n)
{
int sum = 0;
for (int k = 1; k <= n; k++)
sum += k;
return sum;
}
public static long factorial(int n)
{
long f = 1;
for (int k = 2; k <= n; k++)
f *= k;
return f;
}
public static boolean isPrime(int n)
{
if (n <= 1)
return false;
int m = 2;
while (m * m <= n)
{
if (n % m == 0)
return false;
m++;
}
return true;
}
public static void PerfectNumbers(int number)
{
System.out.println("How many perfect numbers would you like to see? Please enter an integer from 1 to 4");
Scanner s = new Scanner(System.in);
int numbersToSee = s.nextInt();
int counts = 0;
for(counts = 0; counts <= numbersToSee; counts++)
{
for (int n = 5; n <= 10000; n++)
{
int temp = 0;
for(int i = 1; i <= number / 2; i++)
{
if (number % i == 0)
{
temp += i;
}
if (temp == number)
{
System.out.println(number);
}
}
}
}
}
public static boolean testGoldbach(int bigNum)
{
for (int n = 6; n <= bigNum; n += 2)
{
boolean found2primes = false;
for (int p = 3; p <= n/2; p += 2)
{
if (isPrime(p) && isPrime(n - p))
found2primes = true;
}
if (!found2primes)
{
System.out.println(n + " is not a sum of two primes!");
return false;
}
}
return true;
}
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
int n;
do
{
System.out.print("Enter an integer from 4 to 20: ");
n = kb.nextInt();
} while (n < 4 || n > 20);
kb.close();
System.out.println();
System.out.println("1 + ... + " + n + " = " + sumUpTo(n));
System.out.println(n + "! = " + factorial(n));
System.out.println("Primes: ");
for (int k = 1; k <= n; k++)
if (isPrime(k))
System.out.print(k + " ");
System.out.println();
System.out.println("Goldbach conjecture up to " + n + ": " + testGoldbach(n));
}
}
you didn't declare the variable "number" in your method.
Edit: you didn't SET the variable number to anything, I misworded my last statement.

Argument values error [duplicate]

This question already has answers here:
How can I avoid ArrayIndexOutOfBoundsException or IndexOutOfBoundsException? [duplicate]
(2 answers)
Closed 7 years ago.
For one of my classes, we had to find a way to make a certain amount of change given an arbitrary amount of coins, with the least amount of coins. Here is my code below:
public class Changemaker {
public static void main ( String[] args ) {
int amount = Integer.parseInt(args[args.length-1]);
int coins = args.length - 1;
if (amount < 0){
throw new IllegalArgumentException("IMPROPER AMOUNT");
} else {
for (int i = 1; i <= coins; i++) {
int coin = Integer.parseInt(args[i]);
if (coin <= 0){
throw new IllegalArgumentException("IMPROPER DENOMINATION");
} else {
for (int j = 1; j <= coins; j++) {
int validCoin = Integer.parseInt(args[j]);
if (validCoin == coin && j != i ) {
throw new IllegalArgumentException("DUPLICATE DENOMINATION");
}
}
}
try {
String firstCoin = args[1];
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("INSUFFICIENT DATA");
throw new ArrayIndexOutOfBoundsException(" ");
}
}
}
Tuple [][] table = new Tuple [coins][amount + 1];
for(int x = 0; x < coins; x++) {
for (int i = 0; i <= amount; i++) {
Tuple tuple = new Tuple (coins);
table[x][i] = tuple;
}
}
for (int i = 1; i <= amount; i++) {
Tuple tuple = table[0][i];
int coin = Integer.parseInt(args[1]);
int total = i;
int remainder = total % coin;
int coinAmt= (int)Math.floor(total / coin);
if (remainder == 0) {
tuple.setElement(0, coinAmt);
}
}
for(int x = 1; x < coins; x++) {
int coin = Integer.parseInt(args[x + 1]);
for (int i = 1; i <= amount; i++) {
Tuple tuple = table[x][i];
int total = i;
int remainder = total % coin;
int coinAmt= (int)Math.floor(total / coin);
if (remainder == 0) {
tuple.setElement(x, coinAmt);
int optimalRow = optimalCheck(table, tuple, x, i);
Tuple optimalTuple = table[optimalRow][i];
tuple.copy(optimalTuple);
} else if (remainder != 0 && amount < coin) {
tuple.copy(table[x - 1][i]);
} else if (remainder != 0 && amount > coin) {
tuple.setElement(x, coinAmt);
Tuple remainderTuple = table[x][remainder];
tuple.add(remainderTuple);
int optimalRow = optimalCheck(table, tuple, x, i);
Tuple optimalTuple = table[optimalRow][i];
tuple.copy(optimalTuple);
}
}
}
Tuple finalAnswer = table[coins - 1][amount];
String result = "";
result = result + finalAnswer.total() + " COIN(S) IN TOTAL: ";
for (int i = 0; i < coins; i++) {
result = result + finalAnswer.getElement(i) + " x " + args[i + 1] + " cent , ";
}
if (finalAnswer.total() == 0) {
System.out.println("AMOUNT CANNOT BE MADE");
} else {
System.out.println(result);
}
}
public static int optimalCheck(Tuple[][] table, Tuple tuple, int row, int column) {
int total = tuple.total();
int optimalRow = 0;
for (int i = 0; i <= row; i++ ){
int checkedTotal = table[i][column].total();
if (checkedTotal < total && checkedTotal > 0) {
optimalRow = optimalRow + i;
break;
} else if (checkedTotal == total && i == row) {
optimalRow = optimalRow + row;
break;
}
}
return optimalRow;
} }
For the most part, my code is correct. The only thing wrong with it is that it counts the amount of change to make as a denomination, and it cuts out my first denomination amount.
So, for example, if I put 1 5 10 25 133 in the command line (1,5,10, and 25 cent coins to make 133 cents), it returns:
1 COIN(S) IN TOTAL: 0 x 5 cent , 0 x 10 cent , 0 x 25 cent , 1 x 133 cent ,
I looked at the code, and I don't see where I went wrong. Can anyone tell me where I made the error? Thanks a ton.
In your for loop, you want
for (int i = 1; i < coins; i++) {
not
for (int i = 1; i <= coins; i++) {
<= will include coins, which is length - 1 - the last argument.

Validate credit card number using luhn algorithm [duplicate]

I tried to check the validation of credit card using Luhn algorithm, which works as the following steps:
Double every second digit from right to left. If doubling of a digit results in a two-digit number, add up the two digits to get a single-digit number.
2 * 2 = 4
2 * 2 = 4
4 * 2 = 8
1 * 2 = 2
6 * 2 = 12 (1 + 2 = 3)
5 * 2 = 10 (1 + 0 = 1)
8 * 2 = 16 (1 + 6 = 7)
4 * 2 = 8
Now add all single-digit numbers from Step 1.
4 + 4 + 8 + 2 + 3 + 1 + 7 + 8 = 37
Add all digits in the odd places from right to left in the card number.
6 + 6 + 0 + 8 + 0 + 7 + 8 + 3 = 38
Sum the results from Step 2 and Step 3.
37 + 38 = 75
If the result from Step 4 is divisible by 10, the card number is valid; otherwise, it is invalid. For example, the number 4388576018402626 is invalid, but the number 4388576018410707 is valid.
Simply, my program always displays valid for everything that I input. Even if it's a valid number and the result of sumOfOddPlace and sumOfDoubleEvenPlace methods are equal to zero. Any help is appreciated.
import java.util.Scanner;
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. ");
}
}
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;
}
}
You can freely import the following code:
public class Luhn
{
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);
}
}
Link reference: https://github.com/jduke32/gnuc-credit-card-checker/blob/master/CCCheckerPro/src/com/gnuc/java/ccc/Luhn.java
Google and Wikipedia are your friends. Instead of long-array I would use int-array. On Wikipedia following java code is published (together with detailed explanation of Luhn algorithm):
public static boolean check(int[] digits) {
int sum = 0;
int length = digits.length;
for (int i = 0; i < length; i++) {
// get digits in reverse order
int digit = digits[length - i - 1];
// every 2nd number multiply with 2
if (i % 2 == 1) {
digit *= 2;
}
sum += digit > 9 ? digit - 9 : digit;
}
return sum % 10 == 0;
}
You should work on your input processing code. I suggest you to study following solution:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
boolean repeat;
List<Integer> digits = new ArrayList<Integer>();
do {
repeat = false;
System.out.print("Enter your Credit Card Number : ");
String input = in.next();
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (c < '0' || c > '9') {
repeat = true;
digits.clear();
break;
} else {
digits.add(Integer.valueOf(c - '0'));
}
}
} while (repeat);
int[] array = new int[digits.size()];
for (int i = 0; i < array.length; i++) {
array[i] = Integer.valueOf(digits.get(i));
}
boolean valid = check(array);
System.out.println("Valid: " + valid);
}
I took a stab at this with Java 8:
public static boolean luhn(String cc) {
final boolean[] dbl = {false};
return cc
.chars()
.map(c -> Character.digit((char) c, 10))
.map(i -> ((dbl[0] = !dbl[0])) ? (((i*2)>9) ? (i*2)-9 : i*2) : i)
.sum() % 10 == 0;
}
Add the line
.replaceAll("\\s+", "")
Before
.chars()
If you want to handle whitespace.
Seems to produce identical results to
return LuhnCheckDigit.LUHN_CHECK_DIGIT.isValid(cc);
From Apache's commons-validator.
There are two ways to split up your int into List<Integer>
Use %10 as you are using and store it into a List
Convert to a String and then take the numeric values
Here are a couple of quick examples
public static void main(String[] args) throws Exception {
final int num = 12345;
final List<Integer> nums1 = splitInt(num);
final List<Integer> nums2 = splitString(num);
System.out.println(nums1);
System.out.println(nums2);
}
private static List<Integer> splitInt(int num) {
final List<Integer> ints = new ArrayList<>();
while (num > 0) {
ints.add(0, num % 10);
num /= 10;
}
return ints;
}
private static List<Integer> splitString(int num) {
final List<Integer> ints = new ArrayList<>();
for (final char c : Integer.toString(num).toCharArray()) {
ints.add(Character.getNumericValue(c));
}
return ints;
}
I'll use 5 digit card numbers for simplicity. Let's say your card number is 12345; if I read the code correctly, you store in array the individual digits:
array[] = {1, 2, 3, 4, 5}
Since you already have the digits, in sumOfOddPlace you should do something like
public static int sumOfOddPlace(long[] array) {
int result = 0;
for (int i = 1; i < array.length; i += 2) {
result += array[i];
}
return result;
}
And in sumOfDoubleEvenPlace:
public static int sumOfDoubleEvenPlace(long[] array) {
int result = 0;
for (int i = 0; i < array.length; i += 2) {
result += getDigit(2 * array[i]);
}
return result;
}
this is the luhn algorithm implementation which I use for only 16 digit Credit Card Number
if(ccnum.length()==16){
char[] c = ccnum.toCharArray();
int[] cint = new int[16];
for(int i=0;i<16;i++){
if(i%2==1){
cint[i] = Integer.parseInt(String.valueOf(c[i]))*2;
if(cint[i] >9)
cint[i]=1+cint[i]%10;
}
else
cint[i] = Integer.parseInt(String.valueOf(c[i]));
}
int sum=0;
for(int i=0;i<16;i++){
sum+=cint[i];
}
if(sum%10==0)
result.setText("Card is Valid");
else
result.setText("Card is Invalid");
}else
result.setText("Card is Invalid");
If you want to make it use on any number replace all 16 with your input number length.
It will work for Visa number given in the question.(I tested it)
Here's my implementation of the Luhn Formula.
/**
* Runs the Luhn Equation on a user inputed CCN, which in turn
* determines if it is a valid card number.
* #param c A user inputed CCN.
* #param cn The check number for the card.
* #return If the card is valid based on the Luhn Equation.
*/
public boolean luhn (String c, char cn)
{
String card = c;
String checkString = "" + cn;
int check = Integer.valueOf(checkString);
//Drop the last digit.
card = card.substring(0, ( card.length() - 1 ) );
//Reverse the digits.
String cardrev = new StringBuilder(card).reverse().toString();
//Store it in an int array.
char[] cardArray = cardrev.toCharArray();
int[] cardWorking = new int[cardArray.length];
int addedNumbers = 0;
for (int i = 0; i < cardArray.length; i++)
{
cardWorking[i] = Character.getNumericValue( cardArray[i] );
}
//Double odd positioned digits (which are really even in our case, since index starts at 0).
for (int j = 0; j < cardWorking.length; j++)
{
if ( (j % 2) == 0)
{
cardWorking[j] = cardWorking[j] * 2;
}
}
//Subtract 9 from digits larger than 9.
for (int k = 0; k < cardWorking.length; k++)
{
if (cardWorking[k] > 9)
{
cardWorking[k] = cardWorking[k] - 9;
}
}
//Add all the numbers together.
for (int l = 0; l < cardWorking.length; l++)
{
addedNumbers += cardWorking[l];
}
//Finally, check if the number we got from adding all the other numbers
//when divided by ten has a remainder equal to the check number.
if (addedNumbers % 10 == check)
{
return true;
}
else
{
return false;
}
}
I pass in the card as c which I get from a Scanner and store in card, and for cn I pass in checkNumber = card.charAt( (card.length() - 1) );.
Okay, this can be solved with a type conversions to string and some Java 8
stuff. Don't forget numbers and the characters representing numbers are not the same. '1' != 1
public static int[] longToIntArray(long cardNumber){
return Long.toString(cardNumber).chars()
.map(x -> x - '0') //converts char to int
.toArray(); //converts to int array
}
You can now use this method to perform the luhn algorithm:
public static int luhnCardValidator(int cardNumbers[]) {
int sum = 0, nxtDigit;
for (int i = 0; i<cardNumbers.length; i++) {
if (i % 2 == 0)
nxtDigit = (nxtDigit > 4) ? (nxtDigit * 2 - 10) + 1 : nxtDigit * 2;
sum += nxtDigit;
}
return (sum % 10);
}
private static int luhnAlgorithm(String number){
int n=0;
for(int i = 0; i<number.length(); i++){
int x = Integer.parseInt(""+number.charAt(i));
n += (x*Math.pow(2, i%2))%10;
if (x>=5 && i%2==1) n++;
}
return n%10;
}
public class Creditcard {
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
String cardno = sc.nextLine();
if(checkType(cardno).equals("U")) //checking for unknown type
System.out.println("UNKNOWN");
else
checkValid(cardno); //validation
}
private static String checkType(String S)
{
int AM=Integer.parseInt(S.substring(0,2));
int D=Integer.parseInt(S.substring(0,4)),d=0;
for(int i=S.length()-1;i>=0;i--)
{
if(S.charAt(i)==' ')
continue;
else
d++;
}
if((AM==34 || AM==37) && d==15)
System.out.println("AMEX");
else if(D==6011 && d==16)
System.out.println("Discover");
else if(AM>=51 && AM<=55 && d==16)
System.out.println("MasterCard");
else if(((S.charAt(0)-'0')==4)&&(d==13 || d==16))
System.out.println("Visa");
else
return "U";
return "";
}
private static void checkValid(String S) // S--> cardno
{
int i,d=0,sum=0,card[]=new int[S.length()];
for(i=S.length()-1;i>=0;i--)
{
if(S.charAt(i)==' ')
continue;
else
card[d++]=S.charAt(i)-'0';
}
for(i=0;i<d;i++)
{
if(i%2!=0)
{
card[i]=card[i]*2;
if(card[i]>9)
sum+=digSum(card[i]);
else
sum+=card[i];
}
else
sum+=card[i];
}
if(sum%10==0)
System.out.println("Valid");
else
System.out.println("Invalid");
}
public static int digSum(int n)
{
int sum=0;
while(n>0)
{
sum+=n%10;
n/=10;
}
return sum;
}
}
Here is the implementation of Luhn algorithm.
public class LuhnAlgorithm {
/**
* Returns true if given card number is valid
*
* #param cardNum Card number
* #return true if card number is valid else false
*/
private static boolean checkLuhn(String cardNum) {
int cardlength = cardNum.length();
int evenSum = 0, oddSum = 0, sum;
for (int i = cardlength - 1; i >= 0; i--) {
System.out.println(cardNum.charAt(i));
int digit = Character.getNumericValue(cardNum.charAt(i));
if (i % 2 == 0) {
int multiplyByTwo = digit * 2;
if (multiplyByTwo > 9) {
/* Add two digits to handle cases that make two digits after doubling */
String mul = String.valueOf(multiplyByTwo);
multiplyByTwo = Character.getNumericValue(mul.charAt(0)) + Character.getNumericValue(mul.charAt(1));
}
evenSum += multiplyByTwo;
} else {
oddSum += digit;
}
}
sum = evenSum + oddSum;
if (sum % 10 == 0) {
System.out.println("valid card");
return true;
} else {
System.out.println("invalid card");
return false;
}
}
public static void main(String[] args) {
String cardNum = "4071690065031703";
System.out.println(checkLuhn(cardNum));
}
}
public class LuhnAlgorithm {
/**
* Returns true if given card number is valid
*
* #param cardNum Card number
* #return true if card number is valid else false
*/
private static boolean checkLuhn(String cardNum) {
int cardlength = cardNum.length();
int evenSum = 0, oddSum = 0, sum;
for (int i = cardlength - 1; i >= 0; i--) {
System.out.println(cardNum.charAt(i));
int digit = Character.getNumericValue(cardNum.charAt(i));
if (i % 2 == 0) {
int multiplyByTwo = digit * 2;
if (multiplyByTwo > 9) {
/* Add two digits to handle cases that make two digits after doubling */
String mul = String.valueOf(multiplyByTwo);
multiplyByTwo = Character.getNumericValue(mul.charAt(0)) + Character.getNumericValue(mul.charAt(1));
}
evenSum += multiplyByTwo;
} else {
oddSum += digit;
}
}
sum = evenSum + oddSum;
if (sum % 10 == 0) {
System.out.println("valid card");
return true;
} else {
System.out.println("invalid card");
return false;
}
}
public static void main(String[] args) {
String cardNum = "8112189875";
System.out.println(checkLuhn(cardNum));
}
}
Hope it may works.
const options = {
method: 'GET',
headers: {Accept: 'application/json', 'X-Api-Key': '[APIkey]'}
};
fetch('https://api.epaytools.com/Tools/luhn?number=[CardNumber]&metaData=true', options)
.then(response => response.json())
.then(response => console.log(response))
.catch(err => console.error(err));

Categories

Resources