What's wrong with my Luhn algorithm code? - java

I'm trying to use this code to test if a sample code is a valid credit card number or not (using the Luhn algorithm) in Java. Where did I go wrong? It takes in an array of 16 one-digit numbers. Any help would be much appreciated. Thanks!
private static boolean isValidCC(int[] number) {
int sum = 0;
boolean alternateNum = true;
for (int i = number.length-1; i>=0; i--) {
int n = number[i];
if (alternateNum) {
n *= 2;
if (n > 9) {
n = (n % 10) + 1;
}
}
sum += n;
alternateNum = !alternateNum;
}
System.out.println(sum);
return (sum % 10 == 0);
}

Your code is correct except you started with the wrong alternate digit. Change to:
boolean alternateNum = false;

Judging from Wikipedia article --you've missed a checksum digit or erroneously taking it into account--.
Update: most probably, you've started with a wrong "alternate" flag.
There is a Java snippet, so why not use it?
public static boolean isValidCC(String number) {
final int[][] sumTable = {{0,1,2,3,4,5,6,7,8,9},{0,2,4,6,8,1,3,5,7,9}};
int sum = 0, flip = 0;
for (int i = number.length() - 1; i >= 0; i--) {
sum += sumTable[flip++ & 0x1][Character.digit(number.charAt(i), 10)];
}
return sum % 10 == 0;
}

Alternating digits are doubled counting from the end not the beginning.
instead of using your alternateNum bool try this.
if((number.length - i) % 2 == 0){
n *= 2;
...
}

Related

Armstrong Number Checker in Java

I am still somewhat of a beginner to Java, but I need help with my code. I wanted to write an Armstrong Number checker.
An Armstrong number is one whose sum of digits raised to the power three equals the number itself. 371, for example, is an Armstrong number because 3^3 + 7^3 + 1^3 = 371.
If I understand this concept correctly, then my code should work fine, but I don't know where I made mistakes. I would appreciate if you could help correct my mistakes, but still kind of stick with my solution to the problem, unless my try is completely wrong or most of it needs to change.
Here is the code:
public class ArmstrongChecker {
boolean confirm = false;
Integer input;
String converter;
int indices;
int result = 1;
void ArmstrongCheck(Integer input) {
this.input = input;
converter = input.toString();
char[] array = converter.toCharArray();
indices = array.length;
result = (int) Math.pow(array[0], indices);
for (int i = 1; i < array.length; i++) {
result = result + (int) Math.pow(array[i], indices);
}
if (result == input) {
confirm = true;
System.out.println(confirm);
} else {
System.out.println(confirm);
}
}
}
For my tries I used '153' as an input. Thank you for your help!
You aren't summing the digits, but the numeric values of the characters representing them. You can convert such a character to its numeric value by subtracting the character '0':
int result = 0;
for(int i = 0; i < array.length; i++) {
result = result + (int) Math.pow(array[i] - '0', indices);
}
Having said that, it's arguably (probably?) more elegant to read the input as an actual int number and iterate its digits by taking the reminder of 10 on each iteration. The number of digits itself can be calculated using a base-10 log.
int temp = input;
int result = 0;
int indices = (int) Math.log10(input) + 1;
while (temp != 0) {
int digit = temp % 10;
result += (int) Math.pow(digit, indices);
temp /= 10;
}
There is a small logical mistake in your code, You're not converting the character to an integer instead you're doing something like
Math.pow('1', 3) -> Math.pow(49, 3) // what you're doing
Math.pow(1, 3) // what should be done
You should first convert the character to the string using any method below
result = (int) Math.pow(array[0],indices);
for(int i = 1;i<array.length;i++) {
result = result + (int) Math.pow(array[i],indices);
}
For converting char to integer
int x = Character.getNumericValue(array[i]);
or
int x = Integer.parseInt(String.valueOf(array[i]));
or
int x = array[i] - '0';
Alternatively
You can also check for Armstrong's number without any conversion, using the logic below
public class Armstrong {
public static void main(String[] args) {
int number = 153, num, rem, res = 0;
num = number;
while (num != 0)
{
rem = num % 10;
res += Math.pow(rem, 3);
num /= 10;
}
if(res == num)
System.out.println("YES");
else
System.out.println("NO");
}
}
For any int >= 0 you can do it like this.
Print all the Armstrong numbers less than 10_000.
for (int i = 0; i < 10_000; i++) {
if (isArmstrong(i)) {
System.out.println(i);
}
}
prints
0
1
2
3
4
5
6
7
8
9
153
370
371
407
1634
8208
9474
The key is to use Math.log10 to compute the number of digits in the candidate number. This must be amended by adding 1. So Math.log10(923) returns 2.965201701025912. Casting to an int and adding 1 would be 3 digits.
The number of digits is then the power used for computation.
Then it's just a matter of summing up the digits raised to that power. The method short circuits and returns false if the sum exceeds the number before all the digits are processed.
public static boolean isArmstrong(int v) {
if (v < 0) {
throw new IllegalArgumentException("Argument must >= 0");
}
int temp = v;
int power = (int)Math.log10(temp)+1;
int sum = 0;
while (temp > 0) {
sum += Math.pow(temp % 10, power);
if (sum > v) {
return false;
}
temp/= 10;
}
return v == sum;
}

Maximum Remainder

Maximum remainder
You are given a number N. Write a program to find a natural number that is smaller than N such that N gives the highest remainder when divided by that number.
If there is more than one such number, print the smallest one.
Can anyone help I think I'm missing something like if 2 numbers will have same reaminders my code would overwrite the minDivisor to the upper value
static int findRemainder(int num){
int maxRemainder=0;
int minDivisor=0
int answer=0;
for(int i = 1; i<num; i++){
if(maxRemainder <= (num % i)) {
maxRemainder = num % i;
if(minDivisor < i && maxRemainder == num%i) {
} else {
minDivisor = i;
}
}
return minDivisor;
}
}
Check this out:
int largestRemainder = c % ((c/2) + 1);

Java : Not sure if correct use of BigInteger

This program is meant to calculate the sum x amount of prime numbers under n, yet my code doesnt seem to work, it compiles and there are no errors.When I run it the console is just blank
public static void main(String[] args) {
Prime prime = new Prime();
BigInteger answer = BigInteger.valueOf(0);
for (int i = 2; i < 2000000; i++) {
if (prime.isPrime(i)) {
answer = answer.add(BigInteger.valueOf(i));
}
}
System.out.println(answer);
}
isPrime method
boolean isPrime(int n) {
for(int i = 2; i < n ; i++) {
if(n % i == 0) {
return false;
}
}
return true;
}
You are just not waiting long enough.
Try using i < 200 and you'll see the answer 4227 print out quite quickly.
You are checking 2,000,000 numbers for primality. Your isPrime method is O(n) so you are doing approximately 2,000,000 * 1,000,000 calculations. You work it out.
Why not use isProbablePrime() method from BigInteger class, if you using it anyway ?
for (int i = 2; i < 2000000; i++) {
if (new BigInteger(Integer.toString(i)).isProbablePrime(10)) {
answer = answer.add(BigInteger.valueOf(i));
}
}
This code runs only for around 4 seconds.
But if you want to do by your method, you should optimize it. It's necessary to check for divisors until sqrt(n)
for(int i = 3; i * i <= n ; i+= 2) {
if(n % i == 0) {
return false;
}
}
Or you can use the Sieve of Eratosthenes to solve your problem

Java program on "friendly numbers "

I am working on a assignment about so called "friendly-numbers" with the following definition: An integer is said to be friendly if the leftmost digit is divisible by 1, the leftmost two digits are divisible by 2, and the leftmost three digits are divisible by 3, and so on. The n-digit itself is divisible by n.
Also it was given we need to call a method (as I did or at least tried to do in the code below). It should print whether a number is friendly or not. However, my program prints "The integer is not friendly." in both cases. From what I have tried, I know the counter does work. I just cannot find what I am missing or doing wrong. Help would be appreciated, and preferably with an adaptation of the code below, since that is what I came up with myself.
import java.util.Scanner;
public class A5E4 {
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.print("Please enter an integer: ");
int friendlyNumber = in.nextInt();
boolean result = isFriendly(friendlyNumber);
if (result)
{
System.out.println("The integer is friendly");
}
else
{
System.out.println("The integer is not friendly");
}
}
public static boolean isFriendly(int number)
{
int counter = 1;
while (number / 10 >= 1)
{
counter ++;
number = number / 10;
}
boolean check = true;
for (int i = 1; i <= counter; i++)
{
if (number / Math.pow(10, (counter - i)) % i == 0 && check)
{
check = true;
}
else
{
check = false;
}
}
return check;
}
}
while (number / 10 >= 1){
counter ++;
number = number / 10;
}
In this bit, you are reducing number to something smaller than 10. That is probably not what you want. You should make a copy of number here.
Also, proper software design would recommend that you extract this to a dedicated method.
private int countDigits(int number){
if(number < 1) throw new IllegalArgumentException();
int n = number;
int counter = 1;
while (n / 10 >= 1){
counter ++;
n = n / 10;
}
return counter;
}
You need to copy the number which you use to find out how much digits your number has. Otherwise you change the number itself and don't know anymore what it was.
The second mistake is that you divide an integer by Math.pow() which returns a double. So your result is double. You want to have an integer to use the modulo operator.
public static boolean isFriendly(int number)
{
int counter = 1;
int tmpNumber = number;
while (tmpNumber / 10 >= 1)
{
counter ++;
tmpNumber = tmpNumber / 10;
}
boolean check = true;
for (int i = 1; i <= counter; i++)
{
if ((int)(number / Math.pow(10, (counter - i))) % i == 0 && check)
{
check = true;
}
else
{
check = false;
}
}
return check;
}
The first problem is that you are modifying the value of the number you are trying to check. So, if your method is called with 149, then after the while loop to count the digits, its value will be 1. So, you are always going to find that it is 'unfriendly'. Assuming you fix this so that number contains the number you are checking. Try this instead of your 'for' loop:
while ( counter && !( ( number % 10 / counter ) % counter ) )
{
number = number / 10;
counter--;
}
It works by taking the last digit of your number using the modulus or remainder operator and then divides this by the digit position and checks that the remainder is zero. If all is good, it decrements the counter until it reaches zero, otherwise it terminates before counter is zero.
Try something like this (change your isFriendly() method):
public static boolean isFriendly(int number)
{
String numberAsString = String.valueOf(number); //Convert the int as a String to make it easier to iterate through
for(int i = 0; i < numberAsString.length(); i++) {
int currentDigit = Character.getNumericValue(numberAsString.charAt(numberAsString.length() - i - 1)); //Iterate over the number backwards
System.out.println(currentDigit); //Print the current digit
if(currentDigit % (i + 1) != 0) {
return false;
}
}
return true;
}
The easy way is to convert to string and then check if it is friendly:
public static boolean isFriendly(int number)
{
String num = Integer.toString(number);
for (int i = 0, dividedBy = 1; i < num.length(); i++, dividedBy++)
{
String numToCheck = "";
for (int j = 0; j <= i; j++)
{
numToCheck += num.charAt(j);
}
if (Integer.valueOf(numToCheck) % dividedBy != 0) {
return false;
}
}
return true;
}

how do i get even placed digits from a number in java

I want my program to get all the even digits from a number input. Then multiply those with digits with 2. If the result is a two digit number, add them. At the end i want it to give me the sum of all the even digits.
public class evenplaceadd {
public static void main(String[] args) {
System.out.println(sumOfevenPlace(5566));
}
public static int sumOfevenPlace(int number)
{
int maxDigitLength = 4;
int sum = 0;
for (int i = 0; i < maxDigitLength; i++)
{
if (i % 2 == 0)
{
int digita = number % 10;
int digitb =digita*2;
int digitc;
if(digita < 9)
{
sum = sum + digitb;
}
else if(digitb>9)
{
digitc =(digitb % 10)+ (digitb /10);
sum =sum + digitc;
}
}
else
{
number = number/10;
}
}
return sum;
}
}
Your code seems ok for the most part. There are some minor flaws in the code which I am sure you will be able to figure out after understanding the code provided below. I have changed it up a bit and made it easier to read. Please confirm it is working, and next time please provide the code when asking question. I know you are new to the community, and so am I. Its a learning experience for all of us. All the best in the future :)
public static void int sumOfEvenDigits(int num){
int sum = 0;
int lastDig = 0;
while(num/10 != 0)
{
lastDig = num % 10;
num = num / 10;
if(lastDig % 2 != 0)
{
continue;
}
if(lastDig > 10)
{
sum += lastDig / 10;
sum += lastDig % 10;
}
else
{
sum += lastDig;
}
}
return sum;
}

Categories