Dear friends I have an assignment and I almost solved it. But I'm having a big problem recently which I couldn't figure a way out for 2 days. If you could help me I would very appreciate it!
So, let's say user entered 5 (N) I immediately create this sequence to get subsets out of it: {1,2,3,4,5}
If N = 4 than the sequence is like: {1, 2, 3, 4} etc.
Than this code below generates all kind of the variations of subsets:
public static int[] genarator(int N)
{
int[] generator = new int[(int) Math.pow(2, N)];
int[] binDigit = new int[(int) Math.pow(2, N)];
for (int i = 0; i < Math.pow(2, N); i++)
generator[i] = (i >> 1) ^ i; // Right Shifting
for (int i = 0; i < Math.pow(2, N); i++)
{
int one = 1;
binDigit[i] = 0;
while (generator[i] > 0)
{
binDigit[i] += (generator[i] % 2) * one;
generator[i] /= 2;
one = one * 10;
}
}
return binDigit;
}
And the way it returns the results like this (In case of: N = 4 {1, 2, 3, 4}) shown here :
1
1 2
2
2 3
1 2 3
1 3
3
3 4
1 3 4
1 2 3 4
2 3 4
2 4
1 2 4
1 4
4
But my lecturer wants from my program to return the result in this order:
1
2
3
4
1 2
1 3
1 4
2 3
2 4
3 4
1 2 3
1 2 4
1 3 4
2 3 4
1 2 3 4
I for now use TreeSet<Long> and parseLong so I can get true results till 1 <= N <= 9. But whenever user enters 10 or higher as N it goes crazy.
To recap, my question is how can I store those numbers which I get from int[] genarator(int N) and display them like my lecturer requires ?
How generator works and how do I get numbers in wrong order? Code is below:
int N = read.nextInt();
int[] sequence = new int[N];
for (int i = 0; i < N; i++)
sequence[i] = i + 1;
int[] tempArray = new int[(int) Math.pow(2, N)];
tempArray = genarator(N);
for (int i = 1; i < Math.pow(2, N); i++)
{
for (int j = 0; j < N; j++)
{
if (tempArray[i] % 10 == 1)
{
System.out.print(sequence[j] + " ");
}
tempArray[i] /= 10;
}
System.out.println();
}
Thank you for checking and I am really sorry for this too long question. But I couldn't make it clear with a short explanation.
What you can do is create a set abstraction that can be compared to other sets. See Java tutorials on Comparators.
//don't call this Set as there is already a Java Set
//interface that youdon't want to confuse yourself with
public class MySet implements Comparable<MySet>{
int[] backingArray;
public MySet(int n) {
//initialize the Set
this.backingArray = generator(n);
}
public static Int[] generator(int n) {
//..whatever you do to generate your results
}
#Override
public int compareTo(MySet otherSet) {
//define how sets are compared (e.g what your professor is asking.
//In your example, if one set is shorter than another,
//it is considered 'smaller')
}
}
Set<MySet> allSets = ....;
and simply invoke Collections.sort(allSets);
Related
This is the question:
You are given Q queries. Each query consists of a single number N . You can perform any of the operations on in each move:
If we take 2 integers a and b where N=a*b (a ,b cannot be equal to 1), then we can change N=max(a,b)
Decrease the value of N by 1 .
Determine the minimum number of moves required to reduce the value of to .
Input Format
The first line contains the integer Q.
The next Q lines each contain an integer,N .
Output Format
Output Q lines. Each line containing the minimum number of moves required > to reduce the value of N to 0.
I have written the following code. This code is giving some wrong answers and also giving time limit exceed error . Can you tell what are the the mistakes present in my code ? where or what I am doing wrong here?
My code:
public static int downToZero(int n) {
// Write your code here
int count1=0;
int prev_i=0;
int prev_j=0;
int next1=0;
int next2=Integer.MAX_VALUE;
if (n==0){
return 0;
}
while(n!=0){
if(n==1){
count1++;
break;
}
next1=n-1;
outerloop:
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
if (i*j==n){
if (prev_i ==j && prev_j==i){
break outerloop;
}
if (i !=j){
prev_i=i;
prev_j=j;
}
int max=Math.max(i,j);
if (max<next2){
next2=max;
}
}
}
}
n=Math.min(next1,next2);
count1++;
}
return count1;
}
This is part is coded for us:
public class Solution {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
int q = Integer.parseInt(bufferedReader.readLine().trim());
for (int qItr = 0; qItr < q; qItr++) {
int n = Integer.parseInt(bufferedReader.readLine().trim());
int result = Result.downToZero(n);
bufferedWriter.write(String.valueOf(result));
bufferedWriter.newLine();
}
bufferedReader.close();
bufferedWriter.close();
}
}
Ex: it is not working for number 7176 ....
To explore all solution tree and find globally optimal solution, we must choose the best result both from all possible divisor pairs and from solution(n-1)
My weird translation to Java (ideone) uses bottom-up dynamic programming to make execution faster.
We calculate solutions for values i from 1 to n, they are written into table[i].
At first we set result into 1 + best result for previous value (table[i-1]).
Then we factor N into all pairs of divisors and check whether using already calculated result for larger divisor table[d] gives better result.
Finally we write result into the table.
Note that we can calculate table once and use it for all Q queries.
class Ideone
{
public static int makezeroDP(int n){
int[] table = new int[n+1];
table[1] = 1; table[2] = 2; table[3] = 3;
int res;
for (int i = 4; i <= n; i++) {
res = 1 + table[i-1];
int a = 2;
while (a * a <= i) {
if (i % a == 0)
res = Math.min(res, 1 + table[i / a]);
a += 1;
}
table[i] = res;
}
return table[n];
}
public static void main (String[] args) throws java.lang.Exception
{
int n = 145;//999999;
System.out.println(makezeroDP(n));
}
}
Old part
Simple implementation (sorry, in Python) gives answer 7 for 7176
def makezero(n):
if n <= 3:
return n
result = 1 + makezero(n - 1)
t = 2
while t * t <= n:
if n % t == 0:
result = min(result, 1 + makezero(n // t))
t += 1
return result
In Python it's needed to set recursion limit or change algorithm. Now use memoization, as I wrote in comments).
t = [-i for i in range(1000001)]
def makezeroMemo(n):
if t[n] > 0:
return t[n]
if t[n-1] < 0:
res = 1 + makezeroMemo(n-1)
else:
res = 1 + t[n-1]
a = 2
while a * a <= n:
if n % a == 0:
res = min(res, 1 + makezeroMemo(n // a))
a += 1
t[n] = res
return res
Bottom-up table dynamic programming. No recursion.
def makezeroDP(n):
table = [0,1,2,3] + [0]*(n-3)
for i in range(4, n+1):
res = 1 + table[i-1]
a = 2
while a * a <= i:
if i % a == 0:
res = min(res, 1 + table[i // a])
a += 1
table[i] = res
return table[n]
We can construct the directed acyclic graph quickly with a sieve and
then compute shortest paths. No trial division needed.
Time and space usage is Θ(N log N).
n_max = 1000000
successors = [[n - 1] for n in range(n_max + 1)]
for a in range(2, n_max + 1):
for b in range(a, n_max // a + 1):
successors[a * b].append(b)
table = [0]
for n in range(1, n_max + 1):
table.append(min(table[s] for s in successors[n]) + 1)
print(table[7176])
Results:
7
EDIT:
The algorithm uses Greedy approach and doesn't return optimal results, it just simplifies OP's approach. For 7176 given as example, below algorithm returns 10, I can see a shorter chain of 7176 -> 104 -> 52 -> 13 -> 12 -> 4 -> 2 -> 1 -> 0 with 8 steps, and expected answer is 7.
Let's review your problem in simple terms.
If we take 2 integers a and b where N=a*b (a ,b cannot be equal to 1), then we can change N=max(a,b)
and
Determine the minimum number of moves required to reduce the value of to .
You're looking for 2 factors of N, a and b and, if you want the minimum number of moves, this means that your maximum at each step should be minimum. We know for a fact that this minimum is reached when factors are closest to N. Let me give you an example:
36 = 1 * 36 = 2 * 18 = 3 * 12 = 4 * 9 = 6 * 6
We know that sqrt(36) = 6 and you can see that the minimum of 2 factors you can get at this step is max(6, 6) = 6. Sure, 36 is 6 squared, let me take a number without special properties, 96, with its square root rounded down to nearest integer 9.
96 = 2 * 48 = 3 * 32 = 4 * 24 = 6 * 16 = 8 * 12
You can see that your minimum value for max(a, b) is max(8, 12) = 12, which is, again, attained when factors are closest to square root.
Now let's look at the code:
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
if (i*j==n){
You can do this in one loop, knowing that n / i returns an integer, therefore you need to check if i * (n / i) == n. With the previous observation, we need to start at the square root, and go down, until we get to 1. If we got i and n / i as factors, we know that this pair is also the minimum you can get at this step. If no factors are found and you reach 1, which obviously is a factor of n, you have a prime number and you need to use the second instruction:
Decrease the value of N by 1 .
Note that if you go from sqrt(n) down to 1, looking for factors, if you find one, max(i, n / i) will be n / i.
Additionally, if n = 1, you take 1 step. If n = 2, you take 2 steps (2 -> 1). If n = 3, you take 3 steps (3 -> 2 -> 1). Therefore if n is 1, 2 or 3, you take n steps to go to 0. OK, less talking, more coding:
static int downToZero(int n) {
if (n == 1 || n == 2 || n == 3) return n;
int sqrt = (int) Math.sqrt(n);
for (int i = sqrt; i > 1; i--) {
if (n / i * i == n) {
return 1 + downToZero(n / i);
}
}
return 1 + downToZero(n - 1);
}
Notice that I'm stopping when i equals 2, I know that if I reach 1, it's a prime number and I need to go a step forward and look at n - 1.
However, I have tried to see the steps your algorithm and mine takes, so I've added a print statement each time n changes, and we both have the same succession: 7176, 92, 23, 22, 11, 10, 5, 4, 2, 1, which returns 10. Isn't that correct?
So, I found a solution which is working for all the test cases -
static final int LIMIT = 1_000_000;
static int[] solutions = buildSolutions();
public static int downToZero(int n) {
// Write your code here
return solutions[n];
}
static int[] buildSolutions() {
int[] solutions = new int[LIMIT + 1];
for (int i = 1; i < solutions.length; i++) {
solutions[i] = solutions[i - 1] + 1;
for (int j = 2; j * j <= i; j++) {
if (i % j == 0) {
solutions[i] = Math.min(solutions[i], solutions[i / j] + 1);
}
}
}
return solutions;
}
}
i'm just started to learn java yesterday. But, now i met difficulty to show the arithmetic progression like the display below:
1 2 2 2 3 3 3 3 3 4 4 4 4 4 4 4
From that example, i know that every odd numbers, the numbers increment. I've tried to make it, but the display just keep showing like this:
2 4 4 4 6 6 6 6 6 8 8 8 8 8 8 8 10 10 10 10 10 10 10 10 10
Here's my code:
for (int i = 0; i <= 10; i++) {
if (i % 2 == 0) {
for(int j = 1; j<i; j++){
System.out.print(i + " ");
}
}
}
And then, i want to take the last value of it. For example, if i have row = 3, it must be value = 2.
because :
row = 1 2 3 4 5 6 7 8 9 10
value = 1 2 2 2 3 3 3 3 3 4
Would you tell me, what line is exactly must be fix? Thank you
It's not about a line that is wrong, it's your approach that's a bit off. You could fix it in multiple ways. Easiest (but not most efficient) way is this:
for (int i = 0; i <= 10; i++) {
if (i % 2 == 0) {
for(int j = 1; j<i; j++){
System.out.print((i/2) + " ");
}
}
}
As you can see, only the output was changed and now it works. However, iterating over 11 numbers (0-10) when you only really care about 4-5 is not necessarily the best way to go here.
It also doesn't make your code easy to understand.
Here's an alternative.
int amount = 1;
for (int i = 1; i <= 5; i++) {
for (int j = 0; j < amount; j++) {
System.out.print(i + " ");
}
amount = amount + 2;
}
Here you can see that the outer for has been changed to only take the numbers we actually care about, which means we can remove the if completely.
We just have to somehow decide how many times we want to execute the print call, which is done with the amount variable.
Try this.
for (int i = 1, r = 1; i <= 4; ++i, r += 2)
System.out.print((i + " ").repeat(r));
You can calculate value from row with this method.
static int value(int row) {
return (int)Math.ceil(Math.sqrt(row));
}
So you can also do like this.
for (int row = 1; row <= 16; ++row)
System.out.print(value(row) + " ");
result:
1 2 2 2 3 3 3 3 3 4 4 4 4 4 4 4
Hey it's a representation of a sequence that grows by 2 every step.
i.e the first element is 1 which shows up one time.
the second element is 3 which shows up 3 times (2 2 2)
and so on and on..
so the code you need is:
int a = 1;
for(int i=1; i<=10;i++){
int j=1;
while(j<=a){
System.out.print(i);
j++;
}
a+=2;
}
printing the value in a wanted row:
Scanner in = new Scanner(System.in);
int rowU = in.nextInt(); // User inputs row
int row = 1; // a variable to keep track of the rows
int repeats = 1; // the number of times a value shoud appear
for(int value=1;value<=10;value++){
int j=1;
while(j<=repeats){
if(row==rowU) // if we got to the wanted row
System.out.println(value); // print the wanted value
j++;
row++;
}
repeats+=2;
}
There is a better, more efficient way to get the value of a wanted row:
int wanted_value = Math.ceil(Math.sqrt(wanted_row));
Thanks to #saka for bringing this one up!
Hope I helped :)
i % 2 == 0 means that the following code is only going to be executed, if i is even.
You could try removing the if, and change the second for to something like
int j = 0; j < 2 * i - 1; j++.
This code snippet will do the work
int n=4;
int printTimes=1;
for(int i=1;i<=n;i++)
{
for(int j=0;j<printTimes;j++)
System.out.print(i+" ");
printTimes+=2;
}
System.out.println();
Here is the example code.
int start = 1;
int end = 5;
int time = 1;
for (int i = start,j = time; i < end; i++,j+=2) {
for (int k = 0; k < j; k++) {
System.out.print(i+" ");
}
}
The puzzle is to obtain the minimum number of steps it takes to make a number 1. Allowed operations are
1. You can subtract 1 from the number
2. You can divide the number by 2 if it is divisible by 2.
3. You can divide the number by 3 if it is divisible by 3.
At the end, you need to make the number 1 by performing the above operations. I am trying to obtain a solution that gives me the minimum number of the above operations required to make the number 1.
My code (in Java) is as follows.
public int minStepsBottomUp(int n) {
int[] memoArray = new int[n+1];
memoArray[0] = 0;
memoArray[1] = 0;
for(int i=2;i<=n;++i){
int r = 1 + memoArray[i-1];
if(n % 2 == 0) {
r = Math.min(r, 1+memoArray[n/2]);
}
if(n % 3 == 0) {
r = Math.min(r, 1+memoArray[n/3]);
}
memoArray[i] = r;
}
return memoArray[n];
}
But I get some ambiguous results.Example - if the number is 5, I get the minimun number of steps required as 4. Actually it should be 3. Can someone please explain where I have gone wrong?
I suggest reversing the problem: starting from 1 we should reach n by using three kinds of operations:
add 1
multiply by 2
multiply by 3
For instance for 5 we'll have 3 operations (multiply by 3, add 1, add 1):
1 -> 3 -> 4 -> 5
So far so good, now we have standard dynamic programming problem; C# implementation:
private static int Best(int value) {
if (value <= 0)
return -1; // or throw ArgumentOutOfRangeException
else if (value == 1)
return 0;
Dictionary<int, int> best = new Dictionary<int, int>() { {1, 0} };
List<int> agenda = new List<int>() { 1 };
for (int step = 1; ; ++step)
for (int i = agenda.Count - 1; i >= 0; --i) {
int item = agenda[i];
agenda.RemoveAt(i);
int[] next = new int[] { item + 1, item * 2, item * 3 };
foreach (int v in next) {
if (v == value)
return step;
if (!best.ContainsKey(v)) {
best.Add(v, step);
agenda.Add(v);
}
}
}
}
Tests:
// 3
Console.WriteLine(Best(5));
// 3
Console.WriteLine(Best(10));
// 7
Console.WriteLine(Best(100));
// 19
Console.WriteLine(Best(1000000));
Inside your loop, you are using n instead of i.
For instance, n % 2 == 0 should be i % 2 == 0
If the number is 5 you can get 1 by doing:
int x = 5 - 1;
x = x - 1;
x= x / 3;
How to write a recursive method in Java which prints the combinations of 3 different numbers with variable count of the numbers used? (No repetitions should be included.) That is, the method should work for different combination lengths. For example, with the numbers 0, 1, 2 and two numbers used in the combinations you should have: 0 0 - 0 1 - 0 2 - 1 1 - 1 2 - 2 2.
With the same numbers, combinations of 3 numbers are:
0 0 0 - 0 0 1 - 0 0 2 - 0 1 1 - 0 1 2 - (...),
and so on.
I have checked several types of recursion methods in other similar topics, but I still cannot thoroughly understand this and write my own method.
Maybe try calculating all permutations first. Then move on to calculating combinations. The images on the wiki are very enlightening https://en.wikipedia.org/wiki/Combination
You could try pen and paper through this code as well: Combinations method return issue!
I have come up with a non-recursive solution based on counting the numbers of an n-based numeral system. E.g., for system with base 3, numbers are added which are powers of 3.
It should be noted that this prints all combinations, and the ones with repetitive elements should be later removed, as is needed in my case. For example, from the combinations 001, 010, 100, only the first one should be left, where the elements are in ascending order.
public static void main(String[] args) {
int t = 2;
int r = 2;
ArrayList<Integer> l = new ArrayList<Integer>();
int tmp;
for (int p = 0; p <= (int)(Math.pow((double)t, (double)r)) - 1; p++) {
tmp = p;
for (int q = r - 1; q >= 0; q--) {
for (int s = t - 1; s >= 0; s--) {
if (tmp >= s * (int) (Math.pow(t, q))) {
l.add(Integer.valueOf(s));
tmp = tmp - s * (int) (Math.pow(t, q));
break;
}
}
}
}
for (int i = 0; i <= l.size() - 1; i++) {
if (i % r != r - 1) {
System.out.print(l.get(i) + "-");
} else {
System.out.println(l.get(i));
}
}
}
Hey guys so I'm working on a problem where I need to print
1 2 3 4 5 6
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1
public class Set_5_P5_18b {
public static void main(String[] args) {
int x;
String y;
x = 1;
y = "";
System.out.println("Pattern B:");
while (x < 7) {
y = y + x + " ";
x++;
}
System.out.println(y);
}
}
What I wrote above print's the first line but I can't figure out how to modify it to print the second, could anyone help me please?
Yuo need the outer for loop to run for say x ranging from values 6 to 1. For each value of x you need a inner loop that runs for values 1 ... x and prints out values in a line.
Keep this in mind and try to come up with pseudo code first and then the implementation code.
you'd have to reset the variables x, when you quit while :P
So commonly when you are writing a for loop and you realize that you want a certain aspect of the for loop to change each time the program iterates, 9/10 times you want to use nested for loops (for loop within a for loop).
So essentially every time that you iterate through the for loop you want to have the duration of the for loop decrease. So...
for (int num =1; num < <number that you want to change>; num++) {}
Here is the code method.
public static void print(int x) {
for (int lengthOfFor = x; lengthOfFor > 0; lengthOfFor--) {
for (int num = 1; num <= lengthOfFor; num++) {
System.out.print(num + " ");
}
System.out.print("\n");
}
}
This is how you would do call the method.
public class print
{
public static void print(int x) {
for (int lengthOfFor = x; lengthOfFor > 0; lengthOfFor--) {
for (int num = 1; num <= lengthOfFor; num++) {
System.out.print(num + " ");
}
System.out.print("\n");
}
}
public static void main (String[] args) {
print(6);
}
}
Your output can be observed like a 2-dimensional array where:
index i grows top-to-bottom and represents row index
index j grows left-to-right and represents column index
What you are doing right now is iterating over the columns of the first row and that is it.
As mentioned in the comments, you should add a second loop to iterate over the rows as well.
Here is how you can achieve this with two for loops:
int colSize = 6;
int rowSize = 6;
for(int i = 1; i <= rowSize; i++) {
for(int j = 1; j <= colSize; j++) {
System.out.print(j + " "); // print individual column values
}
System.out.println(); // print new line for the next row
colSize--; // decrement column size since column size decreases after each row
}
java-8 solution:
public static void printPattern(int rows) {
IntStream.range(0, rows).map(r -> rows - r).forEach(x -> {
IntStream.rangeClosed(1, x).forEach(y -> {
System.out.print(String.format("%3d", y));
});
System.out.println();
});
}
Usage:
printPattern(9);
Output:
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7
1 2 3 4 5 6
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1