Finding Multiples of a number between a range [Java] - java

We have been given a range A<=B and a number M. We have to find how many multiples of M lie in the given range.
My Solution:
import java.util.Scanner;
class ABC {
public static void main(String args[] ) throws Exception {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
for (int i = 0; i < N; i++) {
long A = sc.nextLong();
long B = sc.nextLong();
long M = sc.nextLong();
int res = 0;
while(A<=B)
{
if(A%M==0)res++;
A++;
}
System.out.println(res+"");
}
}
}
Now this is not very efficient. Please tell me how this problem can be solved in least amount of time.

The smallest integer n1 such that n1*M ≥ A is n1=ceil(A/M), and the largest integer n2 such that n2*M ≤ B is n2=floor(B/M). The number of integers between n1 and n2 inclusive is max_of(n2−n1+1 ; 0).
Combining the above we have the answer:
max_of(floor(Z/X)−ceil(Y/X)+1 ; 0)
This is a somewhat standard problem in competitive programming :D

Following should do it (after some more testing).
int r = (b/m - a/m) + (a % m == 0 ? 1 : 0);
explanation
find the amount of multiples m between a/m and b/m
if a is a multiple of m add one more (a % m == 0 ? 1 : 0)
small example PoC
public static void main(String[] args) throws Exception {
int[][] pairs = {{10, 24}, {10, 25}, {11, 24}, {11, 25}, {10, 27}};
int m = 5;
for (int[] pair : pairs) {
int a = pair[0];
int b = pair[1];
int r = (b/m - a/m) + (a % m == 0 ? 1 : 0);
System.out.printf("a: %d b: %d result = %d ", a, b, r);
for (int i = a; i <= b; i++) {
if (i % m == 0) {
System.out.print(" " + i);
}
}
System.out.println("");
}
}
output
a: 10 b: 24 result = 3 10 15 20
a: 10 b: 25 result = 4 10 15 20 25
a: 11 b: 24 result = 2 15 20
a: 11 b: 25 result = 3 15 20 25
a: 10 b: 27 result = 4 10 15 20 25

Try this code :
long A = sc.nextLong();
long B = sc.nextLong();
long M = sc.nextLong();
if (M > A) {
A = M;
}
if(M > B){
System.out.println("0");
return;
}
System.out.println( (((B-A)/M)+1) + "");
Explanation :
if 2 is first multiple than we dont need to check for 3, we have to add 2 to get next multiple so we dont need to traverse from first value to last and check if value is multiple or not, we just need to find first multiple and than number of steps it will take to reach last number means our B by adding M to A.

This works great.
int multiples = 0;
for(int i = x; i<=y; i++){
if(i%z==0)
multiples++;
}
As long as y>x, if that isn't always true just add an additional if statement that checks if y>x or x>y. :)

Related

Down to Zero II

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

My loop is ending wrong, it's exceeding the limit I've given

I'm trying to resolve this problem: Given integer N. Print all the squares of natural numbers, not exceeding N, in ascending order.
For example, lets say N = 50, it prints =
1
4
9
16
25
36
49
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int b = 0;
while (N > b){
b++;
int m = b*b;
System.out.println(m);
if (N < m){
break;
}
With my code I'm getting
1
4
9
16
25
36
49
64
So, it's kinda working but it's exceeding my int N for some reason. Even though the condition states that if N < m, it should break.
What you should do is to, break from loop if condition is met, else print the value. I have rearranged the code below by moving the print statement below the condition -
if (N < m){
break;
}
System.out.println(m);
Your logic is a bit off, you want b + 1 <= Math.sqrt(N). Like,
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int b = 0;
while (b + 1 <= Math.sqrt(N)) {
b++;
System.out.println(b * b);
}

Is there something wrong with my id array?

This program pulls two columns from the input.txt file where the first column indicates the value of the object, and the second column represents the weight. The values are imported and placed into two arrays: the value array and the weight array. The knapsack calculations are then made. There are 23 objects in total represented by the rows of the arrays. My code correctly calculates the total value that is being held in the knapsack, and will print out the correct IDs if the weight capacity entered is 5, but for any other weight the IDs being held in the id array are not correct, but the total value printed out is. Here is my code for both files, and if anyone is able to figure out how to correctly save and print the IDs being held in the knapsack please let me know . . .
input.txt file:
17 5
12 8
15 22
17 11
33 21
43 15
15 4
44 35
23 19
10 23
55 39
8 6
21 9
20 28
20 13
45 29
18 16
21 19
68 55
10 16
33 54
3 1
5 9
knapsack.java file:
//We did borrow concepts from:
//http://www.sanfoundry.com/java-program-solve-knapsack-problem-using-dp/
import java.util.Scanner;
import java.util.*;
import java.lang.*;
import java.io.*;
public class knapsack
{
static int max(int a, int b)
{
if(a > b)
{
//System.out.println(a);
return a;
}
else
//System.out.println(b);
return b;
}
static int knapSack(int maxCapacity, int weight[], int value[], int n)
{
int track = 0;
int i, w;
int foo1 = 0;
int foo2 = 0;
K = new int[n+1][maxCapacity+1];
// Build table K[][] in bottom up manner
for (i = 0; i <= n; i++)
{
for (w = 0; w <= maxCapacity; w++)
{
if (i==0 || w==0)
K[i][w] = 0;
else if (weight[i-1] <= w)
{
//K[i][w] = max(value[i-1] + K[i-1][w-weight[i-1]], K[i-1][w]);
if(value[i-1] + K[i-1][w-weight[i-1]] > K[i-1][w])
{
K[i][w] = value[i-1] + K[i-1][w-weight[i-1]];
//System.out.println("A: "+i);
}
else
{
K[i][w] = K[i-1][w];
id[track++] = i;
//System.out.println("B: "+i);
}
}
else
{
K[i][w] = K[i-1][w];
}
}
//System.out.println(K[foo1][foo2]);
}
return K[n][maxCapacity];
}
public static void main(String args[])throws java.io.FileNotFoundException
{
Scanner sc = new Scanner(System.in);
int n = 23;
File file = new File("input.txt");
Scanner scanner = new Scanner(file);
id = new Integer [n];
//knapval = new int[n];
//knapweight = new int [n];
int []value = new int[n];
int []weight = new int[n];
for(int i=0; i<n; i++)
{
value[i] = scanner.nextInt();
weight[i] = scanner.nextInt();
}
System.out.println("Enter the maximum capacity: ");
int maxCapacity = sc.nextInt();
System.out.println("The maximum value that can be put in a knapsack with a weight capacity of "+maxCapacity+" is: " + knapSack(maxCapacity, weight, value, n));
System.out.println();
System.out.println("IDs Of Objects Held In Knapsack: ");
//System.out.println();
for(int z = 0; z < n && id[z] != null; z++)
{
System.out.println(id[z]);
}
if(id[0] == null)
System.out.println("All objects are too heavy, knapsack is empty.");
sc.close();
scanner.close();
}
protected static Integer [] id;
protected static int [][]K;
}
Your way of recording your solution in the id array is flawed. At the time you do id[track++] = i;, you don’t yet know whether i will be in your final solution. Because of the nested loops you may even add i more than once. This in turn may lead to overflowing the array with a java.lang.ArrayIndexOutOfBoundsException: 23 (this happens for max capacity 12 and above).
I suggest instead of using id, after your solution is complete you track your way backward through the K array (by Java naming conventions, it should be a small k). It holds all the information you need to find out which objects were included in the maximum value.
private static void printKnapsack(int maxCapacity, int weight[], int value[], int n) {
if (K[n][maxCapacity] == 0) {
System.out.println("No objects in knapsack");
} else {
int w = maxCapacity;
for (int i = n; i > 0; i--) {
if (K[i][w] > K[i - 1][w]) { // increased value from object i - 1
System.out.format("ID %2d value %2d weight %2d%n", i, value[i - 1], weight[i - 1]);
// check that value in K agrees with value[i - 1]
assert K[i - 1][w - weight[i - 1]] + value[i - 1] == K[i][w];
w -= weight[i - 1];
}
}
}
}
The above prints the objects backward. Example run:
Enter the maximum capacity:
13
The maximum value that can be put in a knapsack with a weight capacity of 13 is: 36
ID 13 value 21 weight 9
ID 7 value 15 weight 4
If you want the objects in forward order, inside the for loop put them into a list (you may for instance use id from your old attempt), and then print the items from the list in opposite order.

Project-Euler -- Problem20

I thought I solved this problem but the program output "0". I don't see any problem. Thank you for helping.
Question :
n! means n × (n − 1) × ... × 3 × 2 × 1
For example, 10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800, and the sum of
the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27.
Find the sum of the digits in the number 100!
package projecteuler;
public class problem20 {
public static void main(String[] args)
{
int sayi=0;
int carpim=1;
for(int i=100;i>=1;i--)
{
carpim*=i;
}
String carp=""+carpim;
int[] dizi = new int[carp.length()];
String[] dizis=new String[carp.length()];
for(int i=0;i<carp.length();i++)
{
dizis[i]=carp.substring(i);
}
for(int i=0;i<carp.length();i++)
{
dizi[i]=Integer.parseInt(dizis[i]);
sayi+=dizi[i];
}
System.out.println(sayi);
}
}
100! is 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
, and that exceeds the valid range of an int (by rather a lot). Try using a BigInteger. To get you started,
BigInteger carpim = BigInteger.ONE;
for (int i = 100; i >= 1; i--) {
carpim = carpim.multiply(BigInteger.valueOf(i));
}
System.out.println(carpim);
The output of which is the number mentioned before.
It appears the number is overflowing. https://ideone.com/UkXQ4e
4611686018427387904
-4611686018427387904
-9223372036854775808
-9223372036854775808
0
0
0
You might want to try a different class for the factorial like BigInteger
In college, I got this example for finding n! using this algorithm. this is based on the fact that n! = n * (n-1)! (for example, 5! = 4 * 3!). Using a recursive algorithm:
function factorial(n)
if (n = 0) return 1
while (n != 0)
return n * [factorial(n-1)]
once you have 100!, its easy to parse it as String and make Integers out of it to get the sum
int sum = 0;
for (Character c : yourBigInteger.toString().toCharArray()) {
sum = sum + Integer.parseInt(c.toString());
}
System.out.println(sum);
public static void descomposicionFactorial(int num) {
BigInteger factorial = BigInteger.ONE;
for (int i = num; i > 0; i--) {
factorial = factorial.multiply(BigInteger.valueOf(i));
}
String aux =factorial.toString();
char cantidad[] = aux.toCharArray();
int suma = 0, numero = 0;
for (int i = 0; i <cantidad.length; i++) {
numero = cantidad[i] - '0';
suma += numero;
}
System.out.println(suma);
}

Why the output result of this value is always zero?

I'm running this code, but why the output result of m is always zero here?
This is very strange since m is initialized to 2.
public class ScalabilityTest {
public static void main(String[] args) {
long oldTime = System.currentTimeMillis();
double[] array = new double[100000];
int p = 2;
int m = 2;
for ( int i = 0; i < array.length; i++ ) {
p += p * 12348;
for ( int j = 0; j < i; j++ ) {
double x = array[j] + array[i];
m += m * 12381923;
}
}
System.out.println( (System.currentTimeMillis()-oldTime) / 1000 );
System.out.println( p + ", " + m );
}
}
Since you are always multiplying the value of m with a number and add to m, on the 16th iteration it overflows to become 0.
In fact, since you are multiplying the number with an odd number then add it to the original, you are multiplying it with a even number, which make the trailing 0 bits moves at least one step left, thus it ends with 0:
1 1011110011101110111001000 24763848
2 1111011100110010111011000100000 2073654816
3 1111111111111101111010010000000 2147415168
4 10010100011000001100001000000000 -1805598208
5 10010010100010001100100000000000 -1836529664
6 10001011110000100010000000000000 -1950212096
7 1110010101001001000000000000000 1923383296
8 1001100000100000000000000000 159514624
9 1010011110010000000000000000000 1405616128
10 10001110001000000000000000000000 -1910505472
11 1010100100000000000000000000000 1417674752
12 1000010000000000000000000000000 1107296256
13 11001000000000000000000000000000 -939524096
14 100000000000000000000000000000 536870912
15 10000000000000000000000000000000 -2147483648
16 0 0
Here's an observation: as soon as m reaches 0, executing
m += m * 12381923;
Will keep m at 0.
I wrote a program to output the values of m as it goes, and here's what I found:
2
24763848
2073654816
2147415168
-1805598208
-1836529664
-1950212096
1923383296
159514624
1405616128
-1910505472
1417674752
1107296256
-939524096
536870912
-2147483648
0
Converged after 16 iterations.
For reference, here's the source:
public class Converge {
public static void main(String[] args) {
int m = 2;
long counter = 0; // Unnecessary, but I didn't know how many iterations we'd need!
while (m != 0) {
System.out.println(m);
m += m * 12381923;
counter++;
}
System.out.println(m);
System.out.println("Converged after " + counter + " iterations.");
}
}
Hope this helps!
It is because the int value overflows. The following documentation shows that the maximum value of an int is 2,147,483,647 and by the time the sixteenth iteration occurs, m is greater than this value and hence it overflows.

Categories