Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Ok, so I was wondering how can one check whether two numbers have the same digits, e.g. 21 and 12 are ok, also 1233 and 2313, but 123 and 1233 are not, meaning that the digits are permutation of another number's digits.
I know how to do it with arrays or strings or maps, but the problem is, that I don't want to do it with either of those, if there exists another solution.
The solution with arrays / maps:
Map<int, int> counter = new HashMap<int, int>();
for (int i = 0; i < 10; i++)
counter.put(i, 0);
int x = 2421, y = 4223; // testcase
while (x > 0 || y > 0) {
if (x == 0 || y == 0) // if they are not the same length, one will be 0 and thus they are not permutations
return false;
counter.put(x%10, counter.get(x%10) + 1);
counter.put(y%10, counter.get(y%10) - 1);
x /= 10;
y /= 10;
}
// For each digit we added 1 to the counter if it was found in `x`
// and subtract 1 if it was found in `y`.
return counter.values() == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
Now, the array approach is completely the same, since using a map for digits 0-9 is the same as using the key for map as the index in array. The solution without any data structure looks far from ideal to me:
private static boolean haveSameDigits(int x, int y) {
// Because we are not allowed to use maps, declare 10 vars...
int c0 = 0;
int c1 = 0;
int c2 = 0;
int c3 = 0;
int c4 = 0;
int c5 = 0;
int c6 = 0;
int c7 = 0;
int c8 = 0;
int c9 = 0;
while (x > 0 || y > 0) {
if (x == 0 || y == 0)
return false;
if ((x % 10) == 0)
c0++;
else if ((x % 10) == 1)
c1++;
else if ((x % 10) == 2)
c2++;
else if ((x % 10) == 3)
c3++;
else if ((x % 10) == 4)
c4++;
else if ((x % 10) == 5)
c5++;
else if ((x % 10) == 6)
c6++;
else if ((x % 10) == 7)
c7++;
else if ((x % 10) == 8)
c8++;
else if ((x % 10) == 9)
c9++;
if ((y % 10) == 0)
c0--;
else if ((y % 10) == 1)
c1--;
else if ((y % 10) == 2)
c2--;
else if ((y % 10) == 3)
c3--;
else if ((y % 10) == 4)
c4--;
else if ((y % 10) == 5)
c5--;
else if ((y % 10) == 6)
c6--;
else if ((y % 10) == 7)
c7--;
else if ((y % 10) == 8)
c8--;
else if ((y % 10) == 9)
c9--;
x /= 10;
y /= 10;
}
return c0 == 0 && c1 == 0 && c2 == 0 && c3 == 0 && c4 == 0 && c5 == 0 && c6 == 0 && c7 == 0 && c8 == 0 && c9 == 0
}
I have googled about it but no matter what I typed I ended up with a solution using strings or arrays.
I am not looking for a solution, I actually don't want it, I just need a hint to the approach.
Adding some more information: There is nothing prohibiting me from using any data structure I want, this is my program and nobody will be checking over what I do. I am just that kind of person that likes to learn new stuff, so I was wondering if there is a quick solution to it.
As stated in the comments, one can iterate over both numbers and check for each number in range (0,9) inclusive, how many times they appear in string but that obviously yields time complexity of O(n*n) which is not optimal.
You do not want to convert to string, or to use any helper data structures. How about this then: Create a hash from the numbers, in the form xor(2^d for every digit d in n)?
For example, hash(3112) will be (in binary) 1100.
Since you do not want a solution, here's some pseudocode (aka Python):
def hash(n):
r = 0
while n > 0:
d = n % 10 # last digit
n = n // 10 # remaining digits
r = r ^ 2**d # xor with 2^d
return r
def perm(n, m):
return hash(n) == hash(m)
Update: Turns out that the above does not work properly, as XOR can only keep track of whether a digit appears an even or odd number of times. Instead, you could create a hash using multiples of prime numbers. This way, hash(3112) becomes 7 * 3 * 3 * 5. While this uses a list to keep the first ten prime numbers, it does not create any new lists, arrays or maps while checking individual pairs of numbers. Also, keep in mind that the resulting hash might get very large -- larger than Java's int or long types. (You can probably take the modulo of another large prime number, but I'm not sure about that part.)
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
def hash(n):
r = 1
while n > 0:
d = n % 10 # last digit
n = n // 10 # remaining digits
r = r * primes[d]
return r
You can parse int's to strings and check with .contains
final List<Integer> intsForCheck = new ArrayList<>();
for (int i = 1; i < 180; i++)
intsForCheck.add(i);
final int num = 17;
intsForCheck.forEach(integer -> check(integer,num));
public static void check(int integer,int num)
{
final String _int = String.valueOf(integer);
final String _num = String.valueOf(num);
System.out.println(_int + (_int.contains(_num) ? " contains" : " not contains") + _num);
}
Related
This question already has answers here:
How do you get absolute values and square roots
(6 answers)
Check if int is between two numbers
(11 answers)
Closed 1 year ago.
I am new to JAVA, and I have a question about one of the practice assignments.
The question is:
Given an int n, return true if it is within 10 of 100 or 200.
Why do the codes below have errors (bad operand types for binary operator '<=' or '<')?
public boolean nearHundred(int n) {
return (90 <= n <= 110) || (190 <= n <= 210);
}
public boolean nearHundred(int n) {
return (89 < n < 111) || (189 < n < 211);
}
I finally figured out the solution, but I was wondering if there is a better solution for the "absolute" value.
public boolean nearHundred(int n) {
if(n <= 100){
return (100-n)<=10;
}
if (n>=100 && n <= 200){
return (n-100) <=10 || (200-n) <=10;
}
if (n > 200){
return (n-200)<=10;
} else {
return false;
}
}
Thank you very much for your help!
add &&s between your operations so switch return (90 <= n <= 110) || (190 <= n <= 210);
to something like
return (90 <= n && n <= 110) || (190 <= n && n <= 210);
(you can't change operations like that)
Java cannot chain logical operations like a > b > c. You need to use && to connect two parts.
90 <= n && n <= 110 || 190 <= n && n <= 210
"and" is executed before "or", you don't need parenthesis, but you can add them for readability.
(90 <= n && n <= 110) || (190 <= n && n <= 210)
In you case you can also get the absolute value after subtraction:
Math.abs(100 - n) <= 10 || Math.abs(200 - n) <= 10
Alternately you can use Range class from the Guava library:
Range.closed(90, 110).contains(n) || Range.closed(190, 210).contains(n)
Apache Commons Lang has a similar class as well.
You can try Math.abs()
The java.lang.Math.abs(int a) returns the absolute value of an int value
Reference: https://www.tutorialspoint.com/java/lang/math_abs_int.htm
You can use the Range class:
Range<Integer> lowerRange = Range.between(90,110);
Range<Integer> upperRange = Range.between(190,210);
return lowerRange.contains(n) || upperRange.contains(n);
Given a two 1d arrays that are stick one to the other with n and m lengths , write a recursive algorithm to find the number of ways that this shape could be filled by 1x1 or 1x2 or 2x1 blocks ,
here is my attempt , but I believe that I'm counting the same option several times :
public static int foo(int n1 ,int m){
if(n1==0 && m ==0){
return 1;
}
if(n1 < 0 || m < 0)
return 0;
return (foo(n1-1,m)+foo(n1,m-1)+foo(n1-1,m-1) +foo(n1,m-2) + foo(n1-2,m));
}
*** UPDATE ****
now the code compiles.
Examples :
input foo(2,2) output : 21 , the right answer is 7 .
input foo(4,3) output : 417, the right answer is 32.
these are the options for foo(2,2).
We'll assume n < m. If this is not the case we can just reverse the arguments - this makes the code simpler.
Once we've dealt with the terminating conditions we use a decrease-and-conquer strategy to reduce the input according to the following rules: if n == m, we can reduce both n & m by 1 two ways, n & m by 2 one way, n by 1 and m by 2 one way, and n by 2 and m by 1 one way. If n < m we can reduce m by 1 one way and m by 2 one way.
static int foo(int n, int m)
{
if(n > m) return foo(m, n);
if(n < 0 || m < 0) return 0;
if(n == 0 && m == 0) return 1;
if(n == m) return 2*foo(n-1, m-1) + foo(n-2, m-2) + foo(n-1, m-2) + foo(n-2, m-1);
return foo(n, m-1) + foo(n, m-2);
}
Test:
for(int i=0; i<5; i++)
for(int j=i; j<5; j++)
System.out.format("(%d, %d) = %d%n", i, j, foo(i, j));
Output:
(0, 0) = 1
(0, 1) = 1
(0, 2) = 2
(0, 3) = 3
(0, 4) = 5
(1, 1) = 2
(1, 2) = 3
(1, 3) = 5
(1, 4) = 8
(2, 2) = 7
(2, 3) = 10
(2, 4) = 17
(3, 3) = 22
(3, 4) = 32
(4, 4) = 71
For the case n == m (2, 7, 22, 71, ...) this is a known integer sequence (A030186).
And just for reference, here are the 32 configurations for (3,4):
I believe that i have found the correct answer to my question :
yet i'm not closing this problem until someone with better knowledge than me confirm my answer
public static int foo(int n1 ,int m){
if(n1==0 && m ==0){
return 1;
}
if(n1 < 0 || m < 0)
return 0;
if(m == n1){
return Integer.max(foo(n1-1,m),foo(n1,m-1)) + Integer.max(foo(n1-2,m),foo(n1,m-2))+ foo(n1-1,m-1);
}else{
return Integer.max(foo(n1-1,m),foo(n1,m-1)) + Integer.max(foo(n1-2,m),foo(n1,m-2));
}
}
now i'm taking only the maximum sub-Problem answer so I won't count the same option more than once.
You must deliver exactly N kilograms of sugar to a candy store. The sugar made in the sugar factory is contained in a bag. The bag has 3 kg bag and 5 kg bag.
I try to carry as little bags as possible. For example, when you need to deliver 18 kilograms of sugar, you can take 6 bags of 3 kilograms, but if you deliver 3 kilograms and 3 kilograms, you can deliver a smaller number of bags.
Write a program to find out the number of bags you should take when you have to deliver exactly N kilograms of sugar.
(3<=N<=5000 AND If you can not make exactly N kilograms, print -1.)
In case of only 4 or 7 , it is not divided so I made it to print -1.
And to get the minimum bag, I used the code below.
But when I run this, the case if it is not divided by 5 or 3, the bottom sentence should be printed out but it is not working.
I want to know how does it works. Thank you.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int N = input.nextInt();
if (N % 5 == 0) {
System.out.println(N / 5);
} else if (N == 4 || N == 7) {
System.out.println(-1);
} else
for (int i = 1; (N - 3 * i) % 5 != 0; i++) {
if ((N - 3 * i) % 5 == 0)
System.out.println(i + (N - 3 * i) / 5);
break;
}
}
}
Looks there is a logic issue with your solution. Try the following :
boolean isPossible = true;
if (N % 5 == 0) {
System.out.println("You need : " + (N / 5) + " bags");
} else {
int diff = 0;
for (int i = N; i > 0 && N >= 0; i--) {
if (N % 5 != 0) {
diff = N % 5;
N = N - diff;
} else {
if (diff % 3 == 0) {
System.out.println("You need : " + (N / 5 + diff / 3) + " bags");
isPossible = true;
break;
} else {
N = N - 5;
diff = diff + 5;
}
}
}
}
if (N <= 0 || !isPossible)
System.out.println(-1);
Logic is explained below :
Basically here we find the modulus of N with 5 and check if the
remainder (in the example diff) is a multiple of 3.
If the remainder (diff) is not a multiple of 3 then we reduce N by
5 and increase diff by 5. This continues until we have found a match (isPossible) or else if not found -1 is printed out.
So as far as I understand, you're trying to use the smallest amount of 3kg bags in the last for loop and you want to break out as soon as the remainder is divisible by 5kgs.
(int i = 1; (N - 3 * i) % 5 != 0; i++)
Could you not have the middle part as i < 5?
(int i = 1; i < 5; i++)
Also, you could get rid of the if condition
if (N % 5 == 0) {
part by starting i at 0, so you account for the case N is divisible by 5:
(int i = 0; i < 5; i++)
Scanner input = new Scanner(System.in);
int N = input.nextInt();
int sum = 0;
boolean isFound = false;
for (int i = 0; i < N / 2; i++) {
for (int j = 0; j < N / 2; j++) {
if ((5 * i) + (3 * j) == N) {
sum = i + j;
isFound = true;
}
}
}
if (isFound ) {
System.out.println("You require " + sum + " bags");
} else {
System.out.println(-1);
}
Explanation:
The above code aims to find the possible combinations of the sum of the factors of 3 and 5 that give the number, i.e N:
For example:
N = 32
For each iteration, the following condition is checked.
if((5 * i) + (3 * j) == N)
The check continues until the smallest numbers that satisfy the condition are found.
5*0 + 3*0 = 0 which is not equal to 32
5*0 + 3*1 = 3 which is not equal to 32
5*0 + 3*2 = 6 which is not equal to 32
.
.
5*1 + 3*0 = 5 which is not equal to 32
5*1 + 3*1 = 8 which is not equal to 32
5*1 + 3*2 = 11 which is not equal to 32
5*1 + 3*4 = 17 which is not equal to 32
.
.
5*4 + 3*0 = 20 which is not equal to 32
5*4 + 3*1 = 23 which is not equal to 32
5*4 + 3*2 = 26 which is not equal to 32
5*4 + 3*3 = 29 which is not equal to 32
5*4 + 3*4 = 32
In this case, i=4 and j=4, i.e sum of bags required (i+j) = 8
isFound is set to true to indicate that the combination is found.
If no combination is found, isFound remains to be false, and -1 is printed.
I am trying to check if on number is divisible by another, and currently I use this method:
int x = 70;
int y = 30;
if(x/y == Math.round(x/y)) {
...
}
Is there a simpler way?
You can use modulus operator like this in your condition,
if (x%y == 0)
A good way is to use modulus operator, which returns the remainder after dividing by a number, e.g.
5 % 2 = 1 (1 is the remainder after 5 is divided by 2)
So for a number to be divisible by another, it should have a remainder of 0 (i.e. x % y = 0)
if (x % y == 0)
{
//x is divisible by y
}
else
{
//x is not divisible by y
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
The code is supposed to cycle through all the numbers until it finds two numbers that can fulfill the conditions:
The factor of the number must consist of half of the original numbers digits
And the factor numbers must not be a multiple of 100. PS. the factor numbers are T and H.
However the code is not working
import java.util.Scanner;
public class VampierSlayer {
public static void main(String[] args) {
Scanner S = new Scanner(System.in);
System.out.println("Input A Even Digit Integer");
int i = S.nextInt();
String iS = Integer.toString(i);
int t = 0;
int h = 0;
for (h = 0; h < 1000000000; h++) {
if (h * t == i && iS.length() / 2 == Integer.toString(h).length()
&& iS.length() / 2 == Integer.toString(t).length() && h % 100 == 1 && t % 100 == 1) {
System.err.println("Finish");
break;
} else {
t++;
h = h - 1;
}
if (t > 1000) {
t = 0;
h = h + 1;
}
System.out.println(t + " " + h);
}
System.out.println(Integer.toString(h) + "," + t);
}
}
First, you're iterating through all numbers in a bit inconsistent way, you won't get all possible t-h combinations that way. Much better way would be to use 2 nested for-loops:
for (int h = 0; h < ...; h++) {
for (int t = 0; t < ...; t++) {
...
}
}
Next, you should do some research about how modulo works, you should have
h % 100 == 0 && t % 100 == 0
to properly check that numbers t and h are multiples of 100.
"And the factor numbers must not be a multiple of 100." Doesn't this mean:
if (h * t == i && iS.length() / 2 == Integer.toString(h).length()
&& iS.length() / 2 == Integer.toString(t).length()
&& h % 100 != 0 && t % 100 != 0)