Powers of 3 for a given a positive integer A - java

Given a positive integer A, return an array of minimum length whose elements are powers of 3 and have the sum of all the elements equal to A.
For input A = 13:
30 = 1, 31 = 3, 32 = 9.
1 + 3 + 9 = 13.
So A = 13 can be represented as the sum of 1, 3 and 9.
Is there a better way to solve this problem?
public static int[] getSolve(int A) {
List<Integer> binary = new ArrayList<>();
while (A > 0) {
int r = A % 3;
binary.add(r);
A /= 3;
}
// System.out.println(binary.toString());
List<Integer> res = new ArrayList<>();
int j = 0;
for (int i = 0; i < binary.size(); i++) {
if (binary.get(i) != 0) {
while (j < binary.get(i)) {
res.add((int) Math.pow(3, i));
j++;
}
j =0;
}
}
return res.stream().mapToInt(i -> i).toArray();
}

The answer to this question is always the base 3 representation, which is also known as ternary.
My biggest suggestion is that there is no need for your binary data structure. As you are finding the remainders, right there and then you can see whether the remainder is and add the appropriate powers of 3 to your answer.

For python folks, it can be useful
class Solution:
# #param A : integer
# #return a list of integers
def solve(self, A):
bits = []
solution = []
while(A != 0):
bits.append(A % 3);
A = A // 3;
for i in range(len(bits)):
if(bits[i] != 0):
tmp = 0;
while(tmp < bits[i]):
solution.append(pow(3, i));
tmp = tmp + 1
return solution

Related

Fill an array with powers of 3

public class Power {
public static void main(String[] args) {
int base = 3, exponent = 9;
int[] result = new int[10];
System.out.println(result);
while (exponent != 0)
{
result * base = result;
--exponent;
System.out.println(result);
}
}
}
What I would like this code to do is be able to Multiply 1*3 to make 3, put it inside of the array, and multiply it again, and so on and so forth. Basically, it needs to output, 1 3 9 27 81 243 729 2187 6561 19683. How can I store it inside of the array, and also multiply it again?
You could keep a result variable and continue saving it to an array:
int index = 0;
int[] result = new int[10];
int current = 1;
for (int i = 0; i < result.length; ++i) {
result[i] = current;
current *= 3;
}
System.out.println(Arrays.asString(result));
result[0] = 1;
System.out.print(result[0] + " ");
for (int i = 1; i < n; i++) {
result[i] = result[i-1]*3;
System.out.print(result[i] + " ");
}
Let n be one less than the number of entries you want to print.
Your first problem is that assignments need the name on the left side, and the expression on the right side; replace result * base = result; by result = result * base;.
Secondly, result is an array. You’re trying to treat it as a single number.
Thirdly, if you want to fill an array, use a for loop instead of what you currently have:
final int base = 3;
final int[] result = new int[10];
result[0] = 1;
for (int i = 1; i < result.length; i++) {
result[i] = result[i - 1] * base;
}

Explain the behaviour of problem and why use case was rejected?

I had one leetcode challenge, details are below.
Check If Array Pairs Are Divisible by k
Given an array of integers arr of even length n and an integer k.
We want to divide the array into exactly n / 2 pairs such that the sum of each pair is divisible by k.
Return True If you can find a way to do that or False otherwise.
Example 1:
Input: arr = [1,2,3,4,5,10,6,7,8,9], k = 5
Output: true
Explanation: Pairs are (1,9),(2,8),(3,7),(4,6) and (5,10).
Example 2:
Input: arr = [1,2,3,4,5,6], k = 7
Output: true
Explanation: Pairs are (1,6),(2,5) and(3,4).
Example 3:
Input: arr = [1,2,3,4,5,6], k = 10
Output: false
Explanation: You can try all possible pairs to see that there is no way to divide arr into 3 pairs each with sum divisible by 10.
Example 4:
Input: arr = [-10,10], k = 2
Output: true
Example 5:
Input: arr = [-1,1,-2,2,-3,3,-4,4], k = 3
Output: true
Constraints:
arr.length == n
1 <= n <= 10^5
n is even.
-10^9 <= arr[i] <= 10^9
1 <= k <= 10^5
Some basic use case above to evaluate the result.
My Implementation
import java.util.ArrayList;
class Solution {
public static boolean canArrange (int[]arr, int k)
{
if(arr.length % 2 != 0){
return false;
}
int pairs = arr.length / 2;
int[] firstPair = new int[pairs];
int[] secondPair = new int[pairs];
int n =0;
for(int i=0; i<arr.length;i++){
if(i < pairs){
firstPair[i] = arr[i];
}else{
secondPair[n] = arr[i];
n++;
}
}
System.out.println ("pairs =" + pairs);
int divisablePairs = 0;
ArrayList<Integer> firstElement = new ArrayList();
ArrayList<Integer> secondElement = new ArrayList();
for (int i = 0; i < firstPair.length; i++)
{
for (int j = 0; j < secondPair.length; j++)
{
if ((firstPair[i] + secondPair[j]) % k == 0 && (firstPair[i] + secondPair[j]) >= 0)
{
firstElement.add(firstPair[i]);
secondElement.add(secondPair[j]);
System.out.println ("(" + firstPair[i] + "," + secondPair[j] + ")");
divisablePairs++;
}
}
}
return divisablePairs > 0 ? true : false;
}
}
Here one particular use case is getting failed but I am not sure why. Use case give below.
Input:
Array - [9606,4830,4037,-1054,3308,6966,6528,3953,473,-388,9878,-3797,2598,-3283,5813,-6446,-3625,-107,-8756,-3053,-2131,6609,4192,7408,1115,7456,-5674,1219,-8548,540,-9630,-4858,-2453,-726,9902,6192,-7996,1459,-1980,4285,-2659,4156,-2303,-855]
K - 10
My Output:
true
Expected:
false
Someone explain what is the issue with my implementation?
Here we can use an integer map of k size.
This'll pass through:
public class Solution {
public static boolean canArrange(int[] arr, int k) {
int[] countMapRemainders = new int[k];
for (int a : arr) {
int remainder = a % k;
if (remainder < 0) {
remainder += k;
}
countMapRemainders[remainder]++;
}
for (int i = 1; i < k; i++) {
if (countMapRemainders[i] != countMapRemainders[k - i]) {
return false;
}
}
return countMapRemainders[0] % 2 == 0;
}
}
Inputs:
[1,2,3,4,5,10,6,7,8,9]
5
[9606,4830,4037,-1054,3308,6966,6528,3953,473,-388,9878,-3797,2598,-3283,5813,-6446,-3625,-107,-8756,-3053,-2131,6609,4192,7408,1115,7456,-5674,1219,-8548,540,-9630,-4858,-2453,-726,9902,6192,-7996,1459,-1980,4285,-2659,4156,-2303,-855]
10
Outputs:
true
false
References
For additional details, you can see the Discussion Board. There are plenty of accepted solutions with a variety of languages and explanations, efficient algorithms, as well as asymptotic time/space complexity analysis1, 2 in there.

Codility Tape Equilibrium Getting zero on some cases

I just took this sample test, and it's right for the most part, but I am not sure why I would get the two cases wrong.
A non-empty zero-indexed array A consisting of N integers is given.
Array A represents numbers on a tape.
Any integer P, such that 0 < P < N, splits this tape into two
non-empty parts: A[0], A1, ..., A[P − 1] and A[P], A[P + 1], ...,
A[N − 1].
The difference between the two parts is the value of: |(A[0] + A1 +
... + A[P − 1]) − (A[P] + A[P + 1] + ... + A[N − 1])|
In other words, it is the absolute difference between the sum of the
first part and the sum of the second part.
For example, consider array A such that:
A[0] = 3 A1 = 1 A[2] = 2 A[3] = 4 A[4] = 3 We can split
this tape in four places:
P = 1, difference = |3 − 10| = 7 P = 2, difference = |4 − 9| = 5 P =
3, difference = |6 − 7| = 1 P = 4, difference = |10 − 3| = 7 Write a
function:
class Solution { public int solution(int[] A); }
that, given a non-empty zero-indexed array A of N integers, returns
the minimal difference that can be achieved.
For example, given:
A[0] = 3 A1 = 1 A[2] = 2 A[3] = 4 A[4] = 3 the function
should return 1, as explained above.
Assume that:
N is an integer within the range [2..100,000]; each element of array A
is an integer within the range [−1,000..1,000]. Complexity:
expected worst-case time complexity is O(N); expected worst-case space
complexity is O(N), beyond input storage (not counting the storage
required for input arguments).
class Solution {
public int solution(int[] A) {
int sum = 0;
int subtracted = 0;
int minDiff = 100000;
for (int i = 0; i < A.length; i++) {
sum += A[i];
}
for (int i = 0; i < A.length; i++) {
sum -= A[i];
subtracted += A[i];
int diff = (Math.abs(sum - subtracted));
if (minDiff > diff) {
minDiff = diff;
}
}
return minDiff;
}
}
Coldility Result
I wrote in java and achieved 100% on codility
public static int solution(int[] A) {
int sum=0,leftsum=0,rightsum=0,newmin=0,min=0;
for(int i=0;i<A.length;i++){
sum=sum+A[i];
}
for(int i=1;i<A.length;i++){
leftsum=leftsum+A[i-1];
rightsum=sum-leftsum;
//System.out.println(leftsum-rightsum);
if(i==1)
min=newmin=Math.abs(leftsum-rightsum);
else
newmin=Math.abs(leftsum-rightsum);
min=Math.min(min,newmin);
}
return min;
}
Consider this approach using just one for loop: The main idea is to accumulate from left and right at the same time until they cross the middle of the array. At that point, they will start sharing elements in the sum, so you need then to evaluate 2 cases:
1st- subtracting the shared elements from the left side
2nd- subtracting the shared elements from the right side
public int solution(int[] A) {
// write your code in C# 6.0 with .NET 4.5 (Mono)
int l=A.Length;
int mid= l%2>0 ? (l/2) : (l/2)-1;
long ls=0;
long rs=0;
long res=long.MaxValue;
long shared=0;
for(int i=0, j=l-1; i<l; i++, j--){
ls=ls+A[i];
rs=rs+A[j];
if(i>=mid && i<l-1){
if(i==j) shared=A[i];
else if(i>j) shared=shared+A[i]+A[j];
rs=rs-shared;
res= res < Math.Abs(ls-rs) ? res : Math.Abs(ls-rs);
rs=rs+shared;
ls=ls-shared;
res= res < Math.Abs(ls-rs) ? res : Math.Abs(ls-rs);
ls=ls+shared;
}
}
return (int)res;
}
Solved it. Don't use int sum = Arrays.stream(A).sum();, it fails the performance tests. I got all test case right except one with int sum = Arrays.stream(A).sum(); but it timed out on the largest test case. So I changed it to a for loop sum and it passed with 100%.
public int solution(int[] A) {
int result = Integer.MAX_VALUE;
int total = 0;
int sum = 0;
for (int i = 0; i < A.length; i++) {
sum += A[i];
}
for (int i = 0; i < A.length - 1; i++) {
total += A[i];
int toEndSum = sum - total;
int diff = Math.abs(total - toEndSum);
if (diff < result)
result = diff;
}
return result != Integer.MAX_VALUE ? result : 0;
}

Finding the greatest common divisor (GCD) of an array excluding some elements in minimum time

I was doing a competitive programming question whereby you are given an array of numbers, and then a certain number of queries. For each query, you are given 2 integers, 'a' and 'b'. So you're supposed to output the GCD of the remaining elements in the array (excluding a, b , and all the elements in between).
For example, if the array is : 16, 8, 24, 15, 20 and there are 2 queries (2, 3) and (1, 3), then output 1 is: 1 and output 2 is: 5.
Note that the indexing is 1 based.
Here is my code, in which I've implemented the basic idea with a function for finding the GCD of an array passed to it.
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(br.readLine());
while (t-- > 0) { //This is the number of test cases
String[] s1 = br.readLine().split(" ");
int n = Integer.parseInt(s1[0]); //Number of elements in array
int q = Integer.parseInt(s1[1]); //Number of queries
String[] s2 = br.readLine().split(" ");
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(s2[i]);
}
for (int i = 0; i < q; i++) { //for each query
String[] s3 = br.readLine().split(" ");
int a = Integer.parseInt(s3[0]) - 1;
int b = Integer.parseInt(s3[1]) - 1;
int[] copy = new int[n - b + a - 1]; //this is so that the original array doesn't get messed up
int index = 0;
for (int j = 0; j < n; j++) { //filing the array without the elements of the query
if (j < a || j > b) {
copy[index] = arr[j];
index++;
}
}
int fin = gcd(copy);
System.out.println(fin);
}
}
}
private static int gcd(int a, int b) {
while (b > 0) {
int temp = b;
b = a % b; // % is remainder
a = temp;
}
return a;
}
private static int gcd(int[] input) { //simple GCD calculator using the fact that GCD(a,b,c) === GCD((a,b),c)
int result = input[0];
for (int i = 1; i < input.length; i++)
result = gcd(result, input[i]);
return result;
}
The problem is that I'm getting AC on some of the parts (6 out of 10), and a TLE on the rest. Can someone suggest a better method to solve this problem, as my approach seems too slow, and almost impossible to be optimized any further?
You can just precompute gcd for all prefixes and suffixes. Each query is a union of a prefix and a suffix, so it takes O(log MAX_A) time to answer one. Here is my code:
import java.util.*;
import java.io.*;
public class Solution {
static int gcd(int a, int b) {
while (b != 0) {
int t = a;
a = b;
b = t % b;
}
return a;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
int tests = Integer.parseInt(br.readLine());
for (int test = 0; test < tests; test++) {
String line = br.readLine();
String[] parts = line.split(" ");
int n = Integer.parseInt(parts[0]);
int q = Integer.parseInt(parts[1]);
int[] a = new int[n];
parts = br.readLine().split(" ");
for (int i = 0; i < n; i++)
a[i] = Integer.parseInt(parts[i]);
int[] gcdPrefix = new int[n];
int[] gcdSuffix = new int[n];
for (int i = 0; i < n; i++) {
gcdPrefix[i] = a[i];
if (i > 0)
gcdPrefix[i] = gcd(gcdPrefix[i], gcdPrefix[i - 1]);
}
for (int i = n - 1; i >= 0; i--) {
gcdSuffix[i] = a[i];
if (i < n - 1)
gcdSuffix[i] = gcd(gcdSuffix[i], gcdSuffix[i + 1]);
}
for (int i = 0; i < q; i++) {
parts = br.readLine().split(" ");
int left = Integer.parseInt(parts[0]);
int right = Integer.parseInt(parts[1]);
left--;
right--;
int res = 0;
if (left > 0)
res = gcd(res, gcdPrefix[left - 1]);
if (right < n - 1)
res = gcd(res, gcdSuffix[right + 1]);
out.println(res);
}
}
out.flush();
}
}
"Almost impossible to optimize further"? Pshaw:
Add a cache of computed GCDs of adjacent input elements so they don't need to be re-computed. For example, have a table that holds the GCD of input[i] and input[j]. Note that this will be no more than half the size of the original input.
Compute the GDC of successive pairs of inputs (so you can take advantage of #1)
This could be extended to larger groups, at the cost of more space.
What is crucial here is that the GCD of a set of numbers A is equal to the GCD of the GCDs of any partition of A. For example,
GCD(16, 8, 24, 15, 20) = GCD(GCD(16, 8), GCD(24, 15, 20))
I would exploit this fact by building some tree like structure. Lets write GCD[i, j] for the GCD of the set of elements with indices between i and j. For a given input of size n, I would store:
GCD[1, n]
GCD[1, n/2], GCD[n/2+1, n]
...
GCD[1, 2], GCD[2, 3] ... GCD[n-1, n]
That is, at every level of the tree the number of GCDs doubles and the size of the sets over which they are computed halves. Note that you will store n-1 numbers this way, so you need linear extra storage. Computing them bottom-up, you will need to do n-1 GCD operations as preprocessing.
For querying, you need to combine the GCDs such that exactly the two query indices are left out. As an example, lets have an array A with n = 8 and we query (2, 4).
We cannot use GCD[1, 8], because we need to exclude 2 and 4, so we go one level deeper in the tree.
We cannot use GCD[1, 4], but we can use GCD[5, 8], because neither of the indices to exclude is in there. For the first half we need to go deeper.
We cannot use GCD[1, 2], nor GCD[3, 4], so we go one level deeper.
We simply use the elements A[1] and A[3].
We now need to compute the GCD of GCD[5, 8], A[1], and A[3]. For the query, we need to do only 2 GCD calculations, instead of 5 in the naive way.
In general, you will spend O(log n) time searching the structure and will need O(log n) GCD calculations per query.

codility challenge, test case OK , Evaluation report Wrong Answer

the aluminium 2014 gives me wrong answer [3 , 9 , -6 , 7 ,-3 , 9 , -6 , -10] got 25 expected 28
but when i repeated the challenge with the same code and make case test it gives me the correct answer
Your test case [3, 9, -6, 7, -3, 9, -6, -10] : NO RUNTIME ERRORS (returned value: 28)
what is the wrong with it ???
the challenge :-
A non-empty zero-indexed array A consisting of N integers is given. A
pair of integers (P, Q), such that 0 ≤ P ≤ Q < N, is called a slice of
array A. The sum of a slice (P, Q) is the total of A[P] + A[P+1] + ...
+ A[Q]. The maximum sum is the maximum sum of any slice of A. For example, consider array A such that: A[0] = 3
A[1] = 2
A[2] = -6
A[3] = 3
A[4] = 1 For example (0, 1) is a slice of A that has sum A[0] + A[1] = 5. This is the maximum sum of A. You can perform a single swap
operation in array A. This operation takes two indices I and J, such
that 0 ≤ I ≤ J < N, and exchanges the values of A[I] and A[J]. To goal
is to find the maximum sum you can achieve after performing a single
swap. For example, after swapping elements 2 and 4, you will get the
following array A: A[0] = 3
A[1] = 2
A[2] = 1
A[3] = 3
A[4] = -6 After that, (0, 3) is a slice of A that has the sum A[0] + A[1] + A[2] + A[3] = 9. This is the maximum sum of A after a single swap. Write a function: class Solution { public int solution(int[] A);
} that, given a non-empty zero-indexed array A of N integers, returns
the maximum sum of any slice of A after a single swap operation. For
example, given: A[0] = 3
A[1] = 2
A[2] = -6
A[3] = 3
A[4] = 1 the function should return 9, as explained above.
and my code is :-
import java.math.*;
class Solution {
public int solution(int[] A) {
if(A.length == 1)
return A[0];
else if (A.length==2)
return A[0]+A[1];
else{
int finalMaxSum = A[0];
for (int l=0 ; l<A.length ; l++){
for (int k = l+1 ; k<A.length ; k++ ){
int [] newA = A;
int temp = newA[l];
newA [l] = newA[k];
newA[k]=temp;
int maxSum = newA[0];
int current_max = newA[0];
for(int i = 1; i < newA.length; i++)
{
current_max = Math.max(A[i], current_max + newA[i]);
maxSum = Math.max(maxSum, current_max);
}
finalMaxSum = Math.max(finalMaxSum , maxSum);
}
}
return finalMaxSum;
}
}
}
i don't know what's the wrong with it ??
It was a bug in the website and this is the reply from the support team
the evaluation system run your program not only on the test case it presented to you, but also on the mirrored test case B = [-10, -6, 9, -3, 7, -6, 9, 3]. On test case B your program indeed returned 22, when it should have returned 28.
public static int findMaxSumOfArray(int[] A) {
int[] T = new int[A.length];
int sum = 0;
int max1 = Integer.MIN_VALUE;
int max2 = Integer.MIN_VALUE;
int max3 = Integer.MIN_VALUE;
int max1index = 0;
int max2intex = 0;
for (int i = 0; i < A.length; i++) {
if (A[i] < 0) {
T[i] = sum;
sum = 0;
} else if (i == A.length - 1) {
sum += A[i];
T[i] = sum;
sum = 0;
} else {
sum += A[i];
}
}
for (int i = 0; i < T.length; i++) {
if (max3 < T[i]) {
if (max2 < T[i]) {
if (max1 < T[i]) {
max2intex = max1index;
max3 = max2;
max2 = max1;
max1 = T[i];
max1index = i;
} else {
max3 = max2;
max2 = T[i];
max2intex = i;
}
} else {
max3 = T[i];
}
}
}
return max1 + max2 + (Math.abs(max1index - max2intex) == 1 ? max3 : 0);
}

Categories

Resources