product of the numbers in list in java - java

My task here is to find the minimal positive integer number say 'A' so that the product of digits of 'A' is exactly equal to N.
example: lets say my N = 32
so my A would be 48 coz the divisors of 32 would be 1,2,4,8,16,32 and the minimum numbers that would make 32 is 4 and 8. so output is 48.
what i did is first read N, then found the divisors and stored them in a list. and used
if(l.get(i)*l.get(i+1)==N) {
sysout.print(l.get(i));
sysout.print(l.get(i+1));
but im not able to make the numbers as minimum. and also i need to print as -1 if no match is found.
for that i did:
if (l.get(i)*l.get(i+1)!=N) {
System.out.print(-1);
break;
}
but it is printing -1 initially only and breaking off. now im stuck here. please find my code below:
my code:
int N=1;
Scanner in = new Scanner(System.in);
List<Integer> l = new ArrayList<Integer>();
System.out.println("Enter N: ");
if (N>=0 && N<=Math.pow(10, 9)) {
N = in.nextInt();
}
for (int i=1; i<=N;i++) {
if (N%i==0) {
l.add(i);
}
}
System.out.println(l);
for (int i=0; i<l.size()-1;i++) {
if (l.get(i)*l.get(i+1)==N) {
System.out.print(l.get(i));
System.out.print(l.get(i+1));
}
}
in.close();
kindly help. thanks.

You're on the right track with finding the divisors on N. I'm not going to code it for you(you'll learn more by doing) but here's what you do: The divisors will be sorted already so loop the arraylist adding first to last and finding the min.
So for 1,2,4,8,16,32: Find 1+32, 2+16, 4+8; And then fin the max among these.
This is to get you started:
int first = 0;
int last = l.size()-1;
while(first<last){
//Find min using Math.min;
++first;
--last;
}
Happy Coding!
Could not resist. Below is a quick way to do what you want. Tested it here
(https://ideone.com/E0f4X9):
public class Test {
static ArrayList<Integer> nums = new ArrayList<>();
public static void main(String[] args){
int N =32;
findDivisors(N);
int first = 0, a = 0, b = 0;
int last = nums.size()-1;
int results = Integer.MAX_VALUE;
while(first < last){
int sum = nums.get(first) + nums.get(last);
results = Math.min(sum,results);
a = nums.get(first);
b = nums.get(last);
first++;
last--;
}
System.out.println(a+" "+b);
}
private static void findDivisors(int n){
for(int i=1; i<=n; i++){
if(n%i == 0){
nums.add(i);
}
}
}
}

Obviously if N<10 then A=N.
Otherwise A has to consist of more than one digit. Every digit of A is a divisor of N. The more significant digits of A always have to be less or equal than the lesser significant digits. Otherwise the order of digits could be changed to produce a smaller number.
For example A could not be 523 because the digits could be rearranged into 235 which is a smaller number. In this example we have 2 < 3 < 5.
Observation #1: when looking at A the smallest digits are at the front, the digits get higher towards the end.
Observation #2, A can never contain two digits a and b if the product of a and b is also a digit. For example, there can never be a 2 and a 3, there would have to be a 6 instead. There could never be three 2s, it would have to be an 8 instead.
This suggests that when building A we should start with the highest possible divisors of N (because a 9 is always better than two 3s, and so on). Then we should put that digit at the end of A.
So, while N > 10, find the highest divisor x of N that is a single digit (2<=x<=9). Add this value x to the end of A. Divide N by x and proceed with the loop.
Example:
N=126, A=?
Highest possible divisor x that is less or equal to 9 is 9. So 9 is going to be the last digit of A.
Divide N by 9 and repeat the process. N=126/9=14.
Now N=14, A=?9
Highest possible divisor x that is less or equal to 9 is 7. We have found the second to last digit of A.
Divide N by 7 and repeat the process. N=14/7=2.
Now N=2, A=?79
N<10. So 2 is the first digit of A.
The solution is A=279

Related

Reduce time complexity of game program

Adam wants to watch a football game from the top of the building that is arranged in a straight line.
Adam can watch the football match from the top of ith building if
there exists a maximum of K[i] buildings in front of Adam with a
height less than or equal to the height of ith building.
If there is any building in front of Adam with a height more than
the height of ith position building then he cannot see the match
from this ith building.
Count the positions of buildings where Adam can see the match from the top of the buildings.
Example:
Both arrays have the same length.
B (Buildings) = [2,1,3] represents the height of buildings
K = [1,2,1]
Answer:
1
Explanation:
For B[0] = 2 we have K[0] = 1. The number of buildings in front of it that have a height smaller than or equal to 2 is 0. This is <= K[0] So Adam can see the match.
For B[1] = 1, we have K[1] = 2. The number of buildings in front of it that have a height smaller than or equal to 1 is 0. But B[0] = 2 so Adam cannot see the match.
For B[2] = 3, we have K[2] = 1. The number of buildings in front of it that have a height smaller than or equal to 3 is 2. But this value is >= K[2] i.e 1 so Adam cannot see the match
The total positions where Adam can see the match is 1.
Constraints:
Array size is 1 to 10^5
Each element in Arrays is 1 to 10^5
This is the code I tried with the time complexity of O(n^2):
public static int process(int[] buildings, int[] K) {
int n = buildings.length;
int answer = 0;
for(int i=0; i<n; i++) {
int count = 0;
boolean valid = true;
for(int j=i-1; j>=0; j--) {
if(buildings[j] <= buildings[i]) count++;
if (buildings[j] > buildings[i]) {
valid = false;
break;
}
}
if(valid && count <= K[i]) answer++;
}
return answer;
}
This program works for arrays of small size but fails for large arrays as the time complexity of my program is O(n^2).
What is the better approach to solve this and how can we reduce the time complexity?
you have 2 conditions which we look on one by one but we'll start from the second:
The second condition can be interpreted as if ith building is the highest building from any other building in front of it. this can be achieved by checking the max hight to the ith position and update it as you go.
if the second condition is true that's means you have i-1 buildings in front of the ith building that are equal or smaller than it (i instead of i-1 if you start to count from 0 like in array). so the first condition would be true only if k[i] is bigger than (i-1) you just need to compare between them.
here is the code in java:
import java.util.*;
class HelloWorld {
public static void main(String[] args) {
List<Integer> buildings = Arrays.asList(2, 1, 3);
List<Integer> K = Arrays.asList(1, 2, 1);
System.out.println(process(K, buildings));
}
public static Integer process(List<Integer> K, List<Integer> buildings){
Integer maxHightBuilding = buildings.get(0);
Integer sum = 0;
for(Integer i = 0; i < buildings.size(); i++){
if(buildings.get(i) >= maxHightBuilding ){
maxHightBuilding = buildings.get(i);
if(i <= K.get(i)){
sum++;
}
}
}
return sum;
}
}
I think if you retain the biggest value in front of the actual index, you can just check with the value and when your index passes the biggest value you can update it.
So find the biggest value from the end of the array.
HF!

Writing a method that outputs a different uniqe permutation of a number every time it's called

I got this interview question and I am still very confused about it.
The question was as the title suggest, i'll explain.
You are given a random creation function to use.
the function input is an integer n. let's say I call it with 3.
it should give me a permutation of the numbers from 1 - 3. so for example it will give me 2, 3 , 1.
after i call the function again, it won't give me the same permutation, now it will give me 1, 2, 3 for example.
Now if i will call it with n = 4. I may get 1,4,3,2.
Calling it with 3 again will not output 2,3,1 nor 1,2,3 as was outputed before, it will give me a different permutation out of the 3! possible permutations.
I was confused about this question there and I still am now. How is this possible within normal running time ? As I see it, there has to be some static variable that remembers what was called before or after the function finishes executing.
So my thought is creating a static hashtable (key,value) that gets the input as key and the value is an array of the length of the n!.
Then we use the random method to output a random instance out of these and move this instance to the back, so it will not be called again, thus keeping the output unique.
The space time complexity seems huge to me.
Am I missing something in this question ?
Jonathan Rosenne's answer was downvoted because it was link-only, but it is still the right answer in my opinion, being that this is such a well-known problem. You can also see a minimal explanation in wikipedia: https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order.
To address your space-complexity concern, generating permutations in lexicographical ordering has O(1) space complexity, you don't need to store nothing other than the current permutation. The algorithm is quite simple, but most of all, its correctness is quite intuitive. Imagine you had the set of all permutations and you order them lexicographically. Advancing to the next in order and then cycling back will give you the maximum cycle without repetitions. The problem with that is again the space-complexity, since you would need to store all possible permutations; the algorithm gives you a way to get the next permutation without storing anything. It may take a while to understand, but once I got it it was quite enlightening.
You can store a static variable as a seed for the next permutation
In this case, we can change which slot each number will be put in with an int (for example this is hard coded to sets of 4 numbers)
private static int seed = 0;
public static int[] generate()
{
//s is a copy of seed, and increment seed for the next generation
int s = seed++ & 0x7FFFFFFF; //ensure s is positive
int[] out = new int[4];
//place 4-2
for(int i = out.length; i > 1; i--)
{
int pos = s % i;
s /= i;
for(int j = 0; j < out.length; j++)
if(out[j] == 0)
if(pos-- == 0)
{
out[j] = i;
break;
}
}
//place 1 in the last spot open
for(int i = 0; i < out.length; i++)
if(out[i] == 0)
{
out[i] = 1;
break;
}
return out;
}
Here's a version that takes the size as an input, and uses a HashMap to store the seeds
private static Map<Integer, Integer> seeds = new HashMap<Integer, Integer>();
public static int[] generate(int size)
{
//s is a copy of seed, and increment seed for the next generation
int s = seeds.containsKey(size) ? seeds.get(size) : 0; //can replace 0 with a Math.random() call to seed randomly
seeds.put(size, s + 1);
s &= 0x7FFFFFFF; //ensure s is positive
int[] out = new int[size];
//place numbers 2+
for(int i = out.length; i > 1; i--)
{
int pos = s % i;
s /= i;
for(int j = 0; j < out.length; j++)
if(out[j] == 0)
if(pos-- == 0)
{
out[j] = i;
break;
}
}
//place 1 in the last spot open
for(int i = 0; i < out.length; i++)
if(out[i] == 0)
{
out[i] = 1;
break;
}
return out;
}
This method works because the seed stores the locations of each element to be placed
For size 4:
Get the lowest digit in base 4, since there are 4 slots remaining
Place a 4 in that slot
Shift the number to remove the data used (divide by 4)
Get the lowest digit in base 3, since there are 3 slots remaining
Place a 3 in that slot
Shift the number to remove the data used (divide by 3)
Get the lowest digit in base 2, since there are 2 slots remaining
Place a 2 in that slot
Shift the number to remove the data used (divide by 2)
There is only one slot remaining
Place a 1 in that slot
This method is expandable up to 12! for ints, 13! overflows, or 20! for longs (21! overflows)
If you need to use bigger numbers, you may be able to replace the seeds with BigIntegers

Output for finding Sum of the subarray do not come as Expected

Prateek wants to give a party to his N friends on his birthday, where each friend is numbered from 1 to N. His friends are asking for a gift to come to the party, instead of giving him one. The cost of the gifts are given in the array Value where ith friend asks for a gift which has a cost Costi.
But, Prateek has only X amount of money to spend on gifts and he wants to invite his friends which are in continuous range such that sum of the cost of the gifts of those friends will be exactly equal to X.
If he can invite his friends, who can satisfy the above condition then, print YES otherwise print NO.
Input:
The first line contains a single integer T, denoting the number of test cases. In each test case, the following input will be present: - The next line contains two space-separated integers N and X, where N represents the number of friends and X represents amount of money which Prateek can spend on gifts.
- Next N line contains N integers, where ith line contains ith integer, which represents the Costi .
Ouput
Output exactly T lines, each containing the answer to the corresponding test case .
Constraints:
1 <= T <= 10
1 <= N , Costi <= 106
1 <= X <= 1012
Sample Input(Plaintext Link)
1
5 12
1
3
4
5
2
Sample Output(Plaintext Link)
YES
MyApproach
I followed what is said to take the input and took the subarry sum for every element.But I am not getting Expected output.
public static void counCondition()
{
boolean b1=false;
int Sum=0;
Scanner sc=new Scanner(System.in);
int T=sc.nextInt();
for(int i=1;i<=T;i++)
{
sc.nextLine();
String nextLine = sc.nextLine(); //#Edited my mistake
String[] input = nextLine.split("\\s+");
int p = Integer.parseInt(input[0]);
int c = Integer.parseInt(input[1]);
int Cost[]=new int[p];
for(int j=0;j<Cost.length;j++)
{
Cost[j]=sc.nextInt();
}
for(int k=0;k<Cost.length;k++)
{
Sum=0;
for(int l=k;l<p;l++)
{
Sum=Sum+Cost[l];
if(Sum>c)
{
break;
}
else if(Sum==c)
{
b1=true;
break;
}
}
}
if(b1==true)
{
System.out.println("YES");
}
else
{
System.out.println("NO");
}
}
sc.close();
}
//#Edit Output is still the same.
**ActualInput** **ExpectedInput**
1 1
5 12 5 12
1 1
3 3
4 4
5 5
2 2
6
7
8
9
2
**ActualOutput** Expected Output(Plaintext Link)
NO YES
I am not expecting this output.
Can anyone guide me why?
Once you have got the individual cost in the Cost array.
Here is the logic to get continous sum equal to max sum.
Maintain a start index variable telling from where continous sequence is starting. In the start it should be zero index.
Maintain sum variable to track the total sum.
Run a for loop from zero to endIndex.
if sum less than max sum
Add Cost[i] to sum.
else if sum equals max sum, break the for loop
else if sum greater than max sum
Now remove elements from startIndex till sum again becomes less or equal to max sum using while loop.
while(sum > maxSum)
sum = sum - cost[startIndex]
increment startIndex
while loop finished
if sum equals maxsum, break the loop you got your answer
else continue the outer for loop.
The idea of this logic is to keep removing elements from start from the sum whenever sum increases the maxsum.
Scanner sc=new Scanner(System.in);
int t=sc.nextInt();
while(t>0)
{
int n=sc.nextInt();
long x=sc.nextLong();
long[] money=new long[n];
for(int i=0;i<n;i++)
{
money[i]=sc.nextInt();
}
long sum;
int c=0;
sum=money[0];
for(int i=1;i<n;i++)
{
if(sum<x)
sum=sum+money[i];
else if(sum==x)
break;
while(sum>x)
{
sum=sum-money[c];
c++;
}
}
if(sum==x)
System.out.println("YES");
else
System.out.println("NO");
t--;
}
here http://jayarampandava.blogspot.in/2015_10_01_archive.html
you can find the actual solution
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at app.HackerEarth25Dec2015.counCondition(HackerEarth25Dec2015.java:18)
The exception is occurring because you are calling next() method not the nextLine(). The next() method return the next token which 5 here not the complete line.
Also I would suggest you to use the nextInt() from the Scanner instead of getting the String and splitting and parsing it. That would be a cleaner way of doing things.
int p = sc.nextInt();
int c = sc.nextInt();
Also your logic is also not correct. I hope you will find the logical error and fix it.
You can use the below code for fixing the issue.
sc.nextLine(); // This is to read the `\n` left from previous `nextInt()`
String nextLine = sc.nextLine();
String[] input = nextLine.split("\\s+");

Adding two integers together using only 1's

http://puu.sh/8ekfm.png
Zonko's government (The Kingdom of Zumbania) decided to ban directly adding numbers greater than 1 to other numbers. Zonko decided to create his own addition method (for positive integers) to circumvent the ban. Can you help finish his code?
To get the sum of a and b, Zonko starts by setting a variable sum equal to a. He then repeatedly adds 1 to sum until it reaches a+b. 1 is added every iteration of the loop until its been added the right number of times. What is the correct condition in the loop so it stops at the right time?
public int add(int a, int b){
int sum = a;
for(int i=1; LOOP-CONDITION; i=i+1){
sum = sum + 1; //this will add 1 to sum every iteration
}
return sum;
}
Can someone explain this and tell me how they got the answer?
The Java idiomatic for loops to perform an action a certain number of times are:
for(int i=1; i <= [numTimes]; i=i+1){
and
for(int i=0; i < [numTimes]; i=i+1){
The former has the correct starting condition, so your loop condition would be: i <= b.
The trick is in the words :
Zonko's government (The Kingdom of Zumbania) decided to ban directly
adding numbers greater than 1 to other numbers.
This means a cannot be added to b directly when b is greater than 1.
Assume you want to add a = 5 and b = 3. You can get the answer by adding 1 to 5 three times.
a = 5;
loop(b times){
a = a + 1;
}
Here is how the loop will go:
a = 5;
loop starts
a = 5 + 1;
a = 6 + 1; // we made it 6 in previous step
a = 7 + 1;
loop ends

abundant sums, logic

I have been working on the problem below but I get the wrong answer. What is wrong with my logic?
A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.
A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.
As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.
Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.
Here is my code:
public class EulerProblem23 {
public static void main(String[] args) {
//First, I create an array containing all the numbers ranging from 1 to 28123.
int[] tall = new int[28123];
int x = 0;
for (int j = 1;j<=28123;j++){
tall[x] = j;
x++;
}
//Then, give all the numbers that can be written as the sum of two abundant numbers
//the value 0.
int forrige = 0;
for (int i = 1;i<=28123;i++){
if (isAbundant(i)){
if (2 * i <= 28123){
tall[i - 1] = 0;
}
if (forrige + i <= 28123){
tall[i - 1] = 0;
}
}
}
//All that's left should be summing all the numbers in the array.
long sum = 0;
for (int y = 0;y<28123;y++){
sum += tall[y];
}
System.out.println(sum);
}
public static boolean isAbundant(int n){
int sumAvDivisorer = 0;
for (int i = 1;i<n;i++){
if (n % i == 0){
sumAvDivisorer += i;
}
}
if (sumAvDivisorer > n){
return true;
}
else {
return false;
}
}
}
Is there something wrong with my logic here? Wouldn't all of the integers that can be defined as the sum of two abundant numbers become 0?
I would do it like this:
Make an array of all abundant numbers.
Add all pairs together. You can do this with nested for loops.
For every pair that adds to a number less than or equal to 28123, add the sum of that pair to the total sum.
This code makes no sense:
//Then, give all the numbers that can be written as the sum of two abundant numbers
//the value 0.
int forrige = 0;
for (int i = 1;i<=28123;i++){
if (isAbundant(i)){
if (2 * i <= 28123){
tall[i - 1] = 0;
}
if (forrige + i <= 28123){
tall[i - 1] = 0;
}
}
}
Supposedly, what you want to know if, for each i in the loop, if there are two numbers j and k which are both abundant and such that j + k = i.
Your code has no relation with it. Also, the second if has little meaning, as forrige is always 0.
What I would do.
1) An array of booleans [0, 28123]. True if the number is abundant (previous step). (*)
2) Another array [0, 28123]. True if the number in the position is the add of two abundant numbers. Loop i from 1 to 28123, for each i, loop z from 1 to i/2 (either j <= i/2 or k <= i / 2). For each z, check in the previous array for z and i-z, if both are true set the value to true.
3) Loop the previous array and add all the indexes that are true in the array.
Alternatively, is the condition of "abundant" is sparse enough, you could replace 1) with a list of the numbers which are abundant, and a hashset of them. So, instead of running j from 1 to i/2, you loop this list until you get to i/2 (use the hashset to find quickly if i-j is abundant or not).
Anyway, the idea in this problem is precalculating the values that you will be using again and again, instead of repeating the isAbundant calls to the same values time after time.

Categories

Resources