Finding numbers with distinct digits in a range using loops - java

Desired behaviour: print and count all numbers between 1 (inclusive) and lim (exclusive) that have distinct digits, that is, not the same digit twice.
Specific problem: The program runs in an infinite loop.
This is what I have already done. but it is not working. I tried printing the values at each step but it keeps on giving 1 in infinte loop.
What did I do wrong?
public static void main(String args[]) {
Scanner sc= new Scanner(System.in);
double limit=sc.nextDouble(); // reading the range of numbers from 0 to limit-digit number
int count=0,total=0;
int lim=(int)(Math.pow(10.0,limit)); //setting range from 0 to 10^limit
System.out.println(lim);
for(int i=1;i<lim;i++) {
Set<Integer> set = new HashSet<Integer>(); //making a hash set to include the unique elements
System.out.println(i);
while (i > 0) {
int tempVal = i % 10; //each digit is extracted and stored in hash set if unique
set.add(tempVal);
i = i / 10;
count++;
//System.out.println(count);
}
count+=1;
if(count==set.size())
{
total++;
}
count=0;
}
System.out.println(total);
}

Your problem in your loop :
while (i > 0) {//<<------------
To solve your problem you have inverse the order of your condition instead of :
while (i > 0) {
You have to use :
while (i < 0) {
Or it is also logic to replace the i in your loop :
while (i > 0) {
With count like this :
while (count > 0) {

I believe your problem is you are using i for two purposes. i is your loop control variable from 1 to lim. You modify i inside the loop, then it will no longer work as loop control variable. It will never reach lim, so your for loop will never terminate.
Instead you need to work in a copy of i when deciding whether i has distinct digits, so you can do your calculation without modifying i itself.

Related

Facing problem with the output of this code

My friend gave me this code and i cant seem to find the error in it. I am attaching the code below:
import java.util.*;
public class prg {
public static void main(String[] args) {
int n;
int count;
int a=0,b=1;
int c=0;
Scanner kb=new Scanner(System.in);
n=kb.nextInt();
int ar[]=new int[100];
ar[1] = 2;
for(int i=3;i<=n;i+=2)
{
count=0;
for (int j = 2; j < i ;j++ ) {
if (i % j == 0) {
count++;
break;
}
}
if(count==0)
ar[i]=i;
}
for(int i=0;i<=n;i+=2)
{
a = b;
b = c;
c = a + b;
ar[i]=c;
}
for(int i=0;i<14;i++)
System.out.print(ar[i]+" ");
}
}
So, the even index is storing the fibonacci series and the odd index is storing prime number.
Problem: the rest of the code is working fine but the 9th index of 'ar' array is printing 0 i dont know why and because of it the output is showing wrong.
Take input n as 14 and check the code please.
Thankyou in advance.
PS: i have solved this question in one other way so i request you to not give answers like 'try my method, its not efficient'. I just want to know what is going wrong at INDEX 9 of the array.
Edited: facing problem with the Prime Number loop.
When i is 9, your code correctly identifies that it is not a prime number, so count is not 0. This causes this line to not run:
ar[i]=i;
And then you increase i by 2 to check the next odd number. This means that you never set index 9 of the array to anything, so it remains at its default value - 0.
To fix this, you should introduce a new variable possiblePrime to keep track of which number you are checking. Increase this variable every iteration of the outer for loop, and increase i only when possiblePRime is prime. Also, change the above line to:
ar[i] = possiblePrime;
9 is not a prime number, so it sets nothing in the array. 0 is the default value so it gets printed.

how to use value of a variable that was calculated inside a loop in java

`
public static int Digits(int n){
int nbr=0,count=0;
while (nbr!=0){
nbr= nbr/10;
count++;
}
return count;}`
I'm sorry if this question seems silly but I've never taken any java outside university and I have an assignment. The exercise asks to state whether the number of digits of an integer is smaller, equal, or bigger than the number of digits of another integer using method. For this purpose, I used a while loop in the method which tells me the count of the number of digits of a given integer.
I know that I have to declare a variable outside the loop if I want to use it outside the loop.However, I have to initialize it outside the loop so I can use it inside the loop. But I want the value of the count after it has been calculated inside the loop and I'm not able to do this although I tried really hard and searched for answers but didn't find any.
First of all you need to delete count = 0 inside the loop because it will always be 0. Second thing is that your while condition (nbr! = 0) is never true because in declaration you set it to 0
Below function return number of digits in number passed as argument
public static int Digits(int n)
{
int count = 0;
while(n != 0)
{
count++;
n /= 10;
}
return count;
}
There are couples of fixes/improvements needed in this code.
Digits variable is not used.
nbr is always 0 and not assigned the value of n.
On each iteration, count is reset to 0.
It doesn't consider 0, it is digit of one length.
public static int countOfDigits(int n) {
if (n == 0) {
return 1;
}
int count = 0;
while (n != 0) {
n = n / 10;
count++;
}
return count;
}

Why isn't my code returning the "maximum" number of consecutive 1's for the specific input "524275"?

I'm trying to solve HackerRank Day Of Code 10.
In short, the task is to find the maximum number of consecutive 1's in the binary representation of a decimal number. In my code I've tried to use two variables: count and hold. count increases by 1 whenever the current position of the string and the previous position are both 1. Whenever the i'th position is 0, count 's value is assigned to the variable hold. In the following iterations if ever the value of count exceeds that of hold then the value of count is assigned to hold. In this way the maximum number of consecutive 1's is stored in hold. Finally I'm printing the value of hold.
import java.util.*;
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter decimal number");
int n = in.nextInt();
String binary = Integer.toString(n,2);
int count=1;
int hold=0;
if(binary.equals("0"))
System.out.println(0);
else
{
for(int i=0;i<binary.length();i++)
{
if(i==0){}
else if(binary.charAt(i-1)=='1' && binary.charAt(i)=='1')
{
count++;
}
if(count>hold)
hold=count;
if(binary.charAt(i)=='0')
{
hold=count;
count=1;
}
}
System.out.println(hold);
}
}
}
My code isn't working for the sample input "524275" which converts to "1111111111111110011" in binary. The output comes out to be 2 which is strange. my code is written such that the "maximum" number of consecutive 1's are returned. Where did I go wrong? I tried dry running the code mentally but can't spot the mistake yet.
After processing the first 15 ones in with the for loop, hold will actually have the value 15. Then you meet the first zero, and if(binary.charAt(i)=='0') { hold=count; count=1; } will reset count to 1. But then you immediately find another zero, and the same code if(binary.charAt(i)=='0') { hold=count; count=1; } stores 1 in hold and you loose the information 15.
An easy solution is just to remove the line hold=count; in this line. You already set hold three lines above. (And correctly, because you only do it if count is bigger then the previous best value.
The approach is quite complicated. If you want an easier approach. The code should be pretty self-explanatory.
int current_consecutive_ones = 0;
int best_consecutive_ones = 0;
for(int i = 0; i < binary.length(); i++)
{
if (binary.charAt(i) == '1')
current_consecutive_ones++;
else
current_consecutive_ones = 0;
if (current_consecutive_ones > best_consecutive_ones)
best_consecutive_ones = current_consecutive_ones;
}
System.out.println(best_consecutive_ones);

Why am I getting an infinite loop of 0's? (Java)

I asked a question about my code the other day, which was quickly resolved by the incredible community here. However I have encountered a completely separate problem using a re-written version of my code. Here's a description of the program from my previous post.
I'm trying to write a program that can detect the largest sum that can be made with any subset of numbers in an ArrayList, and the sum must be lower than a user-input target number. My program is working flawlessly so far, with the exception of one line (no pun intended). Keep in mind that this code isn't complete yet too.
My problem with the code now is that after the user inputs a target number, the program outputs an infinite loop of 0's. Even after trying to debug, I still come up with problems. The ArrayList is being applied to the program perfectly fine, but I think I may have a problem somewhere within one of my while loops. Any ideas?
Heres the code.
import java.util.*;
class Sum{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int temp = 0, target = 1, result = 0, firstIndex = 0, secondIndex = 0;
String tempString = null;
ArrayList<String> list = new ArrayList<String>();
ArrayList<Integer> last = new ArrayList<Integer>();
System.out.println("Enter integers one at a time, pressing enter after each integer Type \"done\" when finished.\nOR just type \"done\" to use the default list.");
String placehold = "NotDone";
while (!placehold.equals("done")){
list.add(input.nextLine());
placehold = list.get(list.size() - 1);
}
list.remove(list.size() - 1);
if (list.size() == 0){ //Inserts default list if said list is empty
list.add("1");
list.add("2");
list.add("4");
list.add("5");
list.add("8");
list.add("12");
list.add("15");
list.add("21");
}
for (int i = 0; i < list.size(); i++){
tempString = list.get(i);
temp = Integer.parseInt(tempString); //Changes the items in the list to Integers, which can be inserted into another list and then sorted
last.add(temp);
}
Collections.sort(last);
System.out.println("Enter the target number");
target = input.nextInt();
while (result < target){
firstIndex = last.size() - 1;
secondIndex = firstIndex - 1;
while (last.get(firstIndex) > target){
firstIndex--;
}
if (last.get(firstIndex) + last.get(secondIndex) < result){
result = last.get(firstIndex) + last.get(secondIndex);
last.remove(firstIndex);
last.remove(secondIndex);
last.add(result);
}
else{
secondIndex--;
}
System.out.println(result);
}
}
}
And the Output...
Enter integers one at a time, pressing enter after each integer Type "done" when finished.
OR just type "done" to use the default list.
done //Prompting to use the default list
Enter the target number
15 //User inputs target number
0
0
0
0
0
0
... //And so on
target = input.nextInt();
should be within your loop otherwise the variable will never change and
while(result<target) will never turn to false
while(result<target) {
target = input.nextInt();
// otherCoolCode
}
You are assigning target before the while loop, and you are not altering target any way inside the while loop. You need to prompt the user within the while loop. Otherwise, if you set a target variable higher than 0, it will be an infinite loop.
The problem is in
if (last.get(firstIndex) + last.get(secondIndex) < result) {
...
}
Result is always initialized to zero, so that condition will never be true.
One possible fix is to add an extra condition to handle this initial case:
if (result == 0 || last.get(firstIndex) + last.get(secondIndex) < result) {
...
}
An infinite loop occurs when you have a loop whose condition(s) do not change during an iteration of the loop.
Let's review your loop:
while (result < target){
firstIndex = last.size() - 1;
secondIndex = firstIndex - 1;
while (last.get(firstIndex) > target){
firstIndex--;
}
if (last.get(firstIndex) + last.get(secondIndex) < result){
result = last.get(firstIndex) + last.get(secondIndex);
last.remove(firstIndex);
last.remove(secondIndex);
last.add(result);
}
else{
secondIndex--;
}
System.out.println(result);
}
Your loop will only end if result and/ortarget change so that result < target is false.
Within your loop you assign to result only when (last.get(firstIndex) + last.get(secondIndex) < result) is true. So if that condition is false then result will not change.
You have some additional state that is not in the loop condition itself but is manipulated by the loop: firstIndex and secondIndex. Every iteration of the loop you assign to them. You do have an 'else' clause where you modify secondIndex just before printing the current value of result, however you then immediately assign to it at the top of the loop.
This is the crux of your infinite loop (when last.get(firstIndex) + last.get(secondIndex) < result is false):
result doesn't change
Your list last isn't modified, thus last.size()-1 and firstIndex - 1 remain the same
You assign secondIndex = firstIndex - 1; overwriting the decrement at the end of the loop, thus neither firstIndex nor secondIndex change
In this line
if (last.get(firstIndex) + last.get(secondIndex) < result) {
the sum of both your values will hardly ever be less than result, which is "0".

How to recall a function, Sieve of Eratosthenes

I'm trying to write code that will work out prime numbers using the sieve of Eratosthenes. I have to include a function that will take in a number and cross of all of the multiples of that number. For testing I set the first number to be 2 and the second as 3. It works for the first number but never for the second(no matter the order of the numbers i.e if I put 3 into the function first). I know there are other completed sieve of Eratosthenes out there but I wanted to try and do it in the way that I thought of first.
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
System.out.println("Which number would you like to calculate up to?");
int n = input.nextInt();
input.close();
int x = 0;
int newNumber = 2;
int numbers[] = new int[n];
while(newNumber <= n){
numbers[x] = newNumber;
x++;
newNumber++;
}
int currentNumber = 2;
int finalNumber[] = markOfMultiples(n, numbers, currentNumber);
for(int y = 0;y < n-1;y++){
System.out.print(finalNumber[y] + ", ");
}
currentNumber = 3;
int secondNumber[] = markOfMultiples(n, numbers, currentNumber);
for(int y = 0;y < n-1;y++){
System.out.println(secondNumber[y]);
}
}
public static int[] markOfMultiples(int n, int numbers[], int currentNumber){
int originalNumber = currentNumber;
while(currentNumber<n){
currentNumber = currentNumber + originalNumber;
int count2 = 0;
while(currentNumber != numbers[count2] && currentNumber<=n && count2<n){
count2++;
}
numbers[count2] = 0;
}
return numbers;
}
The error I'm getting is: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 20
at sieveOfEratosthenes.sieveOfEratosthenes.markOfMultiples(sieveOfEratosthenes.java:46)
at sieveOfEratosthenes.sieveOfEratosthenes.main(sieveOfEratosthenes.java:28)
Line 28 is when I recall the function:int secondNumber[] = markOfMultiples(n, numbers, currentNumber);
And line 46 is while(currentNumber != numbers[count2] && currentNumber<=n && count2<20){
Any help would be much appreciated. How do I keep on calling the function?
p.s. Please excuse the variable names as I'll be changing them when I get the program working.
If you want to get this approach working, you can do the fix advised by #Thierry to check count2 < n first in your while loop and then also surround the line
numbers[count2] = 0
with an if clause to check count2 is not beyond the end of the index. e.g.
if (count2 < n) {
numbers[count2] = 0;
}
Your final challenge is how you call your markOfMultiples() function enough times when n gets a bit larger. It's not a problem with your fundamental approach - you can definitely do it and your approach will work well and have acceptable performance for low-ish numbers (say up to 10000).
However
I realise this is an assignment and you want to do it your way, but there are a few features of your approach which you might want to consider - maybe after you've got it working.
Readability - is it going to be easy for someone looking at (marking) your code to understand what it's doing and verify that it will do the right thing for all values of n?
Try not to repeat yourself - for instance consider where you fill your numbers array:
while(newNumber <= n){
numbers[x] = newNumber;
x++;
newNumber++;
}
Will x ever be different to newNumber? Did you need both variables? This sort or repetition occurs elsewhere in your code - the principle to stick to is known as DRY (Don't Repeat Yourself)
Is there an easier way to move the index on originalNumber places in your markOfMultiples() method? (HINT: yes, there is)
Do you really need the actual numbers in the numbers[] array? You're going to end up with a lot of zeros and the primes left as integer values if you work out how to call your markOfMultiples repeatedly for high values of n. Would an array of 1s and 0s (or trues and falses) be enough if you used the array index to give you the prime number?
You need to test if count2 < n BEFORE access to numbers[count2]:
while(count2 < n && currentNumber != numbers[count2] && currentNumber<= n){
count2++;
}

Categories