Find amount of happy numbers in a given range - java

I need to find all happy numbers in a given range (input)
A happy number is a number which eventually reaches 1 when replaced by the sum of the square of each digit. 13 is a happy number because 1^2 + 3^2 = 10 And 1^2 + 0^2 = 1, thus 13 is a happy number.
So far I have this:
import java.util.HashSet;
import java.util.Set;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String wrd = scan.nextLine().trim();
String wrd2 = scan.nextLine().trim();
int nieuwnummer = Integer.parseInt(wrd);
int nieuwnummer2 = Integer.parseInt(wrd2);
// int count = 0
Set<Integer> numbers = new HashSet<Integer>();
for (int i = nieuwnummer; i <= nieuwnummer2; i++) { while(nieuwnummer>0) {
nieuwnummer2 += (nieuwnummer % 10)*(nieuwnummer % 10);
nieuwnummer /=10; };
}
nieuwnummer = nieuwnummer2;
}
//System.out.println(count)
}
I think the range isn't working yet and I need a way to actually count the happy number. Please help :)

Here is some working example.
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String st1 = scan.nextLine().trim();
String st2 = scan.nextLine().trim();
int min = Integer.parseInt(st1);
int max = Integer.parseInt(st2);
Set<Integer> happyNumbers = getHappyNumbers(min, max);
System.out.println(happyNumbers.size());
}
public static Set<Integer> getHappyNumbers(int min, int max) {
Set<Integer> out = new HashSet<>();
for (int i = min; i < max; i++) {
if (isHappy(i)) {
out.add(i);
}
}
return out;
}
private static boolean isHappy(int i) {
int sum = 0;
while (i != 0) {
sum += Math.pow((i % 10), 2);
i /= 10;
}
if (sum == 1) return true;
else if (sum >= 10) {return isHappy(sum);}
else return false;
}
}

I don't know if I understand you correctly but:
You have while(nieuwnummer > 0) which is some number on start but after first loop it is changing to 0 [ eg. if range is from 1 to 16] so it will go one time and then skip.
For that kind of problem I would use something like this:
https://www.geeksforgeeks.org/lucky-numbers/
and iterate over the loop

Related

How can I choose a random element from an ArrayList if it changes size?

In my code "count0", "count1" and "count2" receive random values and "totalCount" is a sum of them. Here I have simplified it.
With this code I can choose a random element of the ArrayList but if for example "count0" is equal to 0 it will remove the index 0 from the ArrayList not only the first time but every iteration, causing error if this happens.
The idea is how to randomly choose ingredients from a pantry and when one is exhausted you can still choose from the rest.
Thanks for the help =)
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
public class RndNumArray {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
int totalCount=4, count0=1, count1=1, count2=2;
Random rnd = new Random();
ArrayList<Integer> numbers = new ArrayList<>(Arrays.asList(0, 1, 2));
while(totalCount > 0){
int rand = rnd.nextInt(numbers.size());
int num = numbers.get(rand);
if (num == 0) {
count0--;
if (ccount0 == 0) {
numbers.remove(0);
}
}
if (num == 1) {
count1--;
if (count1 == 0) {
numbers.remove(1);
}
}
if (num == 2) {
count2--;
if (count2 == 0) {
numbers.remove(2);
}
}
totalCount--;
System.out.println(num);
}
}
}
Thanks, guys. You guys are great.
I'll try all your suggestions but I've come up with a solution that works. Instead of deleting the items from the list I have given them a value that I will control with a do-while so that you only choose the available ones.
My code is a modification of the smoking problem (threads and synchronization). In my code each smoker has a certain number of cigars and can finish before the rest, so the agent does not have to put ingredients for him.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
public class RndNumArray {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
int totalCount=4, count0=1, count1=1, count2=2;
Random rnd = new Random();
ArrayList<Integer> numbers = new ArrayList<>(Arrays.asList(0, 1, 2));
while(totalCount>0){
int rand;
int num;
do{
rand = rnd.nextInt(numbers.size());
num = numbers.get(rand);
} while(num==3);
if (num == 0) {
count0--;
if (ccount0 == 0) {
numbers.set(0,3);
}
}
if (num == 1) {
count1--;
if (count1 == 0) {
numbers.set(1,3);
}
}
if (num == 2) {
count2--;
if (count2 == 0) {
numbers.set(2,3);
}
}
totalCount--;
System.out.println(num);
}
}
}
Use two List counts (how many count of product you have) and numbers (product number):
public static void main(final String[] args)
{
final int totalCount = 4;
final Random rnd = new Random();
final List<Integer> numbers = new ArrayList<>(Arrays.asList(0, 1, 2));
final List<Integer> counts = new ArrayList<>(Arrays.asList(1, 1, 2));
for (int i = 1; i < totalCount; i++)
{
final int rand = rnd.nextInt(numbers.size());
final int num = numbers.get(rand);
int count = counts.get(rand);
count--;
if (count < 1)
{
numbers.remove(rand);
counts.remove(rand);
}else
{
counts.set(rand, count);
}
System.out.println(num);
}
}
Or you can delete numbers List if you product numbers is always 0,1,2,3...

How to create dynamic array in java with unclear and diffrent inpu INDEXes?

I am new to Java and I needed dynamic Array ... all of thing I found that's for dynamic Array we should use "Array List' that's ok but when I want the indexes to be the power of X that given from input , I face ERORR ! .. the indexes are unclear and the are not specified what is the first or 2th power ! .... can anyone help me how solve it?
public static void main(String[] args) throws Exception {
Scanner Reader = new Scanner(System.in);
ArrayList<Float> Zarayeb = new ArrayList<Float>();
Float s ;
int m;
System.out.print("Add Count of equation Sentences : ");
int N = Reader.nextInt();
if (N == 0)
return;
for (int i = 0; i < N ; i++) {
s = Reader.nextFloat() ;
System.out.print("x^");
m = Reader.nextInt();
if (Zarayeb.get(m)== null)
Zarayeb.add(0 , s);
else{
Float l ;
l = Zarayeb.get(m);
Zarayeb.add (m , l+s);
}
if (i < N-1)
System.out.print("\r+");
}
System.out.print("Add Count of equation Sentences : ");
N = Reader.nextInt();
if (N == 0)
return;
for (int i = 0; i < N ; i++) {
s = Reader.nextFloat() ;
System.out.print("x^");
m = Reader.nextInt();
if (Zarayeb.get(m)== null)
Zarayeb.add(m , s);
else{
Float l ;
l = Zarayeb.get(m);
Zarayeb.add (m , l+s);
}
if (i < N-1)
System.out.print("\r+");
}
System.out.print("Enter X: ");
float X = Reader.nextFloat();
float Sum = 0;
for (int i = 0; i < Zarayeb.size();i++) {
Sum += (Zarayeb.get(i) * Math.pow(X,i));
}
System.out.println("\nThe final answer is : " + Sum);
First I refactored your code a bit to make sense of it:
Main class with the top level logic:
import java.util.Scanner;
public class Main {
private Scanner scanner;
private final Totals totals = new Totals();
public static void main(final String[] args) {
final Main app = new Main();
app.run();
}
private void run() {
scanner = new Scanner(System.in);
try {
readAndProcessEquationSentences();
} finally {
scanner.close();
}
}
private void readAndProcessEquationSentences() {
readSentences(true);
readSentences(false);
System.out.println("The final answer is : " + totals.calculateSum(readBaseInput()));
}
private void readSentences(final boolean useInitialLogic) {
System.out.print("Enter number of equation sentences:");
final int numberOfSentences = scanner.nextInt();
if (numberOfSentences == 0) {
throw new RuntimeException("No sentences");
}
for (int i = 0; i < numberOfSentences; i++) {
Sentence sentence = Sentence.read(scanner);
if (useInitialLogic) {
totals.addInitialSentence(sentence);
} else {
totals.addNextSentence(sentence);
}
if (i < numberOfSentences - 1) {
System.out.print("\r+");
}
}
}
private float readBaseInput() {
System.out.print("Enter base: ");
return scanner.nextFloat();
}
}
Sentence class which represents one equation sentence entered by the user:
import java.util.Scanner;
public class Sentence {
private Float x;
private int y;
public static Sentence read(final Scanner scanner) {
final Sentence sentence = new Sentence();
System.out.println("Enter x^y");
System.out.print("x=");
sentence.x = scanner.nextFloat();
System.out.println();
System.out.print("y=");
sentence.y = scanner.nextInt();
System.out.println();
return sentence;
}
public Float getX() {
return x;
}
public int getY() {
return y;
}
}
Totals class which keeps track of the totals:
import java.util.ArrayList;
import java.util.List;
public class Totals {
private final List<Float> values = new ArrayList<Float>();
public void addInitialSentence(final Sentence sentence) {
if (values.size() <= sentence.getY()) {
addToStart(sentence);
} else {
addToValue(sentence);
}
}
private void addToStart(final Sentence sentence) {
values.add(0, sentence.getX());
}
public void addNextSentence(final Sentence sentence) {
if (values.size() <= sentence.getY()) {
values.add(sentence.getY(), sentence.getX());
} else {
addToValue(sentence);
}
}
private void addToValue(final Sentence sentence) {
Float total = values.get(sentence.getY());
total = total + sentence.getX();
values.add(sentence.getY(), total);
}
public float calculateSum(final float base) {
float sum = 0;
for (int i = 0; i < values.size(); i++) {
sum += (values.get(i) * Math.pow(base, i));
}
return sum;
}
}
I don't have the foggiest idea what this is supposed to do. I named the variables according to this foggy idea.
You are letting the user input values in two separate loops, with a slightly different logic I called 'initial' and 'next'.
In the initial loop you were doing this:
if (Zarayeb.get(m) == null)
Zarayeb.add(0 , s);
In the next loop this:
if (Zarayeb.get(m) == null)
Zarayeb.add(m , s);
There are problems with this because the ArrayList.get(m) will throw an IndexOutOfBoundException if m is out or range. So I changed that to the equivalent of:
if (Zarayeb.size() <= m) {
....
}
However, in the 'next' case this still does not solve it. What should happen in the second loop when an 'm' value is entered for which no element yet exists in the ArrayList?
Why do you need to enter sentences in two loops?
What is the logic supposed to achieve exactly?

How to efficiently implement Eratosphenes method to generate prime numbers?

I use the following components in my code:
A byte array, each bit representing whether the correspondent number is prime(0) or not(1)
A recursion of Filtering.filter()
I want to ascertain whether these parts make it more efficient or actually slow it down. Any other advices also appreciated.
Code:
import java.lang.Math;
import java.util.*;
class Container{
public final byte[] binary_array;
private final int bit_length;
public Container(int nominal_bit_length){
int byte_length = (int)Math.ceil(nominal_bit_length / 8.0);
this.binary_array = new byte[byte_length];
this.bit_length = 8 * byte_length;
}
private String toBinaryString(int index){//convert into a binary string the byte value on which the bit number refered by the index exists
int byte_index = index / 8;
//System.out.println(index);
String str = Integer.toBinaryString(this.binary_array[byte_index]);
String formatted = ("00000000" + str).substring(str.length());
return formatted;
}
public char get(int index){
String str = this.toBinaryString(index);
return str.charAt(index % 8);//
}
public char set(int index, char value){
StringBuilder str = new StringBuilder(this.toBinaryString(index));
char temp = str.charAt(index % 8);//
str.setCharAt(index % 8, value);//
int byte_index = index / 8;
this.binary_array[byte_index] = (byte)Integer.parseUnsignedInt(str.toString(), 2);
return temp;
}
public int length(){
return this.bit_length;
}
public static Container preset(){
Container c = new Container(8);
c.set(1-1, '1');
c.set(4-1, '1');
c.set(6-1, '1');
c.set(8-1, '1');
return c;
}
}
class Screener{
private static void filterMultiplesOf(int num, Container container){
if (num == 1){
return;
}
int i = 2;
while ((i * num - 1) < container.length()){
container.set(i * num - 1, '1');
i++;
}
}
public static void filter(Container c){
int num = c.length();
if (num <= 8){
c = Container.preset();
} else{
Container base = new Container((int)Math.floor(Math.sqrt(num)));
filter(base);
for (int i = 0; i < base.length(); i++){
if (base.get(i) == '0'){
filterMultiplesOf(i+1, c);
}
}
}
}
}
public class Prime2{
public static void main(String[] args){
Scanner reader = new Scanner(System.in);
int num = reader.nextInt();
Container c = new Container(num);
Screener.filter(c);
for (int i = 1; i < c.length(); i++){
if (c.get(i) == '0'){
System.out.print((i + 1) + " ");
}
}
}
}
Edit at 12-03-2014:
What about this segment code?
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class PrimeGenerator {
public static Set<Integer> prime(int num){
if (num <= 2){
Set<Integer> foo = new HashSet<>();
foo.add(2);
return foo;
}
IntStream stream = IntStream.rangeClosed(1, num);
Set<Integer> base = prime((int)Math.ceil(Math.sqrt(num)));
IntStream multiples = base.stream().flatMapToInt((factor) -> (IntStream.rangeClosed(2, (int)Math.floorDiv(num, factor)).map(n -> n * factor)));
Set<Integer> primeset = stream.collect(HashSet::new, HashSet::add, HashSet::addAll);
Set<Integer> nonprimeset = multiples.collect(HashSet::new, HashSet::add, HashSet::addAll);
primeset.removeAll(nonprimeset);
primeset.remove(1);
return primeset;
}
public static void main(String[] args) {
// TODO code application logic here
prime(100000).stream().map(num -> num + " ").forEach(System.out::print);
}
}
as well as this:
import java.lang.Math;
import java.util.*;
/**
* Variation of BitSet which does NOT interpret the highest bit synonymous with
* its length.
*
* #author casper.bang#gmail.com
*/
class FixedBitSet extends BitSet{
int fixedLength;
public FixedBitSet(int fixedLength){
super(fixedLength);
this.fixedLength = fixedLength;
}
#Override
public int length() {
return fixedLength;
}
}
class Screener{
private static FixedBitSet preset;
static{
preset = new FixedBitSet(4);
preset.set(1-1, true);
preset.set(4-1, true);
}
private static void filterMultiplesOf(int num, FixedBitSet bitset){
//System.out.println("--------");
if (num == 1){
return;
}
int i = 2;
while ((i * num - 1) < bitset.length()){
bitset.set(i * num - 1, true);
i++;
}
}
public static void filter(FixedBitSet bitset){
//System.out.println("--------");
int num = bitset.length();
if (num <= 4){
//System.out.println("--------");
bitset = preset;
} else{
FixedBitSet base = new FixedBitSet((int)Math.floor(Math.sqrt(num)));
filter(base);
for (int i = 0; i < base.length(); i++){
if(!base.get(i)){
filterMultiplesOf(i + 1, bitset);
}
}
}
}
}
public class Prime3{
public static void main(String[] args){
Scanner reader = new Scanner(System.in);
int num = reader.nextInt();
FixedBitSet bs = new FixedBitSet(num);
// System.out.println(bs.length());
Screener.filter(bs);
for (int i = 1; i < bs.length(); i++){
if(!bs.get(i)){
System.out.print((i + 1) + " ");
}
}
}
}
Your "efficient" usage of a byte array is immaterial to the bad performance of your code, which uses string building to implement getting and setting.
Instead write code which uses low-level bit-manipulation operators (such as ~, &, and |) to implement get and set.
If you're not up to that, then consider using BitSet, a JDK-provided class which serves the same purpose.
If you want to learn how it's done, then simply open BitSet's source code.

Loop in Credit Card Validation in java

I am a high school student in an introductory Computer Science course. Our assignment was the following:
The last digit of a credit card number is the check digit, which protects against transcription errors such as an error in a single digit or switching two digits. the following method is used to verify actual credit card numbers but, for simplicity, we will describe it for numbers with 8 digits instead of 16:
Starting from the rightmost digit, form the sum of every other digit. For example, if the credit card number is 4358 9795, then you form the sum 5+7+8+3 = 23.
Double each of the digits that were not included in the preceding step. Add all the digits of the resulting numbers. For example, with the numbers given above, doubling the digits, starting with the next-to-last one, yields 18 18 10 8. Adding all the digits in these values yields 1+8+1+8+1+0+8=27.
Add the sums of the two preceding steps. If the last digit of the result is 0, the number is valid. In our case, 23 + 27 = 50, so the number is valid.
Write a program that implements this algorithm. The user should supply an 8-digit number, and you should print out whether the number is valid or not. If it is not valid, you should print out the value of the check digit that would make the number valid.
I have everything done except for the part in bold. My code is listed below:
public class CreditCard
{
private String creditCardNumber;
private boolean valid;
private int checkDigit;
int totalSum;
/**
* Constructor for objects of class CreditCard
*/
public CreditCard(String pCreditCardNumber)
{
creditCardNumber = pCreditCardNumber;
checkDigit = Integer.parseInt(pCreditCardNumber.substring(creditCardNumber.length() - 1));
int sumOfDigits = checkDigit + Integer.parseInt(pCreditCardNumber.substring(6,7)) + Integer.parseInt(pCreditCardNumber.substring(3,4)) + Integer.parseInt(pCreditCardNumber.substring(1,2));
int dig7 = Integer.parseInt(pCreditCardNumber.substring(7,8));
int dig5 = Integer.parseInt(pCreditCardNumber.substring(5,6));
int dig3 = Integer.parseInt(pCreditCardNumber.substring(2,3));
int dig1 = Integer.parseInt(pCreditCardNumber.substring(0,1));
String string7 = Integer.toString(dig7);
int doubledDig7a = Integer.parseInt(string7.substring(0));
int doubledDig7b = 0;
if (dig7 * 2 >= 10)
{
doubledDig7a = Integer.parseInt(string7.substring(0));
doubledDig7b = 0;
}
String string5 = Integer.toString(dig5);
int doubledDig5a = Integer.parseInt(string7.substring(0));
int doubledDig5b = 0;
if (dig5 * 2 >= 10)
{
doubledDig5a = Integer.parseInt(string5.substring(0));
doubledDig5b = 0;
}
String string3 = Integer.toString(dig3);
int doubledDig3a = Integer.parseInt(string3.substring(0));
int doubledDig3b = 0;
if (dig3 * 2 >= 10)
{
doubledDig3a = Integer.parseInt(string3.substring(0));
doubledDig3b = 0;
}
String string1 = Integer.toString(dig1);
int doubledDig1a = Integer.parseInt(string1.substring(0));
int doubledDig1b = 0;
if (dig1 * 2 >= 10)
{
doubledDig1a = Integer.parseInt(string1.substring(0));
doubledDig1b = 0;
}
int doubleDigits = doubledDig1a + doubledDig1b + doubledDig3a + doubledDig3b + doubledDig5a + doubledDig5b + doubledDig7a + doubledDig7b;
totalSum = sumOfDigits + doubleDigits;
if (totalSum % 10 == 0)
{
valid = true;
}
else
{
valid = false;
}
}
public void makeItValid()
{
while (totalSum % 10 != 0)
{
checkDigit--;
if (totalSum % 10 == 0)
{
break;
}
}
}
public boolean isItValid()
{
return valid;
}
}
The loop is what I am having issues with. I always end up in an infinite loop whenever it compiles. It looks like everything should work, though. It's supposed to decrease the value of the check Digit (not increase so I don't end up with a check digit of 10 or higher), and then add that number back into the total sum until the total sum is divisible by 10, and then the loop would end. Is the type of loop I'm using wrong? Any advice would be appreciated.
Your problem is that both of your loop conditions involve totalSum but you only change checkDigit.
while (totalSum % 10 != 0)
{
checkDigit--;
if (totalSum % 10 == 0)
{
break;
}
}
You either need to recalculate totalSum or change the condition to be based on checkDigit. If you want to loop and decrement like you are doing you will need to add a method that performs the algorithm and call it every time. The way you have your class outlined makes this very inconvenient because you don't convert the numbers.
public static int[] cardToNumbers(String cardText) {
// \D is regex for non-digits
cardText = cardText.replaceAll("\\D", "");
int[] cardNumbers = new int[cardText.length()];
// convert unicode to corresponding integers
for (int i = 0; i < cardText.length(); i++)
cardNumbers[i] = cardText.charAt(i) - '0';
return cardNumbers;
}
public static int calcTotalSum(int[] cardNumbers) {
int sum = 0;
/* "every other one" loops
*
* I recommend against the "mod 2 index" scheme
* i % 2 relies on the card number being even
* you can't have your code blow up with unusual inputs
*
*/
for (int i = cardNumbers.length - 1; i >= 0; i -= 2) {
sum += cardNumbers[i];
}
for (int i = cardNumbers.length - 2; i >= 0; i -= 2) {
int dig = cardNumbers[i] * 2;
while (dig > 0) {
sum += dig % 10;
dig /= 10;
}
}
return sum;
}
Now you can do something like:
public void makeItValid() {
int[] invalidNumbers = cardToNumbers(creditCardNumber);
int sum = calcTotalSum(invalidNumbers);
while ((sum = calcTotalSum(invalidNumbers)) % 10 != 0)
invalidNumbers[invalidNumbers.length - 1]--;
totalSum = sum;
checkDigit = invalidNumbers[invalidNumbers.length - 1];
}
But you should be able to just subtract the difference to find the valid check digit:
if (totalSum % 10 != 0) checkDigit -= totalSum % 10;
Or something like:
public void makeItValid() {
int[] invalidNumbers = cardToNumbers(creditCardNumber);
checkDigit = invalidNumbers[invalidNumbers.length - 1] -= totalSum % 10;
totalSum = calcTotalSum(invalidNumbers);
valid = true;
}
Some asides,
I would recommend storing the digits as a field and have checkDigit represent an index in the array. This would simplify some of the operations you are doing.
I would also suggest not to be "silently" changing fields internally IE like in your makeItValid method unless this is a specification of the assignment. I think a better form is to let the "owning" code make the changes itself which is more clear externally. A somewhat complete implementation would look like this:
public class CreditCard {
public static void main(String[] args) {
if (args.length == 0) return;
CreditCard card = new CreditCard(args[0]);
if (!card.isValidNumber()) {
card.setCheckDigit(card.getValidCheckDigit());
}
}
private final String cardText;
private final int[] cardDigits;
private final int cdIndex;
public CreditCard(String ct) {
cardDigits = cardToNumbers(cardText = ct);
if ((cdIndex = cardDigits.length - 1) < 0) {
throw new IllegalArgumentException("# had no digits");
}
}
public boolean isValidNumber() {
return calcTotalSum(cardDigits) % 10 == 0;
}
public void setCheckDigit(int dig) {
cardDigits[cdIndex] = dig;
}
public int getValidCheckDigit() {
int sum = calcTotalSum(cardDigits);
if (sum % 10 != 0) {
return cardNumbers[cdIndex] - sum % 10;
} else {
return cardNumbers[cdIndex];
}
}
// above static methods
}
The best form IMO would be to disallow creation of a credit card object at all unless the check digit is valid. As an OOP principle it should not make sense to create invalid credit cards. The constructor should throw an exception if the card is invalid and have a static method to correct the number.
I would do something like the following (shortened):
public class CreditCard {
public CreditCard(String number) {
if (!validateCheckDigit(number)) {
throw new IllegalArgumentException("check digit failure");
}
}
}
public static void main(String[] args) {
String number = args[0];
CreditCard card = null;
boolean valid = false;
do {
try {
card = new CreditCard(number);
valid = true;
} catch (IllegalArgumentException e) {
number = CreditCard.correctCheckDigit(number);
}
} while (!valid);
}
I guess that's more or less doing your homework for you but I'm sure you can learn from it.
Unless I'm missing something major on how the validation works your makeitvalid method wont work in the way you are approaching it.
It makes more sense (at least to me) to extract everything you have in your constructor into a method ie.
boolean isValid(String cardNumber);
which would do everything that your constructor does except set the valid flag. your constructor then becomes
public CreditCard(String pCreditCardNumber){
valid = isValid(pCreditCardNumber);
}
and then to find what change would make it valid your check valid method does something like
change the value of check digit
if (isValid(Changed String))
return checkdigit
else
continue
repeat until you either find one that works or until you determine that it can't work.
Something along these lines should do. You'll still need to implement a few methods on your own.
public static void main(String[] args) {
String creditCardNumber = readCreditCardNumber();
String correctCreditCardNumber = getCorrectCreditCardNumber(creditCardNumber);
if (creditCardNumber.equals(correctCreditCardNumber)) {
System.out.println("Credit Card Valid");
} else {
System.out.println("Credit Card Invalid. Did you mean " + correctCreditCardNumber + "?");
}
}
public static String getCorrectCreditCardNumber(String creditCardNumber) {
int[] creditCardDigits = getCreditCardDigits(creditCardNumber);
int sum = 0;
for (int i = creditCardDigits.length - 2; i >= 0; i--) {
if (isOdd(i)) {
sum += creditCardDigits[i];
} else {
sum += digitSum(creditCardDigits[i] * 2);
}
}
int last = creditCardDigits.length - 1;
int remainder = sum % 10;
if (remainder != 0) {
creditCardDigits[last] = 10 - remainder;
}
return getCreditCardNumberAsString(creditCardDigits);
}
This program is very dynamic. I did not add too much error handling. You can enter any number that is divisible by 8.
Code in action:
Enter a card number: 4358 9795
Number is valid?: true
Continue? (y/n): y
Enter a card number: 4358 9796
Number is valid?: false
Continue? (y/n): y
Enter a card number: 43-58 97-95
Number is valid?: true
Continue? (y/n): n
Exiting...
CreditCardValidator.java
import java.text.ParseException;
import java.util.Scanner;
public class CreditCardValidator {
Integer[] digits;
public CreditCardValidator(String numberSequence) {
parseNumber(numberSequence);
}
private void parseNumber(String numberSequence) {
try {
String sequence = numberSequence.replaceAll("[\\s-]+", "");
int length = sequence.length();
if (length % 8 != 0) {
throw new IllegalArgumentException("Number length invalid.");
}
digits = new Integer[length];
int pos = 0;
for (Character c : sequence.toCharArray()) {
if (Character.isDigit(c)) {
digits[pos++] = Character.getNumericValue(c);
} else {
throw new ParseException("Invalid digit.", pos);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private boolean validateNumber() {
int sum = 0;
for (int i = digits.length - 1; i >= 0; i--) {
if (i % 2 == 1) {
sum += digits[i];
} else {
sum += NumberUtils.sumDigits(digits[i] * 2);
}
}
return sum % 10 == 0;
}
public static void main(String[] args) {
boolean stop = false;
CreditCardValidator c;
while (!stop) {
System.out.print("Enter a card number: ");
c = new CreditCardValidator(new Scanner(System.in).nextLine());
System.out.println("Number is valid?: " + c.validateNumber());
System.out.print("\nContinue? (y/n): ");
if (new Scanner(System.in).next().charAt(0) == 'n') {
stop = true;
}
System.out.println();
}
System.out.println("Exiting...");
System.exit(0);
}
}
I wrote a separate digit summation utility:
public class NumberUtils {
public static void main(String[] args) {
for(int i = 0; i < 2000; i+=75) {
System.out.printf("%04d: %02d\n", i, sumDigits(i));
}
}
public static int sumDigits(int n) {
if (n < 0)
return 0;
return sumDigitsRecursive(n, 0);
}
private static int sumDigitsRecursive(int n, int total) {
if (n < 10)
return total + n;
else {
return sumDigitsRecursive(n / 10, total + (n % 10));
}
}
}

Uva's 3n+1 problem

I'm solving Uva's 3n+1 problem and I don't get why the judge is rejecting my answer. The time limit hasn't been exceeded and the all test cases I've tried have run correctly so far.
import java.io.*;
public class NewClass{
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
int maxCounter= 0;
int input;
int lowerBound;
int upperBound;
int counter;
int numberOfCycles;
int maxCycles= 0;
int lowerInt;
BufferedReader consoleInput = new BufferedReader(new InputStreamReader(System.in));
String line = consoleInput.readLine();
String [] splitted = line.split(" ");
lowerBound = Integer.parseInt(splitted[0]);
upperBound = Integer.parseInt(splitted[1]);
int [] recentlyused = new int[1000001];
if (lowerBound > upperBound )
{
int h = upperBound;
upperBound = lowerBound;
lowerBound = h;
}
lowerInt = lowerBound;
while (lowerBound <= upperBound)
{
counter = lowerBound;
numberOfCycles = 0;
if (recentlyused[counter] == 0)
{
while ( counter != 1 )
{
if (recentlyused[counter] != 0)
{
numberOfCycles = recentlyused[counter] + numberOfCycles;
counter = 1;
}
else
{
if (counter % 2 == 0)
{
counter = counter /2;
}
else
{
counter = 3*counter + 1;
}
numberOfCycles++;
}
}
}
else
{
numberOfCycles = recentlyused[counter] + numberOfCycles;
counter = 1;
}
recentlyused[lowerBound] = numberOfCycles;
if (numberOfCycles > maxCycles)
{
maxCycles = numberOfCycles;
}
lowerBound++;
}
System.out.println(lowerInt +" "+ upperBound+ " "+ (maxCycles+1));
}
}
Are you making sure to accept the entire input? It looks like your program terminates after reading only one line, and then processing one line. You need to be able to accept the entire sample input at once.
I faced the same problem. The following changes worked for me:
Changed the class name to Main.
Removed the public modifier from the class name.
The following code gave a compilation error:
public class Optimal_Parking_11364 {
public static void main(String[] args) {
...
}
}
Whereas after the changes, the following code was accepted:
class Main {
public static void main(String[] args) {
...
}
}
This was a very very simple program. Hopefully, the same trick will also work for more complex programs.
If I understand correctly you are using a memoizing approach. You create a table where you store full results for all the elements you have already calculated so that you do not need to re-calculate results that you already know (calculated before).
The approach itself is not wrong, but there are a couple of things you must take into account. First, the input consists of a list of pairs, you are only processing the first pair. Then, you must take care of your memoizing table limits. You are assuming that all numbers you will hit fall in the range [1...1000001), but that is not true. For the input number 999999 (first odd number below the upper limit) the first operation will turn it into 3*n+1, which is way beyond the upper limit of the memoization table.
Some other things you may want to consider are halving the memoization table and only memorize odd numbers, since you can implement the divide by two operation almost free with bit operations (and checking for even-ness is also just one bit operation).
Did you make sure that the output was in the same order specified in the input. I see where you are swapping the input if the first input was higher than the second, but you also need to make sure that you don't alter the order it appears in the input when you print the results out.
ex.
Input
10 1
Output
10 1 20
If possible Please use this Java specification : to read input lines
http://online-judge.uva.es/problemset/data/p100.java.html
I think the most important thing in UVA judge is 1) Get the output Exactly same , No Extra Lines at the end or anywhere . 2) I am assuming , Never throw exception just return or break with No output for Outside boundary parameters.
3)Output is case sensitive 4)Output Parameters should Maintain Space as shown in problem
One possible solution based on above patterns is here
https://gist.github.com/4676999
/*
Problem URL: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=36
Home>Online Judge > submission Specifications
Sample code to read input is from : http://online-judge.uva.es/problemset/data/p100.java.html
Runtime : 1.068
*/
import java.io.*;
import java.util.*;
class Main
{
static String ReadLn (int maxLg) // utility function to read from stdin
{
byte lin[] = new byte [maxLg];
int lg = 0, car = -1;
String line = "";
try
{
while (lg < maxLg)
{
car = System.in.read();
if ((car < 0) || (car == '\n')) break;
lin [lg++] += car;
}
}
catch (IOException e)
{
return (null);
}
if ((car < 0) && (lg == 0)) return (null); // eof
return (new String (lin, 0, lg));
}
public static void main (String args[]) // entry point from OS
{
Main myWork = new Main(); // create a dinamic instance
myWork.Begin(); // the true entry point
}
void Begin()
{
String input;
StringTokenizer idata;
int a, b,max;
while ((input = Main.ReadLn (255)) != null)
{
idata = new StringTokenizer (input);
a = Integer.parseInt (idata.nextToken());
b = Integer.parseInt (idata.nextToken());
if (a<b){
max=work(a,b);
}else{
max=work(b,a);
}
System.out.println (a + " " + b + " " +max);
}
}
int work( int a , int b){
int max=0;
for ( int i=a;i<=b;i++){
int temp=process(i);
if (temp>max) max=temp;
}
return max;
}
int process (long n){
int count=1;
while(n!=1){
count++;
if (n%2==1){
n=n*3+1;
}else{
n=n>>1;
}
}
return count;
}
}
Please consider that the integers i and j must appear in the output in the same order in which they appeared in the input, so for:
10 1
You should print
10 1 20
package pandarium.java.preparing2topcoder;/*
* Main.java
* java program model for www.programming-challenges.com
*/
import java.io.*;
import java.util.*;
class Main implements Runnable{
static String ReadLn(int maxLg){ // utility function to read from stdin,
// Provided by Programming-challenges, edit for style only
byte lin[] = new byte [maxLg];
int lg = 0, car = -1;
String line = "";
try
{
while (lg < maxLg)
{
car = System.in.read();
if ((car < 0) || (car == '\n')) break;
lin [lg++] += car;
}
}
catch (IOException e)
{
return (null);
}
if ((car < 0) && (lg == 0)) return (null); // eof
return (new String (lin, 0, lg));
}
public static void main(String args[]) // entry point from OS
{
Main myWork = new Main(); // Construct the bootloader
myWork.run(); // execute
}
public void run() {
new myStuff().run();
}
}
class myStuff implements Runnable{
private String input;
private StringTokenizer idata;
private List<Integer> maxes;
public void run(){
String input;
StringTokenizer idata;
int a, b,max=Integer.MIN_VALUE;
while ((input = Main.ReadLn (255)) != null)
{
max=Integer.MIN_VALUE;
maxes=new ArrayList<Integer>();
idata = new StringTokenizer (input);
a = Integer.parseInt (idata.nextToken());
b = Integer.parseInt (idata.nextToken());
System.out.println(a + " " + b + " "+max);
}
}
private static int getCyclesCount(long counter){
int cyclesCount=0;
while (counter!=1)
{
if(counter%2==0)
counter=counter>>1;
else
counter=counter*3+1;
cyclesCount++;
}
cyclesCount++;
return cyclesCount;
}
// You can insert more classes here if you want.
}
This solution gets accepted within 0.5s. I had to remove the package modifier.
import java.util.*;
public class Main {
static Map<Integer, Integer> map = new HashMap<>();
private static int f(int N) {
if (N == 1) {
return 1;
}
if (map.containsKey(N)) {
return map.get(N);
}
if (N % 2 == 0) {
N >>= 1;
map.put(N, f(N));
return 1 + map.get(N);
} else {
N = 3*N + 1;
map.put(N, f(N) );
return 1 + map.get(N);
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
while(scanner.hasNextLine()) {
int i = scanner.nextInt();
int j = scanner.nextInt();
int maxx = 0;
if (i <= j) {
for(int m = i; m <= j; m++) {
maxx = Math.max(Main.f(m), maxx);
}
} else {
for(int m = j; m <= i; m++) {
maxx = Math.max(Main.f(m), maxx);
}
}
System.out.println(i + " " + j + " " + maxx);
}
System.exit(0);
} catch (Exception e) {
}
}
}

Categories

Resources