/* This program converts decimal to binary */
import javax.swing.JOptionPane;
public class BinaryLoop {
public static void main(String []args) {
String askForDecimal = JOptionPane.showInputDialog("Enter the decimal number you would like to convert?");
int decimalNumber = Integer.parseInt(askForDecimal);
int remainder = 0;
for (int i = 1; decimalNumber > 0; i++) {
decimalNumber /= 2;
remainder = decimalNumber % 2;
System.out.print(remainder);
}
}
}
For example I type in 15 but it returns 1110 which should be 1111.
p.s. this the result will be read from right to left.
decimalNumber /= 2;
remainder = decimalNumber % 2;
These two lines should be in the opposite order. Can you see why?
You don't need the variable i in your for loop at all, just use a while loop.
There is a flaw in your algorithm because you are dividing first:
15 / 2 = 7
7 / 2 = 3
3 / 2 = 1
1 / 2 = 0
You need to check the remainder before dividing, not afterwards.
If you understand the intent of the program, you should see the problem if you output some of the intermediate workings:
int remainder = 0;
for (int i = 1; decimalNumber > 0; i++) {
System.out.println("Entering for() block");
System.out.println("decimalNumber=" + decimalNumber);
decimalNumber /= 2;
System.out.println("decimalNumber=" + decimalNumber);
remainder = decimalNumber % 2;
System.out.println(remainder);
}
}
Examine the output of this and the error should become obvious, which is that because two statements are the wrong way around, you're missing the first, biggest, value of decimalNumber.
You might also notice that remainder is not used outside the block, so you don't need to declare it outside the block, and you don't need to initialise it to zero.
Likewise, you might notice that the value of i is never used, so you could change the for loop to:
for(;decimalNumber > 0;)
... which is equivalent to:
while(decimalNumber > 0)
Many people get into the habit of putting temporary println statements in their code to debug. However it's a bad habit. Instead, learn to use a debugger as soon as you can. With a debugger you can pause a program and step through it line by line, looking at the values of all the variables as they change.
You need to do this:
String s = "";
Integer remainder = 0;
while(decimalNumber > 0) {
remainder = decimalNumber % 2;
decimalNumber /= 2;
s = remainder.toString() + s;
}
System.out.println(s);
you have to change the code to
remainder = decimalNumber % 2;
decimalNumber /= 2;
You have to get the remainder before dividing the number by 2.
Related
This is my code for the Codewars problem (Java) yet I cannot make it work. I'm pretty sure I've made a stupid mistake somewhere because of my lack of experience (coding for 4 months)
public static int zeros(int n) {
int f = 1;
int zerocount = 0;
for(int i = 2 ; i <= n; i++){
f *= i;
}
String factorial = String.valueOf(f);
String split [] = factorial.split("");
for(int i = 0; i < split.length; i++){
String m = split[i];
if(m.equals( "0")){
zerocount ++;
}
else {
zerocount = 0;
}
}
return zerocount;
}
}
In fact, you do not need to calculate the factorial because it will rapidly explode into a huge number that will overflow even a long. What you want to do is count the number of fives and twos by which each number between 2 and n can be divided.
static int powersoffive(int n) {
int p=0;
while (n % 5 == 0) {
p++;
n /= 5;
}
return p;
}
static int countzeros(int n) {
int fives = 0;
for (int i = 1; i <= n; i++)
fives += powersoffive(i);
return fives;
}
Note: Lajos Arpad's solution is superior.
As pointed out by other users your solution will probably not be accepted because of the exploding factorial you are calculating.
About the code you wrote there are two mistakes you have made:
You are calculating the factorial in the wrong way. You should start with i = 2 in the loop
for(int i = 2; i <= n; i++){
f *= i;
}
Also in Java you cannot compare strings using ==. This is not valid
if(m == "0")
You should compare them like this
if(m.equals("0"))
Anyway this is how I would have resolved the problem
public static int zeros(int n) {
int zerocount = 0;
for (int i = 5; n / i > 0; i *= 5) {
zerocount += n / i;
}
return zerocount;
}
A zero in a base-10 representation of a number is a 2*5. In order to determine the number of trailing zeroes you will need to determine how many times can you divide your number with ten, or, in other words, the minimum of the sum of 2 and 5 factors. Due to the fact that 5 is bigger than 2 and we go sequentially, the number of fives will be the number of trailing zeroes.
A naive approach would be to round down n/5, but that will only give you the number of items divisible with 5. However, for example, 25 is divisible by 5 twice. The same can be said about 50. 125 can be divided by 5 three times, no less.
So, the algorithm would look like this:
int items = 0;
int power = 5;
while (power < n) {
items += (int) (n / power);
power *= 5;
}
Here small numbers are in use in relative terms, but it's only a proof of concept.
You do need to use brute force here and you integers will overflow anyway.
With multiplication trailing zero appears only as the result of 2*5.
Now imagine the factorial represented by a product of it's prime factors.
Notice that for every 5 (five) we will always have 2 (two).
So to calculate the number of zeroes we need to calculate the number of fives.
That can be implemented by continuously dividing N by five and totaling results
In Java code that will be something like this:
static int calculate(int n)
{
int result = 0;
while (n > 0 ) {
n /= 5;
result += n;
}
return result;
}
Problem Statement:
Find the minimum number of steps required to reach a target number x from 0 (zero), using only two operations: +1 (add 1 to the number) or *2 (multiply 2 with the number).
So here's the Logic that I came up with:
The best way is to work backwards. Start from the number you need:
Subtract 1 if the number is odd.
Divide by 2 if the number if even.
Stop when you get to zero.
For example, for 29, you get 28, 14, 7, 6, 3, 2, 1, 0.
And, here's what I have tried doing (Java 7):
kValues is an array that has the x values for which the steps are needed to be computed and stored in an array called result.
static int[] countOperationsToK(long[] kValues) {
int size = kValues.length,x,i,steps;
int result[] = new int[size];
for (i = 0; i < size; ++i)
{
steps = 0;
for (x = (int)kValues[i]; x != 0 ; ++steps)
{
if((x % 2) == 0)
x /= 2;
else x--;
}
result[i] = steps;
}
return result;
}
My Problem:
This is a Hackerrank question and I am supposed to write an efficient code. I was successful with 7/11 test cases and others were timed out. Since, it is a Hackerrank question, I can't change the function definition or the return type. That is the reason why I am converting from long to int in my for loop, in order to use % (modulus). I would like to know where I am going wrong. Is my algorithm taking too long to compute (for the number of values close to a million)? Which is obviously the case, but how do I alter my algorithm in order to pass all the test cases?
Thank you in advance :)
for (x = (int)kValues[i]; x != 0 ; ++steps)
The fact that you are casting a long to an int is very suspicious. You might get a negative number when you do that.
Say x == -2: you divide it by 2 to give -1, then subtract 1 to give -2. You'll keep doing that indefinitely.
Just define x to be a long, and remove the cast.
So, here's the working code. I had forgotten to append L while using the modulo. Silly mistake led to so much of typing. LOL!!
static int[] countOperationsToK(long[] kValues) {
int size = kValues.length,i,steps;
int result[] = new int[size];
long x;
for (i = 0; i < size; ++i)
{
steps = 0;
for (x = kValues[i]; x != 0 ; ++steps)
{
if((x % 2L) == 0)
x /= 2L;
else x -= 1L;
}
result[i] = steps;
}
return result;
}
Here is a very short version, using bit-analysis:
static int[] countOperationsToK(long... input) {
int result[] = new int[input.length];
for (int i = 0; i < input.length; i++)
if (input[i] > 0)
result[i] = Long.bitCount(input[i]) + 63 - Long.numberOfLeadingZeros(input[i]);
return result;
}
The idea here is to look at the binary number, e.g. for 29 that is 11101. There are 4 bits set, so we'd need to do +1 four times, and the highest bit position is 4, so we need to left-shift (i.e. *2) four times, for a total of 8 operations: +1, *2, +1, *2, +1, *2, *2, +1.
numberOfBits = Long.bitCount(x)
highBitNumber = floor(log2(x)) = 63 - Long.numberOfLeadingZeros(x)
The highBitNumber part doesn't work if value is zero, hence the if statement.
For input number x,
Minimum no. of Ops = (int)log2(x) + Long.BitCount(x)
I am trying to figure out how to write my code that it reads from the right to left, not left to right
public static int sumofEvenSpot(long number)
{
int sumEvenSpot = 0;
String stringLength = Long.toString(number);
for (int i = 0; i< stringLength.length(); i += 2)
sumEvenSpot += (getDigit(Character.getNumericValue(stringLength.charAt(i)) * 2));
return sumEvenSpot;
}
Just do for(int i = stringLength.length() - 1; i = 0; i = i - 2)
( for(start, end, increment) )
OR
You can reverse your string and do a normal for but it takes more code
You can start summing from the rightmost digit, and every iteration divide the number by 100 in order to remove the current digit and the next one (in the odd place) in order to keep summing the following even digit:
int sum = 0;
while(number > 0) {
sum += number % 10;
number /= 100;
}
One advantage of doing it this way is that you don't have to convert the long to string and then back to int.
My assignment asks for a command-line input to be put through nested while loops to find if a number is a happy number or not. So far I have this:
int i = 0;
int sum = 0;
int dig2, dig1, dig3, dig4, dig1next, dig2next, dig3next;
int digit1sum, digit2sum, digit3sum;
happyNumber = number;
while (i < 500){
while (happyNumber > 0){
while (sum!=1){
dig3 = happyNumber / 100;
dig2 = happyNumber % 10;
dig1 = happyNumber / 10;
dig2next = dig2 % 10;
dig1next = dig1 % 10;
dig3next = dig3 % 10;
digit1sum = dig1next * dig1next;
digit2sum = dig2next * dig2next;
digit3sum = dig3next * dig3next;
sum = digit1sum + digit2sum + digit3sum;
happyNumber = sum;
}
System.out.println("It is a happy number.");
System.exit(0);
}
i++;
System.out.println(i);
System.exit(0);
}
I set i<500 so when i++ reaches 500, the loop should stop. I've pretty much tried putting i++ in every section of the code possible, it never works. what am i doing wrong here?
also: i am not allowed to use for loops or do-while loops on this assignment. i have to use nested while loops only
Happy number: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1(how long the loop will be: 500).
After a quick glance at your code:
while (sum!=1)
....
sum = digit1sum + digit2sum + digit3sum;
happyNumber = sum;
This while test is likely to be always true -> infinite loop -> stack overflow
You will never get out of your innermost while-loop in case of a number that loops endlessly (it is by no means stopped by the 500- limit and your logic is wrong here).
Secondly, something to think about:
digit1sum = dig1next*dig1next;
digit2sum = dig2next*dig2next;
digit3sum = dig3next*dig3next;
these (digitxsum) will always be positive.
sum = digit1sum + digit2sum + digit3sum;
sum will therefore always be positive
happyNumber = sum;
happynumber will always be positive
while (happyNumber > 0)
what is this for?
I'm trying to take an integer as a parameter and then use recursion to double each digit in the integer.
For example doubleDigit(3487) would return 33448877.
I'm stuck because I can't figure out how I would read each number in the digit I guess.
To do this using recursion, use the modulus operator (%), dividing by 10 each time and accumulating your resulting string backwards, until you reach the base case (0), where there's nothing left to divide by. In the base case, you just return an empty string.
String doubleDigit(Integer digit) {
if (digit == 0) {
return "";
} else {
Integer thisDigit = digit % 10;
Integer remainingDigits = (digit - thisDigit) / 10;
return doubleDigit(remainingDigits) + thisDigit.toString() + thisDigit.toString();
}
}
If you're looking for a solution which returns an long instead of a String, you can use the following solution below (very similar to Chris', with the assumption of 0 as the base case):
long doubleDigit(long amt) {
if (amt == 0) return 0;
return doubleDigit(amt / 10) * 100 + (amt % 10) * 10 + amt % 10;
}
The function is of course limited by the maximum size of a long in Java.
I did the same question when doing Building Java Programs. Here is my solution which works for negative and positive numbers (and returns 0 for 0).
public static int doubleDigits(int n) {
if (n == 0) {
return 0;
} else {
int lastDigit = n % 10;
return 100 * doubleDigits(n / 10) + 10 * lastDigit + lastDigit;
}
There's no need to use recursion here.
I'm no longer a java guy, but an approximation of the algorithm I might use is this (works in C#, should translate directly to java):
int number = 3487;
int output = 0;
int shift = 1;
while (number > 0) {
int digit = number % 10; // get the least-significant digit
output += ((digit*10) + digit) * shift; // double it, shift it, add it to output
number /= 10; // move to the next digit
shift *= 100; // increase the amount we shift by two digits
}
This solution should work, but now that I've gone to the trouble of writing it, I realise that it is probably clearer to just convert the number to a string and manipulate that. Of course, that will be slower, but you almost certainly don't care about such a small speed difference :)
Edit:
Ok, so you have to use recursion. You already accepted a perfectly fine answer, but here's mine :)
private static long DoubleDigit(long input) {
if (input == 0) return 0; // don't recurse forever!
long digit = input % 10; // extract right-most digit
long doubled = (digit * 10) + digit; // "double" it
long remaining = input / 10; // extract the other digits
return doubled + 100*DoubleDigit(remaining); // recurse to get the result
}
Note I switched to long so it works with a few more digits.
You could get the String.valueOf(doubleDigit) representation of the given integer, then work with Commons StringUtils (easiest, in my opinion) to manipulate the String.
If you need to return another numeric value at that point (as opposed to the newly created/manipulated string) you can just do Integer.valueOf(yourString) or something like that.