Related
Function to implement
Code
public class arctan {
public static double arctan(double x) {
double sum = 0;
int k = 0;
double arctan1 = (Math.pow(-1, k) * (Math.pow(x, 2 * k + 1) / (2 * k + 1)));
for (int i = k; i < 100; i++) {
sum =+ arctan1;
}
return (double) arctan1;
}
}
Issue
My program just gives back my x as output. I don't see the mistake I am doing.
You have to put double arctan1 = (Math.pow(-1, k) * (Math.pow(x, 2 * k + 1) / (2 * k + 1))); in the loop as well since that is what the Σ is doing in the formula.
You also didn't need to have a new variable i in the for loop in this case. Using k like the formula is fine.
So it would be like this instead:
public class arctan {
public static double arctan(double x) {
double sum = 0;
for (int k = 0; k < 100; i++) {
sum += (Math.pow(-1, k) * (Math.pow(x, 2 * k + 1) / (2 * k + 1)));
}
return sum;
}
}
What does the letter Σ (sum over) mean?
See Wikipedia about the mathematical sum-symbol (uppercase sigma in Greek alphabet): Σ.
In you case it is the sum over a range from k = 0 until k = infinite.
The sum of the term following the sigma.
Define it as function instead variable
The term following is implemented correctly by:
double arctan1 = (Math.pow(-1, k) * (Math.pow(x, 2 * k + 1) / (2 * k + 1)));
Extract it as function of k and x:
public static double arctan1(int k, double x) {
return ( Math.pow(-1, k) * (Math.pow(x, 2 * k + 1) / (2 * k + 1) ));
}
Because the calculation is depending on inputs k and x now, you can use it in your sum-over range of k:
// Note: the limit is 99 here, not infinite
for (int k = 0; k < 100; k++) {
sum += arctan1( k,x ); // increasing k used as input
}
Put it all together
// your "term following the sum-over" implemented by function arctan1(int k, double x)
public static double arctan(double x) {
double sum = 0;
// your loop to sum-up for increasing k
return sum;
}
I wrote a function that recursively calculates the binomical coefficient term of n and k using the memoizazion methood, I get an OutOfBoundException when i execute, I'll be happy to hear some directions about the mistake I've done.
Thank you all.
public class Binomial {
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
int k = Integer.parseInt(args[1]);
StdOut.print(binomial(n, k));
}
/**
* Recursively calculates the binomical coefficient term of n and k using
* the memoizazion methood
*
* #param n
* the upper nonnegative integer of the binomical coefficient
* #param k
* the lower nonnegative integer of the binomical coefficient
* #returns the computed binomical coefficient
*/
public static long binomial(int n, int k) {
long[][] mem = new long[n + 1][k + 1];
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= n; j++) {
mem[i][j] = -1;
}
}
return binomial(n, k, mem);
}
public static long binomial(int n, int k, long[][] mem) {
if (k > n)
return 0;
if (k == 0 || n == 0)
return 1;
if (mem[n - 1][k] == -1) {
mem[n - 1][k] = binomial(n - 1, k, mem);
}
if (mem[n - 1][k - 1] == -1) {
mem[n - 1][k - 1] = binomial(n - 1, k - 1, mem);
}
return (mem[n - 1][k] + mem[n - 1][k - 1]);
}
}
A very simple mistake cause this error in function public static long binomial(int n, int k) change n in inner for with k, I mean :
public static long binomial(int n, int k) {
long[][] mem = new long[n + 1][k + 1];
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= k; j++) {
mem[i][j] = -1;
}
}
return binomial(n, k, mem);
}
is your correct function.
Recently learned about Cramers rule in precalculus, and decided to make an algorithm in Java to help me understand it better.
The following code works 100% correctly, however it does not use any sort of for loop to do what it does in a much simpler fashion.
Question: Is there a more elegant implementation of Cramers Rule in Java?
I'm thinking that making a basic determinant method, and then doing some column swapping for when I need to take the determinant of Dx, Dy, and Dz. (for Dx, swap column 4 with column 1 of the original matrix, then take determinant and divide by original determinant.)
This sound good?
public static void main(String[] args) {
int[][] matrix = new int[3][3];
matrix[0] = new int[] { 3, 5, -1, -2 };
matrix[1] = new int[] { 1, -4, 2, 13 };
matrix[2] = new int[] { 2, 4, 3, 1 };
int[] r = crame(matrix);
info("x: " + r[0] + ", y: " + r[1] + ", z: " + r[2]);
for(int i = 0; i < matrix.length; i++) {
int[] base = matrix[i];
if(check(base, r, base[3])) {
info("System " + (i+1) + " checks!");
} else {
info("System " + (i+1) + " fails check!");
}
}
}
public static int[] crame(int[][] m) {
int[] result;
if (m.length == 2) {
result = new int[2];
int D = (m[0][0] * m[1][1]) - (m[1][0] * m[0][1]);
int Dx = (m[0][2] * m[1][1]) - (m[1][2] * m[0][1]);
int Dy = (m[0][0] * m[1][2]) - (m[1][0] * m[0][2]);
result[0] = (int) (Dx / D);
result[1] = (int) (Dy / D);
} else if (m.length == 3) {
result = new int[3];
int D = (((m[0][2] * m[1][1] * m[0][2]) + (m[2][1] * m[1][2] * m[0][0]) + (m[2][2]
* m[1][0] * m[0][2])) - ((m[0][0] * m[1][1] * m[2][2])
+ (m[0][1] * m[1][2] * m[0][2]) + (m[0][2] * m[1][0] * m[2][1])));
int Dx = (((m[2][3] * m[1][1] * m[0][2]) + (m[2][1] * m[1][2] * m[0][3]) + (m[2][2]
* m[1][3] * m[0][1])) - ((m[0][3] * m[1][1] * m[2][2])
+ (m[0][1] * m[1][2] * m[2][3]) + (m[0][2] * m[1][3] * m[2][1])));
int Dy = (((m[2][0] * m[1][3] * m[0][2]) + (m[2][3] * m[1][2] * m[0][3]) + (m[2][2]
* m[1][0] * m[0][3])) - ((m[0][0] * m[1][3] * m[2][2])
+ (m[0][3] * m[1][2] * m[2][0]) + (m[0][2] * m[1][0] * m[2][3])));
int Dz = (((m[2][0] * m[1][1] * m[0][3]) + (m[2][1] * m[1][3] * m[0][0]) + (m[2][3]
* m[1][0] * m[0][1])) - ((m[0][0] * m[1][1] * m[2][3])
+ (m[0][1] * m[1][3] * m[2][0]) + (m[0][3] * m[1][0] * m[2][1])));
result[0] = (int) (Dx / D);
result[1] = (int) (Dy / D);
result[2] = (int) (Dz / D);
} else {
return new int[] {};
}
return result;
}
public static int product(int[] a, int[] b) {
int p = 0;
int[] fin = new int[(a.length -1)];
for(int x = 0; x < fin.length; x++) {
fin[x] = a[x] * b[x];
}
for (int f : fin) {
p += f;
}
return p;
}
public static boolean check(int[] a, int[] b, int z) {
return product(a, b) == z;
}
public static void info(String log) {
System.out.println(log);
}
My question pertains to the specific algorithm that can be used to solve systems of equations using Cramers rule only, is there any algorithm that is more elegant? The function is only designed for square matrices.
This is not a homework assignment, after HS I will be studying CS and I've been working on developing algorithms as preliminary practice.
Thank you for checking this out
First of, there is one way in which Cramers rule is perfect: It gives the algebraic solution of a linear system as a rational function in its coefficients.
However, practically, it has its limits. While the most perfect formula for a 2x2 system, and still good for a 3x3 system, its performance, if implemented in the straightforward way, deteriorates with each additional dimension.
An almost literal implementation of Cramers rule can be achieved with the Leverrier-Faddeev algorithm a b. It only requires the computation of matrix products and matrix traces, and manipulations of the matrix diagonal. Not only does it compute the determinant of the matrix A (along with the other coefficients of the characteristic polynomial), it also has the adjugate or co-factor matrix A# in its iteration matrix. The interesting fact about this matrix is that it allows to write the solution of A*x=b as (A#*b)/det(A), that is, the entries of A#*b already are the other determinants required by Cramers rule.
Leverrier-Faddeev requires n4+O(n3) operations. The same results can be obtained by the more complicated Samuelson-Berkowitz algorith, which has one third of that complexity, that is n4/3+O(n3).
The computation of the determinants required in Cramers rule becomes downright trivial if the system (A|b) is first transformed into triangular form. That can be achieved by Gauß elimination, aka LU decomposition (with pivoting for numerical stability) or the QR decomposition (easiest to debug should be the variant with Givens rotations). The efficient application of Cramers rule is then backward substitution in the triangular system.
Your method sounds good to me at least; however, I just may not be aware of any more efficient methods. The not-fun part may be figuring out how to best implement the determinant-calculating method, as apparently it's not an inexpensive operation.
But once you know that that's working, the rest sounds pretty OK to me. Cache the determinant of the original matrix, substitute in columns, etc.
Figured out exactly how to do this effectively.
http://sandsduchon.org/duchon/math/determinantJava.html
Provides a method for seamless determinants, and mentions matrix decomposition. I have not learned this yet as it's not a HS level concept however I did some problems using it and it's a solid method.
Final Code:
public static void main(String[] args) {
int[][] matrix = new int[3][3];
matrix[0] = new int[] { 3, 5, -1, -2 };
matrix[1] = new int[] { 1, -4, 2, 13 };
matrix[2] = new int[] { 2, 4, 3, 1 };
int[] r = crame(matrix);
info("x: " + r[0] + ", y: " + r[1] + ", z: " + r[2]);
for (int i = 0; i < matrix.length; i++) {
int[] base = matrix[i];
if (check(base, r, base[3])) {
info("System " + (i + 1) + " checks!");
} else {
info("System " + (i + 1) + " fails check!");
}
}
}
public static int getDet(int[][] a) {
int n = a.length - 1;
if (n < 0)
return 0;
int M[][][] = new int[n + 1][][];
M[n] = a; // init first, largest, M to a
// create working arrays
for (int i = 0; i < n; i++)
M[i] = new int[i + 1][i + 1];
return getDet(M, n);
} // end method getDecDet double [][] parameter
public static int getDet(int[][][] M, int m) {
if (m == 0)
return M[0][0][0];
int e = 1;
// init subarray to upper left mxm submatrix
for (int i = 0; i < m; i++)
for (int j = 0; j < m; j++)
M[m - 1][i][j] = M[m][i][j];
int sum = M[m][m][m] * getDet(M, m - 1);
// walk through rest of rows of M
for (int i = m - 1; i >= 0; i--) {
for (int j = 0; j < m; j++)
M[m - 1][i][j] = M[m][i + 1][j];
e = -e;
sum += e * M[m][i][m] * getDet(M, m - 1);
} // end for each row of matrix
return sum;
} // end getDecDet double [][][], int
public static int[] crame(int[][] m) {
int[] result;
if (m.length == 2) {
result = new int[m.length];
int D = getDet(m);
for (int i = 0; i < m.length; i++) {
result[i] = getDet(slide(m, i, m.length)) / D;
}
} else if (m.length == 3) {
result = new int[m.length];
int D = getDet(m);
for (int i = 0; i < m.length; i++) {
result[i] = (getDet(slide(m, i, m.length)) / D);
}
} else {
return new int[] {};
}
return result;
}
public static int[][] slide(int[][] base, int col, int fin) {
int[][] copy = new int[base.length][];
for (int i = 0; i < base.length; i++) {
int[] aMatrix = base[i];
int aLength = aMatrix.length;
copy[i] = new int[aLength];
System.arraycopy(aMatrix, 0, copy[i], 0, aLength);
}
for (int i = 0; i < base.length; i++) {
copy[i][col] = base[i][fin];
}
return copy;
}
public static int product(int[] a, int[] b) {
int p = 0;
int[] fin = new int[(a.length - 1)];
for (int x = 0; x < fin.length; x++) {
fin[x] = a[x] * b[x];
}
for (int f : fin) {
p += f;
}
return p;
}
public static boolean check(int[] a, int[] b, int z) {
return product(a, b) == z;
}
public static void info(String log) {
System.out.println(log);
}
There is a variety of answers for the MaxProductOfThree task on codility.com, most of them involving a sorting algorithm.
The problem is:
A non-empty zero-indexed array A consisting of N integers is given.
The problem is to find the maximum product of 3 elements from given array.
The length of the array is between 3 and 100,000
each element of array A is an integer within the range [−1,000..1,000]
expected worst-case time complexity is O(N*log(N));
expected worst-case space complexity is O(1),
beyond input storage (not counting the storage required for input arguments).
Example:
a[0] = -3;
a[1] = 7;
a[2] = 2;
a[3] = 1;
a[4] = 5;
a[5] = 7;
the max product is a[1]*a[4]*a[5] = 245
Is there a linear-time solution to this problem, besides the O(n log n) approach that involves sorting?
/* The method get the max product of 3 consists in basically find the biggest 3 numbers from the array and the smallest 2 numbers from the array in just 1 iteration over the array. Here is the java code:*/
int solution(int[] a) {
/* the minimums initialized with max int to avoid cases with extreme max in array and false minims 0 minimums returned */
int min1 = Integer.MAX_VALUE;
int min2 = Integer.MAX_VALUE;
/* the same logic for maximum initializations but of course inverted to avoid extreme minimum values in array and false 0 maximums */
int max1 = Integer.MIN_VALUE;
int max2 = Integer.MIN_VALUE;
int max3 = Integer.MIN_VALUE;
//the iteration over the array
for (int i = 0; i < a.length; i++) {
//test if max1 is smaller than current array value
if (a[i] > max1) {
//if a[i] is greater than the biggest max then a chain reaction is started,
// max3 will be max2, max2 will be actual max1 and max1 will be a[i]
max3=max2;
max2=max1;
max1=a[i];
/* in case if current a[i] isn't bigger than max1 we test it to see maybe is bigger than second
max. Then the same logic from above is applied for the max2 amd max3 */
}else if(a[i]>max2){
max3 = max2;
max2 = a[i];
/* finally if current array value isn't bigger than max1 and max2 maybe is greater than max3 */
}else if(a[i]>max3){
max3 = a[i];
}
/* The logic from above with maximums is is applied here with minimums but of course inverted to
discover the 2 minimums from current array. */
if (a[i] < min1) {
min2 =min1;
min1=a[i];
} else if (a[i] < min2) {
min2 = a[i];
}
}
/* after we discovered the 3 greatest maximums and the 2 smallest minimums from the array
we do the 2 products of 3 from the greatest maximum and the 2 minimums . This is necessary
because mathematically the product of 2 negative values is a positive value, and because of
this the product of min1 * min2 * max1 can be greater than max1 * max2 * max3
and the product built from the the 3 maximums. */
int prod1 = min1 * min2 * max1;
int prod2 = max1 * max2 * max3;
//here we just return the biggest product
return prod1 > prod2 ? prod1 : prod2;
}
There are only two possible options for the max product in a sorted array.
1) The largest (the last) three elements
2) Combination of two smallest and the largest elements (in case of negative elements, a product of two negatives is positive which multiplied with the largest element, if positive, of an array can produce the largest product)
So the solution is a max of the two and nothing else. The below got 100/100 on Codility.
// you can also use imports, for example:
// import java.util.*;
// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");
import java.util.Arrays;
class Solution {
public int solution(int[] A) {
int N = A.length;
Arrays.sort(A);
/**
* When we sort an array there are two possible options for the largest product
* 1) The largest (the last) three elements
* 2) Combination of two smallest and the largest elements
* Logic of (1): Obvious
* Logic of (2): A pair of negatives multiplied returns a positive, which in combination with
* the largest positive element of the array can give the max outcome.
* Therefore we return the max of options (1) and (2)
*/
return Math.max(A[0] * A[1] * A[N - 1], A[N - 1] * A[N - 2] * A[N - 3]);
}
}
Cheers
Kotlin without sorting.
I wonder why so many answer here ignore the question title "without sorting"!
fun solution(A: IntArray): Int {
// write your code in Kotlin
if (A.size < 3) return -1
var max1: Int = Int.MIN_VALUE
var max2: Int = Int.MIN_VALUE
var max3: Int = Int.MIN_VALUE
var min1: Int = Int.MAX_VALUE
var min2: Int = Int.MAX_VALUE
A.forEach {
when {
it > max1 -> {
max3 = max2
max2 = max1
max1 = it
}
it > max2 -> {
max3 = max2
max2 = it
}
it > max3 -> {
max3 = it
}
}
when {
it < min1 -> {
min2 = min1
min1 = it
}
it < min2 -> {
min2 = it
}
}
}
return (min1 * min2 * max1).coerceAtLeast(max1 * max2 * max3)
}
Here's an O(n log n ) solution.
First we sort the array,
then knowing that two negatives with great value make a bigger positive we need to calculate the max at the left of the array, and the product of the 3 elements that are to the right of the array and compare which one is bigger.
Here's a sample code:
// [1,2,3,4] = 24
public int solution(int[] sortedArray) {
Arrays.sort(sortedArray);
int length = sortedArray.length;
int P, Q, R;
int maximumLeft = Integer.MIN_VALUE, maximumRight = Integer.MIN_VALUE;
P = sortedArray[length - 3];
Q = sortedArray[length - 2];
R = sortedArray[length - 1];
maximumRight = P * Q * R;
P = sortedArray[0];
Q = sortedArray[1];
R = sortedArray[length -1];
maximumLeft = P * Q * R;
return maximumRight > maximumLeft ? maximumRight : maximumLeft;
}
Don't forget to import java.util.Arrays;
See this link for the Java file.
Here you go it doesn't use sorting and still gets 100%.
#include<limits>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int solution(vector<int> &A) {
//Keep the absolute value for max 2 -ve num . As their mul will be +ve
int abs1 = numeric_limits<int>::min();
int abs2 = numeric_limits<int>::min();
//Keep the max three num irrespective of sign
int max1 = numeric_limits<int>::min();
int max2 = numeric_limits<int>::min();
int max3 = numeric_limits<int>::min();
unsigned int size = A.size()-1;
for (unsigned int i = 0; i <= size ; ++i) {
if(A[i] > 0 ){
} else if(abs(A[i]) >= abs1 ) {
abs2 = abs1;
abs1 = abs(A[i]);
}else if(abs(A[i]) >= abs2 ) {
abs2 = abs(A[i]);
}
if(A[i] >= max1 ){
//Push max1s prev value to max2 and max2's prev val to max3
max3 = max2;
max2 = max1;
max1 = A[i];
} else if(A[i] >= max2 ) {
max3 = max2;
max2 = A[i];
}else if(A[i] > max3 ) {
max3 = A[i];
}
}
// Either max 3 multiplication , or Max 2 negative num whose mul is +ve and the regular max
return max(max1 * max2 * max3, abs1 * abs2 * max1);
}
int main(){
vector<int> test = {-3, 1, 2, -2, 5, 6};
cout << solution(test);
return 0;
}
There is a lot of great answers, but I think this one has some elegance in it, also gives 100% on codility.
public static int solution(int[] A) {
Arrays.sort(A);
int F = 0, L = A.length - 1;
int s1 = A[F] * A[F + 1] * A[F + 2];
int s2 = A[F] * A[F + 1] * A[L];
int s3 = A[F] * A[L - 1] * A[L];
int s4 = A[L - 2] * A[L - 1] * A[L];
return Math.max(Math.max(s1, s2), Math.max(s3, s4));
}
Here, is my solution, I have sorted only upto required one
https://app.codility.com/demo/results/training68T6KT-NY6/
public int solution(int[] A) {
// write your code in Java SE 8
int result;
for (int i = 0; i < 3; i++) {
for (int j = i; j < A.length; j++) {
if (A[i] < A[j]) {
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
}
for (int i = 0; i < 2; i++) {
for (int j = 0; j < A.length - i; j++) {
if (A[A.length - 1 - i] > A[j]) {
int temp = A[A.length - 1 - i];
A[A.length - 1 - i] = A[j];
A[j] = temp;
}
}
}
if ((A[A.length - 1] < 0) && A[A.length - 1] * A[A.length - 2] > 0) {
result = A[0] * A[A.length - 1] * A[A.length - 2];
if (result > A[0] * A[1] * A[2])
return result;
}
return A[0] * A[1] * A[2];
}
This might work:
int solution(vector<int>& A) {
// write your code in C++14 (g++ 6.2.0)
int missing = 1;
vector<int> count(A.size());
for (int n = 0; n < A.size(); n++) {
if (A[n] > 0 && A[n] < (A.size() + 1)) {
count[A[n] - 1]++;
}
}
for (int n = 0; n < A.size(); n++) {
if (count[n] == 0) {
break;
}
missing++;
}
return missing;
}
Python solution - 100%
def solution(A):
A.sort()
return max(A[0] * A[1] * A[-1] , A[-3] * A[-2] * A[-1])
private static int[] rev(int[] validData) {
for (int i = 0; i < validData.length / 2; i++) {
int temp = validData[i];
validData[i] = validData[validData.length - i - 1];
validData[validData.length - i - 1] = temp;
}
return validData;
}
public static int solution(int[] A) {
// write your code in Java SE 8
long p = 0, q = 0, r = 0, max1 = Integer.MAX_VALUE, max2 = Integer.MAX_VALUE, res = 0;
Arrays.sort(A);
A = rev(A);
int start = 0, end = A.length;
//upper bound
p = A[start];
q = A[start + 1];
r = A[start + 2];
max1 = p * q * r;
//lower bound
q = A[end - 1];
r = A[end - 2];
max2 = p * q * r;
return (int) Math.max(max1, max2);
}
kinda late, but this approach is less efficient, but still fast. it reverses the array, then the logic is , the upper bound is the first element * two consectives, or either first element * two last consecutives, either one of the two should yield the maximaum.
here is my solution applied to the problem got 100%.
import java.util.*;
// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");
class Solution {
public int solution(int[] A) {
Arrays.sort(A);
int length = A.length;
int max =0;
if(A[0]>0||A[length-1]<0){
max = (A[length-1]*A[length-2]*A[length-3]);
return max;
}else{
int lastMultiPlier = A[length-1];
if((A[0]*A[1])>(A[length-2]*A[length-3])){
max=A[0]*A[1]*lastMultiPlier;
}else{
max=A[length-2]*A[length-3]*lastMultiPlier;
}
return max;
}
}
}
It's ok to use sorting in the Codility problem. here is a solution that gives you 100%. Without sorting it becomes messy but definitely possible.
#include<limits>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int solution(vector<int> &A) {
int abs1 = numeric_limits<int>::min();
int abs2 = numeric_limits<int>::min();
sort(A.begin(), A.end());
unsigned int size = A.size()-1;
int temp;
for (unsigned int i = 0; i <= size ; ++i) {
if(A[i] > 0 ) continue;
if(abs(A[i]) >= abs1 ) {
temp = abs1;
abs1 = abs(A[i]);
abs2 = temp;
}else if(abs(A[i]) >= abs2 ) {
abs2 = abs(A[i]);
}
}
return max(A[size] * A[size-1] * A[size-2], abs1 * abs2 * A[size]);
}
int main(){
vector<int> test = {-4, -6, 3, 4, 5};
cout << solution(test);
return 0;
}
With JavaScript (Node.js 8.9.4):
function solution(A) {
// first we order it
A.sort((a, b) => (a - b));
// we see the first two possibilities and we compare them
let val1 = A[A.length - 1] * A[A.length - 2] * A[A.length - 3]
let val2 = A[A.length - 1] * A[0] * A[1]
// we return the higher value
if (val1 > val2) { return val1 } else { return val2 }
}
python 3, thank you DanutClapa, I did first the positives well but your clarification on last 2 negatives was the solution.
def solution(arr):
if not arr:
return 0
if len(arr) == 3:
m = 1
for i in arr:
m *= i
return m
else:
max_num = min(arr)
second_max = min(arr)
tercero_max = min(arr)
min_num = max(arr)
min_num_2 = max(arr)
for i in range(0, len(arr)):
if (arr[i] > max_num):
tercero_max = second_max
second_max = max_num
max_num = arr[i]
elif arr[i] > second_max:
tercero_max = second_max
second_max = arr[i]
elif arr[i] > tercero_max:
tercero_max = arr[i]
if arr[i] < min_num:
min_num_2 = min_num
min_num = arr[i]
elif arr[i] < min_num_2:
min_num_2 = arr[i]
return max( max_num * second_max * tercero_max, max_num * min_num * min_num_2)
No sort ... ES6, but honestly: why no sort?
find the biggest number {max[0] > max[1] > max[2]}
find the 2 smallest {min[0] < min[1]} (explained above as 2 negative number)
return max of [max[0] * max[1] * max[0], max[0] * max[1] * max[2]]
function answer(A) {
maxA = [...A]
minA = [...A]
max = [];
min = [];
max.push(Math.max(...maxA)); maxA.pop()
max.push(Math.max(...maxA)); maxA.pop()
max.push(Math.max(...maxA));
min.push(Math.min(...minA)); minA.pop()
min.push(Math.min(...minA))
return Math.max(max[0] * max[1] * max[0], max[0] * max[1] * max[2])
}
Here is my c# solution. First order the array, for max product max integers required.
For negative integers we need to look first two element of sorted array.
This solution gets 100%
public int solution(int[] A)
{
var sorted = A.ToList();
sorted.Sort();
var last = sorted[sorted.Count-1]*sorted[sorted.Count-2]*sorted[sorted.Count-3];
var firsttwo = sorted[0]*sorted[1]*sorted[sorted.Count-1];
return Math.Max(last,firsttwo);
}
Python solution with 100% Score
import sys
def solution(A):
if len(A) < 3:
return 0
min_value = sys.maxsize*-1
max_value = sys.maxsize
positive_nus = [min_value]*3
negative_nus =[max_value]*2
for i in range(0,len(A)):
if A[i]> positive_nus[0]:
positive_nus[2] = positive_nus[1]
positive_nus[1]= positive_nus[0]
positive_nus[0] = A[i]
elif A[i] > positive_nus[1]:
positive_nus[2] = positive_nus[1]
positive_nus[1]= A[i]
elif A[i] > positive_nus[2]:
positive_nus[2] = A[i]
if A[i] < negative_nus[0]:
negative_nus[1] = negative_nus[0]
negative_nus[0] = A[i]
elif A[i] < negative_nus[1]:
negative_nus[1] = A[i]
sol1 = positive_nus[0]*positive_nus[1]*positive_nus[2]
sol2 = positive_nus[0]*negative_nus[0]*negative_nus[1]
return max(sol1,sol2)
JavaScript Solution from #Slobodan Antonijević Answer
function solution(A) {
let N = A.length;
/* some time sort doesn't work as expected try passing your own
sorting function to sort it in ascending order
*/
A = A.sort((a,b) => (a-b));
return Math.max(A[0] * A[1] * A[N - 1], A[N - 1] * A[N - 2] * A[N - 3]);
}
In case anyone cares about C.
I tried quicksort before , but got 88% result due to performance issue.
So i ended up with an efficient (100%) yet messy code:
https://app.codility.com/demo/results/trainingGT8RQR-FBM/
int solution(int A[], int N) {
int NEG[3]; NEG[0]=0; NEG[1] = 0; NEG[2]=0; int p=-1;
int POS[3]; POS[0] = 0; POS[1] =0; POS[2] = 0; int n=-1;
int MAXIM[3]; MAXIM[0]=-1001; MAXIM[1]=-1001; MAXIM[2]=-1001; int m = -1;
int i =0;
for(i = 0 ; i < N ; i++)
{
if(A[i] < 0 && A[i] < NEG[2])
{
if(A[i] < NEG[0]) { NEG[2] = NEG[1]; NEG[1] = NEG[0];NEG[0] = A[i];}
else if(A[i] < NEG[1]) { NEG[2] = NEG[1]; NEG[1] = A[i];}
else if(A[i] < NEG[2]) NEG[2] = A[i];
if(n < 2) n++;
}
else if(A[i] >= 0 && A[i] > POS[2])
{
if(A[i] > POS[0]) {POS[2] = POS[1]; POS[1] = POS[0]; POS[0]=A[i];}
else if(A[i] > POS[1]) {POS[2] = POS[1]; POS[1] = A[i];}
else POS[2] = A[i];
if(p < 2) p++;
}
if(A[i] <= 0 )
{
if(A[i] > MAXIM[0]){ MAXIM[2]=MAXIM[1];MAXIM[1]=MAXIM[0]; MAXIM[0]=A[i]; if(m<2)m++;}
else if(A[i]>MAXIM[1]){MAXIM[2]=MAXIM[1]; MAXIM[1]=A[i];if(m<2)m++;}
else if(A[i]>MAXIM[2]){MAXIM[2]=A[i]; if(m<2)m++;}
}
}
int max =0, val_set =0;;
if( n >=1 && p>=0 )
{
int tmp = NEG[0] * NEG[1] * POS[0];
if(val_set == 0)
{ max = tmp;
val_set =1;
}
else
if(tmp > max){
max = tmp;
}
}
if( p > 1 )
{
int tmp = POS[0] * POS[1] * POS[2];
if(val_set == 0)
{ max = tmp;
val_set =1;
}
else
if(tmp > max )
{max = tmp;}
}
else
if( n > 1)
{
int tmp = NEG[0] * NEG[1] * NEG[2];
if(val_set == 0)
{ max = tmp;
val_set =1;
}
else
if(tmp > max ){
max = tmp;}
}
if(m>1){
int temp = MAXIM[0] * MAXIM[1] * MAXIM[2];
if(val_set == 0)
{ max = temp;
val_set =1;
}
else if(temp > max){
max = temp;}
}
return max;
}
Sort the array in Ascending order.
Product1 = Product of last 3 numbers of the sorted array
Product2 = Product of last number and the first 2 numbers of the sorted array
Return the maximum of two above products
O(n) solution in Javascript could be:
function solution(A) {
let sorted = A.sort((a, b) => a-b);
let max1 = A[A.length - 1] * A[A.length - 2] * A[A.length - 3];
let max2 = A[0] * A[1] * A[A.length - 1];
return Math.max(max1, max2);
}
Since some weeks ago I have been trying to convert this c and other c function to java language (i'm a newbie on it).
My first problem is how-to convert to java code, the pointers on lines like:
q = fdata + ind;
datend = fdata + buff_size;
For example when "ind" has a negative position (-220 for example) the pointer will be on "ind" position before "fdata" values, also the same occur with datend var.
I figured out that can be solved on isolated way by creating an index var for each pointer to know where there are pointing at. The real problem for me comes a few line after that, when i trying to not run over end of frame of "fdata" array.
Can some body with more experiences help me please?
Thank.
static Stat *stat = NULL;
static float *mem = NULL;
static Stat*
get_stationarity(fdata, freq, buff_size, nframes, frame_step, first_time)
float *fdata;
double freq;
int buff_size, nframes, frame_step, first_time;
{
static int nframes_old = 0, memsize;
float preemp = 0.4f, stab = 30.0f;
float *p, *q, *r, *datend;
int ind, i, j, m, size, order, agap, w_type = 3;
agap = (int) (STAT_AINT * freq);
size = (int) (STAT_WSIZE * freq);
ind = (agap - size) / 2;
if (nframes_old < nframes || !stat || first_time) {
/* move this to init_dp_f0() later */
nframes_old = nframes;
if (stat) {
ckfree((char *) stat->stat);
ckfree((char *) stat->rms);
ckfree((char *) stat->rms_ratio);
ckfree((char *) stat);
}
if (mem) ckfree((void *) mem);
stat = (Stat *) ckalloc(sizeof (Stat));
stat->stat = (float*) ckalloc(sizeof (float) *nframes);
stat->rms = (float*) ckalloc(sizeof (float) *nframes);
stat->rms_ratio = (float*) ckalloc(sizeof (float) *nframes);
memsize = (int) (STAT_WSIZE * freq) + (int) (STAT_AINT * freq);
mem = (float *) ckalloc(sizeof (float) * memsize);
for (j = 0; j < memsize; j++) mem[j] = 0;
}
if (nframes == 0) return (stat);
q = fdata + ind;
datend = fdata + buff_size;
if ((order = (int) (2.0 + (freq / 1000.0))) > BIGSORD) {
fprintf(stderr,
"exceeds that allowable (%d); reduce Fs\n", BIGSORD);
order = BIGSORD;
}
/* prepare for the first frame */
for (j = memsize / 2, i = 0; j < memsize; j++, i++) mem[j] = fdata[i];
/* do not run over end of frame */
for (j = 0, p = q - agap; j < nframes; j++, p += frame_step, q += frame_step) {
if ((p >= fdata) && (q >= fdata) && (q + size <= datend))
stat->stat[j] = get_similarity(order, size, p, q,
&(stat->rms[j]),
&(stat->rms_ratio[j]), preemp,
stab, w_type, 0);
else {
if (first_time) {
if ((p < fdata) && (q >= fdata) && (q + size <= datend))
stat->stat[j] = get_similarity(order, size, NULL, q,
&(stat->rms[j]),
&(stat->rms_ratio[j]),
preemp, stab, w_type, 1);
else {
stat->rms[j] = 0.0;
stat->stat[j] = 0.01f * 0.2f; /* a big transition */
stat->rms_ratio[j] = 1.0; /* no amplitude change */
}
} else {
if ((p < fdata) && (q + size <= datend)) {
stat->stat[j] = get_similarity(order, size, mem,
mem + (memsize / 2) + ind,
&(stat->rms[j]),
&(stat->rms_ratio[j]),
preemp, stab, w_type, 0);
/* prepare for the next frame_step if needed */
if (p + frame_step < fdata) {
for (m = 0; m < (memsize - frame_step); m++)
mem[m] = mem[m + frame_step];
r = q + size;
for (m = 0; m < frame_step; m++)
mem[memsize - frame_step + m] = *r++;
}
}
}
}
}
/* last frame, prepare for next call */
for (j = (memsize / 2) - 1, p = fdata + (nframes * frame_step) - 1; j >= 0 && p >= fdata; j--)
mem[j] = *p--;
return (stat);
}
This code is easier rewritten than ported. The reason is, that it uses a large number of pointer-arithmetic and casting.
It looks to me like this code combines a sliding window and averaging functions over the data. You can easily do this in Java, just place each time-series in an array, use an index (instead of a pointer) to point at the array's entries. In the case where the C-code uses a pointer and then a (possibly negative) offset as a second pointer just use two indices into the time-series-array.
It is easier to do this if you have the formula (math-notation. sliding-window plus averaging functions) that this code is supposed to compute and translate the formula to java.