NChooseR Java Recursion Program - java

I'm having a problem finding the "NChooseR" value when the user enters two numbers, and the program must use recursion. The "NChooseR" formula must be n! / r!(n-r)!
Scanner input = new Scanner(System.in);
System.out.println("This program will calculate the number of ways to chose r different objects from a set of n objects\n");
System.out.println("How many objects would you like to chose? (r value)");
int userR = input.nextInt();
System.out.println("How many objects are there to chose from? (n value)");
int userN = input.nextInt();
System.out.println("There are " + nchooser(userN, userR) + " ways to chose " + userR + " objects from a set of " + userN + " objects");
}
public static long factorialn(int n) {
//return a value of one for terms one and two
if ((n == 1) || (n == 2)) {
return 1;
} else {
return factorialn(n - 1) + factorialn(n - 2);
}
}
public static long factorialr(int r) {
//return a value of one for terms one and two
if ((r == 1) || (r == 2)) {
return 1;
} else {
return factorialr(r - 1) + factorialr(r - 2);
}
}
public static long factorialnr(int r, int n) {
//return a value of one for terms one and two
if ((r == 1) || (r == 2) || (n == 1) || (n == 2)) {
return 1;
} else {
return factorialr((n-r) - 1) + factorialr((n - r) - 2);
}
}
public static long nchooser(int r, int n) {
return factorialn(n) / (factorialr(r) * (factorialnr(n,r)));
}

here is some code that may work with larger numbers:
public static final long f(final int n) { // factorial
long i,p;
if(n<=1)
p=1;
else for(p=n,i=2;i<=n-1;i++)
p=p*i;
return (p);
}
public static final long c(final int n,final int r) { // binomial coefficient
long i,p;
if(r<0||n<0||r>n)
p=0;
else if(r==0)
p=1;
else if(r>n-r)
p=c(n,n-r);
else {
for(p=1,i=n;i>=n-r+1;i--)
p=p*i;
p=p/f(r);
}
return p;
}

Related

Java recursion exponentiation method making recursion more efficient

I'd like to change this exponentiation method (n is the exponent):
public static double exponentiate(double x, int n) {
counter++;
if (n == 0) {
return 1.0;
} else if (n == 1) {
return x;
} else {
return x * exponentiate(x, n - 1);
}
}
I'd like to change the method to make it more efficient, so the method is not opened n times but maximum (n/2+1) times WITHOUT using the class MATH.
So far I came up with this code:
public static double exponentiate(double x, int n) {
counter++;
if (n == 0) {
return 1.0;
} else if (n == 1) {
return x;
} else {
if (n % 2 == 0) {
n = n-(n-1);
} else {
n = ((n-1) / 2) + n;
}
return ((x * x) * exponentiate(x, n - (n / 2)));
}
}
But somehow it only works for odd n, not vor even n.
Can somebody help?
Thanks!
I think you can optimize the above method to run for O(logn) by calculating exponentiate(x,n/2) once and using it.
Something like this:-
public static double exponentiate(double x, int n)
{
int temp;
if(n == 0)
return 1;
temp = exponentiate(x, n/2);
if (n%2 == 0)
return temp*temp;
else
return x*temp*temp;
}
Hope this helps!
I don't know if this is the solution you search but this is an example of an algorithm that perform exponentiation in O(log(n)) time
public static double exponentiate(double x, int n) {
if (n == 0) {
return 1.0;
} else if (n == 1) {
return x;
} else {
return ((n % 2 == 0) ? 1 : x) * exponentiate(x * x, n / 2);
}
}

Java program not outputting correct values

I'm trying to create a simple program that determines if a number can be written as n^x and what n and x are. Ex: 81 = 3^4. My program correctly identifies numbers that can be written as n^x but the values for n and x are way off. (this is just supposed to be an exercise). The logic in my coding is kind of confusing so here's basically what it is. First it finds a number that can divide into a (the chosen number), then it figures out if the a can be divided by the number until it reaches 1. Then it figures out how many times it takes to reach 1. I can't find any problems with the logic. Here's my code.
public static void main(String[] args) {
Scanner scan1 = new Scanner(System.in);
int a = scan1.nextInt();
scan1.close();
int i = 2;
boolean y = false;
int x = 0;
for (; i <= Math.sqrt(a); i++) {
if (a % i == 0) {
int n = i;
for (; n <= a; n *= i) {
if (a % n != 0) {
y = false;
break;
}
x++;
y = true;
}
}
}
if (y == true) {
System.out.println(a + " = " + i + " ^ " + x);
}
else {
System.out.println("Your number cannot be represented as n^x");
}
}
public static void main(String[] args) {
Scanner scan1 = new Scanner(System.in);
int a = scan1.nextInt();
scan1.close();
int i = 2;
boolean y = false;
int x = 0;
for(; i <= Math.sqrt(a); i++) {
if (a % i == 0) {
int n = i;
for (; n <= a; n *= i) {
if (a % n != 0) {
y = false;
}
y = true;
x = n;
break;
}
}
}
i--;
if (y == true) {
System.out.println(a + " = " + i + " ^ " + x);
}
else {
System.out.println("Your number cannot be represented as n^x");
}
}
Use a do-while for the outer loop and you won't need i--; at the end.

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();
}
}

Why is my method repeating when I run

public class PalindromicPrimes {
public static void main (String[] args) {
userInt();
System.out.println("The palindromic primes less than " + userInt() +
" are:");
for (int i = 0; i <= userInt(); i++) {
if (isPrime() && isPalindrome()) {
System.out.println(i);
}
}
}
private static boolean isPrime() {
if (userInt() == 2 || userInt() == 3) {
return true;
}
if (userInt() % 2 == 0) {
return false;
}
int sqrt = (int) Math.sqrt(userInt()) + 1;
for (int i = 3; i < sqrt; i += 2) {
if (userInt() % i == 0) {
return false;
}
}
return true;
}
private static boolean isPalindrome() {
if (userInt() < 0)
return false;
int div = 1;
while (userInt() / div >= 10) {
div *= 10;
}
while (userInt() != 0) {
int x = userInt();
int l = x / div;
int r = x % 10;
if (l != r)
return false;
x = (x % div) / 10;
div /= 100;
}
return true;
}
private static int userInt() {
Scanner s = new Scanner(System.in);
System.out.print("Enter a positive integer: ");
int userInt = s.nextInt();
return userInt;
}
}
is there a different way of getting the user input? or can I keep it this way?
when it runs it just keeps prompting the user input.
rearrange it like this:
public static void main (String[] args) {
//get it and save it here!
int userValue = userInt();
System.out.println("The palindromic primes less than " + userValue +
" are:");
for (int i = 0; i <= userValue; i++) {
if (isPrime(userValue) && isPalindrome(userValue)) {
System.out.println(i);
}
}
}
then also update all the methods that care about this "userInt" value.
Every time you call userInt() you're telling the code to get a new value from the command line.
Try this:
public static void main (String[] args) {
int value = userInt();
System.out.println("The palindromic primes less than " + value +
" are:");
for (int i = 0; i <= value; i++) {
if (isPrime() && isPalindrome()) {
System.out.println(i);
}
}
}
The term userInt() is a function invocation that prompts the user for input. Odds are you only want to do this once. You're doing it multiple times.
You should store the result of userInt() in a variable.
int typed = userInt();
And then use this variable to reference what the user typed instead of calling userInt() again.
System.out.println("The palindromic primes less than " + typed +
" are:");
for(int i = 0; i < typed; i++) ...
You keep calling userInt(). That is the problem.
I don't understand your logic. So I have not modified that code. But the code runs.
import java.util.Scanner;
public class PalindromicPrimes {
public static void main (String[] args) {
int x = userInt();
System.out.println("The palindromic primes less than " + x +
" are:");
for (int i = 0; i <= x; i++) {
if (isPrime(i) && isPalindrome(i)) {
System.out.println(i);
}
}
}
private static boolean isPrime(int a) {
if (a == 2 || a == 3) {
return true;
}
if (a % 2 == 0) {
return false;
}
int sqrt = (int) Math.sqrt(a) + 1;
for (int i = 3; i < sqrt; i += 2) {
if (a % i == 0) {
return false;
}
}
return true;
}
private static boolean isPalindrome(int a) {
if (a < 0)
return false;
int div = 1;
while (a / div >= 10) {
div *= 10;
}
while (a != 0) {
int x = a;
int l = x / div;
int r = x % 10;
if (l != r)
return false;
x = (x % div) / 10;
div /= 100;
}
return true;
}
private static int userInt() {
Scanner s = new Scanner(System.in);
System.out.print("Enter a positive integer: ");
int userInteger = s.nextInt();
return userInteger;
}
}
Remember, don't use the same names for variable and function. In the function userInt(), you have used a variable int userInt, to get the result from the scanner. This might be aa recursive call sometimes. Be careful with that.

How can I output the hundred and teens numbers in words in my program

I need help to display my hundred and teens number in words. For example if I enter 116. My program will output One hundred and Six, instead of One hundred and sixteen. All the other numbers that I input work except for the teens numbers.
I would change 4 things in your code:
First:
Use int instead of double for your input
int numInput = Integer.parseInt(br.readLine());//user inputs number
Second:
In order to get the appropriate digit placements in int use:
int hundredsDigit = (numInput % 1000) / 100;
int tensDigit = (numInput % 100) / 10;
int onesDigit = numInput % 10;
instead of:
double hundredsDigit=Math.floor((numInput%1000)/100);
double tensDigit = Math.floor((numInput % 100) / 10);
double onesDigit = numInput % 10;
Third:
The else condition for the 110-119 range must be before the 100-999 (which technically should be 120-999)
Fourth:
Your teens method is taking the original numInput as parameter.
What you need to take is the onesDigit to determine which "teen" it is
So it should be a call like:
teens(onesDigit);
This call must be changed in the [10-19] condition and the [110-119] condition
And your teens new method should look like:
public static void teens(int onesDigit) {
if (onesDigit == 0) {
System.out.print("Ten ");
}
if (onesDigit == 1) {
System.out.print("Eleven ");
}
if (onesDigit == 2) {
System.out.print("Twelve ");
}
if (onesDigit == 3) {
System.out.print("Thirteen ");
}
if (onesDigit == 4) {
System.out.print("Fourteen ");
}
if (onesDigit == 5) {
System.out.print("Fifteen ");
}
if (onesDigit == 6) {
System.out.print("Sixteen ");
}
if (onesDigit == 7) {
System.out.print("Seventeen ");
}
if (onesDigit == 8) {
System.out.print("Eighteen ");
}
if (onesDigit == 9) {
System.out.print("Nineteen ");
}
}//closes teens method
That happens because you check if the number is in the range [100, 999] before checking that it is in the range [100, 119], change the order of the ifs and it will work just fine.
Start from smallest number to highest when comparing.
First condition:
if((numInput>=10)&&(numInput<=19)){
Second:
else if((numInput>=20)&&(numInput<=99)){
Third:
else if((numInput>100)&&(numInput<=119)){
Fourth:
else if((numInput>=100)&&(numInput<=999)){
You should put the
else if((numInput>100)&&(numInput<=119))
clause before the more inclusive
else if((numInput>=100)&&(numInput<=999))
What's happening here is that the larger range is searched first, and your tens function doesn't output anything for 1.
Your else if
else if((numInput>100)&&(numInput<=119)){
hundreds(hundredsDigit);
System.out.print(" ");
teens(numInput);
}
must be placed one level higher... Since the
else if((numInput>=100)&&(numInput<=999)){
hundreds(hundredsDigit);
System.out.print(" ");
tens(tensDigit);
System.out.print(" ");
ones(onesDigit);
}
will also fulfill the condition, the "116" you entered will never get there...
Just in case you wan't this, I did not write this:
public static String intToText(int n) {
if (n < 0)
return "Minus " + intToText(-n);
else if (n == 0)
return "Zero";
else if (n <= 19)
return oneToNineteen[n - 1] + " ";
else if (n <= 99)
return twentyToNinety[n / 10 - 2] + " " + intToText(n % 10);
else if (n <= 199)
return "One Hundred " + intToText(n % 100);
else if (n <= 999)
return intToText(n / 100) + "Hundred " + intToText(n % 100);
else if (n <= 1999)
return "One Thousand " + intToText(n % 1000);
else if (n <= 999999)
return intToText(n / 1000) + "Thousand " + intToText(n % 1000);
else if (n <= 1999999)
return "One Million " + intToText(n % 1000000);
else if (n <= 999999999)
return intToText(n / 1000000) + "Million " + intToText(n % 1000000);
else if (n <= 1999999999)
return "One Billion " + intToText(n % 1000000000);
else
return intToText(n / 1000000000) + "Billion " + intToText(n % 1000000000);
}
This was fun. It has the following issues:
-Only deals with integers. No longs, doubles etc.
-Doesn't deal with the single case of zero.
-Fails at Integer.MIN_VALUE because of the number = number * -1
Otherwise, it seems to work. The motivation was that I can't stand huge blocks of "if-else" code.
public class NumbersToWords {
private static final Map<Integer,String> NUM_TO_WORD = new HashMap<Integer, String>();
private static final List<Integer> KEYS = new ArrayList<Integer>(30);
static {
NUM_TO_WORD.put(0,"zero");
NUM_TO_WORD.put(1,"one");
NUM_TO_WORD.put(2,"two");
NUM_TO_WORD.put(3,"three");
NUM_TO_WORD.put(4,"four");
NUM_TO_WORD.put(5,"five");
NUM_TO_WORD.put(6,"six");
NUM_TO_WORD.put(7,"seven");
NUM_TO_WORD.put(8,"eight");
NUM_TO_WORD.put(9,"nine");
NUM_TO_WORD.put(10,"ten");
NUM_TO_WORD.put(11,"eleven");
NUM_TO_WORD.put(12,"twelve");
NUM_TO_WORD.put(13,"thirteen");
NUM_TO_WORD.put(14,"fourteen");
NUM_TO_WORD.put(15,"fifteen");
NUM_TO_WORD.put(16,"sixteen");
NUM_TO_WORD.put(17,"seventeen");
NUM_TO_WORD.put(18,"eighteen");
NUM_TO_WORD.put(19,"nineteen");
NUM_TO_WORD.put(20,"twenty");
NUM_TO_WORD.put(30,"thirty");
NUM_TO_WORD.put(40,"forty");
NUM_TO_WORD.put(50,"fifty");
NUM_TO_WORD.put(60,"sixty");
NUM_TO_WORD.put(70,"seventy");
NUM_TO_WORD.put(80,"eighty");
NUM_TO_WORD.put(90,"ninety");
NUM_TO_WORD.put(100,"hundred");
NUM_TO_WORD.put(1000,"thousand");
NUM_TO_WORD.put(1000000,"million");
NUM_TO_WORD.put(1000000000,"billion");
KEYS.addAll(NUM_TO_WORD.keySet());
Collections.sort(KEYS);
}
public static void main(String[] args){
int[] testValues = {24,4,543755,12,10000,123000,123,Integer.MAX_VALUE, -456};
NumbersToWords ntw = new NumbersToWords();
for(int i : testValues){
System.out.println(i + " -> " + ntw.getWords(i));
}
}
/* called recursively */
public String getWords(int number){
boolean isNegative = number < 0;
if(isNegative){
number = number * -1;
}
if(number < 100){
return getWordLessThanHundred(number);
}
StringBuilder words = new StringBuilder(50);
int key = getKey(number);
if(isNegative){
words.append("negative ");
}
words.append(getWords(number/key))
.append(" ").append(NUM_TO_WORD.get(key)) // get the largest placeholder word
.append(" ").append(getWords(number % key)); // get the rest
return words.toString();
}
private String getWordLessThanHundred(int number){
if(number == 0){
return "";
}
if(number < 21){
return NUM_TO_WORD.get(number);
}
int key = getKey(number);
return NUM_TO_WORD.get(key) + " " + NUM_TO_WORD.get(number - key);
}
private int getKey(int number){
for(int i = 0; i<KEYS.size();i++){
int value = KEYS.get(i);
if(i > 0 && number < value){
return KEYS.get(i - 1);
}else if(number == value){
return value;
}
}
return KEYS.get(KEYS.size() - 1);
}
}

Categories