My ta told me that if i want to count the length of a long variable I can create a method using modulos. From what I understood he was saying that i need to keep using modulos until the long is 0. Here's what I'm thinking right now, but i'm pretty lost.
public static int inputSize(long cc_num)
{
int count = 0;
while( cc_num > 0)
{
count += 1;
cc_num = cc_num % 10;
}
}
That's almost correct.
Just replace the % operator with / operator:
cc_num /= 10;
That should work :)
Here is your code with minor changes:
public static boolean validSize(long cc_num) {
int count = 0;
if (cc_num < 0) cc_num *= -1; // fix negative number
while (cc_num > 0) {
count++;
cc_num = cc_num / 10;
}
//checks if length of long is correct
return count == 15 || count == 16;
}
Let me know if this works for you.
If you want to limit the number of possible comparisons:
public static int inputSize(long cc_num)
{
if(cc_num < 0) // check for negative numbers
cc_num = -cc_num;
int count = 1;
if(cc_num >= 10000000000000000L)
{
count += 16;
cc_num /= 10000000000000000L;
}
if(cc_num >= 100000000)
{
count += 8;
cc_num /= 100000000;
}
if(cc_num >= 10000)
{
count += 4;
cc_num /= 10000;
}
if(cc_num >= 100)
{
count += 2;
cc_num /= 100;
}
if(cc_num >= 10)
{
count ++;
}
return count;
}
Related
I have an assignment where i get an number input from the user, for example : "57779227"
and i need to return the longest sequence of identical numbers. For this example, the longest sequence is "777" and the return should be 3 (as the amount of times the number "7" is in a row.
So far I wrote an iteration method.
***No loops to be used in this method, ONLY RECURSION. ***
Iteration example :
public static int maxSequence(int num) {
int max = 1; //initiate
int currentCount = 1;
int prevDigit = 11;//Because num%10 != 11 Always!
int currentDigit;
while (num!=0) {
currentDigit = num%10;
if (prevDigit == currentDigit)
currentCount++;
else if (currentCount > max)
max = currentCount;
if (prevDigit != currentDigit) //initiate for the next Iteration
currentCount = 1;
prevDigit = currentDigit;
num = num/10;
}
return max;
}
When previousDigit != currentDigit then a new count will be start
public static int maxSequence(int num) {
int previousMax = 1;
int currentMax = 1;
int previousDigit = num % 10;
num /= 10;
while (num != 0) {
int currentDigit = num % 10;
if (previousDigit == currentDigit) {
currentMax++;
} else {
if (previousMax < currentMax) {
previousMax = currentMax;
}
currentMax = 1;
previousDigit = currentDigit;
}
num /= 10;
}
return Math.max(currentMax, previousMax);
}
I built 2 methods 1 get a number's digits, the 2nd sums all the digits of the number. It works , but for some reason when i type the number 11111 or higher it returns a wrong result.
For ex. the number 11111 returns 3 instead of 5
public class test_2 {
public static int getDigits(int x) {
int counter = 0;
while (x > 0) {
x /= 10;
counter++;
}
return counter;
}
public static int getNumber(int y) {
int New = 0;
for (int i = 0; i <= test_2.getDigits(y); i++) {
New += (y % 10);
y /= 10;
if (y < 10 && y > 0)
New += (y % 10);
}
return New;
}
}
There are multiple issues with your code, Follow below
test_2.getDigits(y) changes in each iteration of the loop, since y keeps changing
if (y < 10 && y > 0) condition is not necessary
The following will work:
public static int getNumber(int y) {
int New = 0;
for (int i = 0, len = getDigits(y); i < len; i++) {
New += (y % 10);
y /= 10;
}
return New;
}
Or simply:
public static int getNumber(int y) {
int New = 0;
while (y > 0) {
New += (y % 10);
y /= 10;
}
return New;
}
I wanted to use a for and a while loop to obtain the prime factors of a number. My while loop example works fine which I have posted below my for loop example. However, my for loop does not work, and i am guessing that I can't use a continue in the same manner that I used it in the while loop. If this is true, then how would I accomplish this. I have not been able to find a basic beginners example of this using a for loop. Thanks
// My getting largest prime factor using a for loop
public class LargestPrime{
public static void main(String[] args) {
int number = 36;
int largestPrime = 0;
for ( int i = 2; i <= number; i++){
if (number % i == 0){
largestPrime = i;
number /= i;
continue;
}
System.out.println(" largest prime = " + i);
}
}
}
//*******************************************************************
//*******************************************************************
public class LargestPrime {
// gettting largest prime using a while loop
public static int getLargestPrime(int number) {
if (number <= 1) {
return -1;
}
int largestPrime = 0;
int count = 2;
while (count <= number) {
if (number % count == 0) {
largestPrime = count;
number = number / count;
continue;
}
count++;
}
return largestPrime;
}
}
The problem is that continue in a for loop executes the update part (i++), which your while loop didn't.
The other problem is that you're printing inside the loop.
There are multiple way to fix this:
Do i-- before continue, so it evens out to nothing with the i++. This is a fairly common way to handle this.
Since you don't have any code after the if statement, you don't need the continue.
for (int i = 2; i <= number; i++) {
if (number % i == 0) {
largestPrime = i;
number /= i;
i--; // to retry same `i` value
}
}
Do the i++ "yourself", i.e. not as part of for loop:
for (int i = 2; i <= number; ) {
if (number % i == 0) {
largestPrime = i;
number /= i;
continue;
}
i++;
}
Or:
for (int i = 2; i <= number; ) {
if (number % i == 0) {
largestPrime = i;
number /= i;
} else {
i++;
}
}
Use a while loop inside the for loop:
for (int i = 2; i <= number; i++) {
while (number % i == 0) {
largestPrime = i;
number /= i;
}
}
That can be shortened to:
for (int i = 2; i <= number; i++)
for (; number % i == 0; number /= i)
largestPrime = i;
Though rather than assign largestPrime repeatedly, you could do this:
for (int i = 2; i <= number; i++) {
if (number % i == 0) {
largestPrime = i;
do {
number /= i;
} while (number % i == 0);
}
}
I currently have a program to find the prime factorisation of a given number; works fine with smaller numbers, but it takes ages for anything over a million. My code is extremely inefficient, finding all prime numbers below the input and checking which ones divide without a remainder. I don't know how to make it less inefficient, any help?
static ArrayList<Integer> primeNumbersBelow(long n) {
ArrayList<Integer> ay = new ArrayList<Integer>();
ay.add(2);
for(int i = 3; i < ((n % 2 != 0) ? (n + 1) / 2 : n / 2); i++) {
boolean divides = false;
for(int j = 2; j < i; j++) {
if(i % j == 0) {
divides = true;
}
}
if(!divides) {
ay.add(i);
System.out.println(i);
}
}
return ay;
}
static ArrayList<Integer> primeFactorisationOf() {
ArrayList<Integer> ay = new ArrayList<Integer>();
ArrayList<Integer> aay = primeNumbersBelow(input);
long n = input;
for(int i = 0, len = aay.size(); i < len; i++) {
int f = aay.get(i);
boolean run = true;
while(run) {
if(n % f == 0) {
ay.add(f);
n /= f;
} else {
run = false;
}
}
}
return ay;
}
From Mr Lars Vogel # vogella...
public static List<Integer> primeFactors(int number) {
int n = number;
List<Integer> factors = new ArrayList<Integer>();
for (int i = 2; i <= n; i++) {
while (n % i == 0) {
factors.add(i);
n /= i;
}
}
return factors;
}
Sticking to your general algorithm and not re-writing your primesBelow(..) method: I would say:
Once divides = true, you can break out of the for-loop
The complex for loop termination condition for primality check can be reduced to the Math.sqrt(n) - I won't go through the math, but you can look that up yourself.
One way to improve the code is to remove the IO inside your loop structure.
That is,
static ArrayList<Integer> primeNumbersBelow(long n) {
ArrayList<Integer> ay = new ArrayList<Integer>();
ay.add(2);
for(int i = 3; i < ((n % 2 != 0) ? (n + 1) / 2 : n / 2); i++) {
boolean divides = false;
for(int j = 2; j < i; j++) {
if(i % j == 0) {
divides = true;
}
}
if(!divides) {
ay.add(i);
//REMOVE THE FOLLOWING LINE
System.out.println(i);
}
}
return ay;
}
I'm sure you'll see a huge performance boost just from that alone.
I have been having trouble on Problem 14 on Project Euler. I don't understand why my code(Java) isn't working and any help would be appreciated.
public class Calculate {
public static void main(String[] args){
System.out.println(calc());
}
public static int calc(){
int max = 0;
int maxI = 0;
for (int i = 0; i < 1000000; i++){
if (seqLen(i) >= max){
max = seqLen(i);
maxI = i;
}
}
return maxI;
}
public static int seqLen(int seed){
if (seed <= 0) return 0;
if (seed == 1) return 1;
int len = 1;
if (seed % 2 == 0){
len += seqLen(seed/2);
}
else{
len += seqLen((3*seed)+1);
}
return len;
}
}
Thanks!
You run into an overflow with your int variables.
The maximum number appearing in this computation (when using a brute force approach) is 56991483520.
Java's int maximum value is 2^31-1 == 2147483647, which is obviously smaller.
So change your variables etc to use long. Here the max value is 2^63-1 == 9223372036854775807, which will be fitting for all values.
You are breaking the int limit.
Using long:
public static long calc() {
long max = 0;
long maxI = 0;
for (long i = 0; i < 1000000; i++) {
long len = seqLen(i);
if (len >= max) {
max = len;
maxI = i;
}
}
return maxI;
}
public static long seqLen(long seed) {
if (seed <= 0) {
return 0;
}
if (seed == 1) {
return 1;
}
long len = 1;
if (seed % 2 == 0) {
len += seqLen(seed / 2);
} else {
len += seqLen((3 * seed) + 1);
}
return len;
}
public void test() {
System.out.println(seqLen(13));
System.out.println(calc());
}
Gives you the correct result of 837799.
Note that there are better/more efficient algorithms than this one.
Actually, you don't have to check from 1 to 499999.
You only need to check from 500000 to 999999
because the next step of any even number between 500000 and 999999
is going to be some integer from 1 to 499999.
That means that an integer from 1 to 499999 cannot be the answer.
So change the for loop to the following
for (int i = 500000; i < 1000000; i++) {
}
And "i" doesn't have to be long
while "seed" has to be long.