Project Euler 14 Java - java

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.

Related

How can I swap 2 digits (i,j) from a n number?

basically i have an integer n = 23456 and i want to swap the second and fourth digit, so i = 2 and j = 4. So the output would be 25436. I canĀ“t use any Java class, so I supose that one of the ways to do it is by divide the number on powers of 10 and keep the rest on a new variable.
this is what i have so far:
public static int powerOfTen(int n) {
int p = 10;
while(n-1 > 0) {
p = p*10;
n--;
}
return p;
}
public static int swapNum(int n, int i, int j) {
int swap = 1;
int count = numDigits(n);
int digit1 = nDigit(n, i);
int digit2 = nDigit(n, j);
if(i > j) {
swap = n/powerOfTen(i);
int rest = n%powerOfTen(i);
rest = rest/10;
swap = swap*powerOfTen(i);
}
}
Here's your code with some modifications:
public class Main
{
// Count the number of digits in an integer
static int numDigits(int n)
{
if (n == 0) return 1;
int count = 0;
while (n != 0) {
count++;
n /= 10;
}
return count;
}
// Reverse an integer
static int reverseNumber(int n)
{
int result = 0;
while (n != 0) {
result = result * 10 + n % 10;
n /= 10;
}
return result;
}
// Get the nth digit - from the left
static int nDigit(int n, int index)
{
n = reverseNumber(n);
for (int i = 0; i < index; i++) {
n /= 10;
}
return n % 10;
}
static int swapNum(int n, int i, int j)
{
// Make indexes 0-based
i = i - 1;
j = j - 1;
int count = numDigits(n);
int digit1 = nDigit(n, i);
int digit2 = nDigit(n, j);
int result = 0;
for (int k = count - 1; k >= 0; --k) {
int digit;
// Get the correct digit, i, j, or current
if (k == i) digit = digit2;
else if (k == j) digit = digit1;
else digit = n % 10;
result = result * 10 + digit;
n /= 10;
}
return reverseNumber(result);
}
public static void main(String[] args) {
System.out.println(swapNum(12345678 , 4, 5));
}
}
You can't use any class? what about convert number to char array, swap and parse it back?
// helper function to convert char array to int
public static int parseInt(char[] chars) {
int result = 0; // accumulator
int idx_value = 1; // power of ten counter
for (int i = chars.length - 1; i >= 0; i--) { // loop from tail to head
// char - '0' mean it will convert '0' to 0 and '1' will be 1 so on.
result += (chars[i] - '0') * idx_value;
idx_value *= 10;
}
return result;
}
public static int swapNum(int n, int i, int j) {
// convert number to char array
char[] chars = ("" + n).toCharArray();
// use zero based index
i-=1;j-=1;
// perform swap
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
// convert char array back to int
return parseInt(chars);
}

How to find sequence of identical numbers using recursion? -- Java

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

Large Number Power Method

I can't figure out why, but when the power function is used, it adds a (what seems to be random) integer into the middle of the answer. I can't figure out why, can any of you see anything unusual? Thanks
//multiplication method
public IntValue Multiply(IntValue multiplier) {
StringBuilder product = new StringBuilder();
int pos = 0;
for (int i = multiplier.getValue().length() - 1; i >= 0; i--) {
int currentPosition = pos++;
int carry = 0;
int multiplierDigit = Character.getNumericValue(multiplier.getValue().charAt(i));
for (int j = value.length() - 1; j >= 0; j--) {
int multiplicandDigit = Character.getNumericValue(value.charAt(j));
int tempProduct = currentPosition < product.length()
? Character.getNumericValue(product.charAt(currentPosition)) : 0;
int currentProduct = (multiplicandDigit * multiplierDigit) + carry + tempProduct;
if (currentProduct > 9) {
carry = currentProduct / 10;
currentProduct = currentProduct % 10;
}
if (currentPosition < product.length()) {
product.setCharAt(currentPosition, Character.forDigit(currentProduct, 10));
} else {
product.append(currentProduct);
}
++currentPosition;
}
if (carry > 0) {
if (currentPosition < product.length()) {
product.setCharAt(currentPosition, Character.forDigit(carry, 10));
} else {
product.append(carry);
}
}
}
return new IntValue(product.reverse().toString());
}
//number1 and number2 are IntValues.
//power method
public IntValue Power(long n) {
IntValue result = new IntValue("1");
for(int i = 0; i < n; i++) {
result = result.Multiply(this);
}
return result;
}
System.out.println("Result = "+number1.Power(Long.parseLong(number2.toString())));
Try the following code:
BigInteger number1 = new BigInteger("5");
System.out.println("Result = " + number1.pow(5).toString());
It's how we do it in java.
There is a library for working with powers in Java, namely Math.pow (for small numbers) and BigInteger pow (for arbitrary large numbers). Note that BigInteger power cannot compute fractional powers.
There are iterative DIY algorithms for fractional powers as well, for example
BigInteger sqrt(BigInteger n) {
BigInteger a = BigInteger.ONE;
BigInteger b = new BigInteger(n.shiftRight(5).add(new BigInteger("8")).toString());
while(b.compareTo(a) >= 0) {
BigInteger mid = new BigInteger(a.add(b).shiftRight(1).toString());
if(mid.multiply(mid).compareTo(n) > 0) b = mid.subtract(BigInteger.ONE);
else a = mid.add(BigInteger.ONE);
}
return a.subtract(BigInteger.ONE);
}

Way to get number of digits from a long using Modulos

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

Using iteration to work out powers

I'm basically trying to rewrite math.pow, I have the following obviously I'm not getting the concept of returning values. What exactly am I doing wrong?
public static int power(int x, int n)
{
if (n == 0) return 1;
int i,total;
for(i = 0; i < n-1 ;i++);
{
total = (x * total);
}
return total;
}
You need to initialize total to 1.
int total = 1;
You can just rewrite everything to:
public static int power(int x, int n)
{
int total = 1;
for(int i = 0; i < n; i++) // i can be declared here directly
{
total = (x * total);
}
return total; // total remains 1 if n = 0
}
public static int power(int x, int n)
{
int total = 1; // Initialized total to 1
for(int i = 0; i < n; i++)
{
total = x*total;
}
return total;
}
instead of i < n-1 you should use i <= n-1 or i < n and int total=1. hope it will work.
also remove ; from the for loop end. rewriting the code
public static int power(int x, int n){
int total=1;
for(int i = 0;i < n;i++)
total *= x;
return total;
}
For one, it looks like you meant:
if (n == 0) return 1;
check the power, not the base number.
You're not initialisign total either, using total = x would fix things i think.
The variable total starts at 0. So calling total = x*total will always be 0.
You need to initialize total to x.
Here is a solution with log(n) complexity instead of linear. Be careful with overflow though.
int pow(int x, int n) {
int res = 1;
while(n > 0) {
if(n % 2 == 1) {
res = res * x;
}
x = x * x;
n = n / 2;
}
return res;
}

Categories

Resources