Double 'else' statement in pascal - c++

I was trying to translate the following Pascal code to C++, when I stumbled upon the "else else" construction in question. I've never seen this before, so could anybody tell me what it does and what are it's C++ (or maybe C) equivalents?
Procedure Force(Q:Int64;V,K:Integer);
Var i,j,t:Integer;
begin
if K<=0 then
if (Q>=A)and(Q Mod KK =0)and(V>=S)and(V<=F)then Out:=Out+1 else else
For i:=0 to 9 do
if (Q+(i+1)*h[k-1]>=A)and(Q+i*h[k-1]<=B) then
if (Q+(i+1)*h[K-1]<B)and(Q+i*h[k-1]>=A) then
Begin
M:=(Q+i*h[k-1]) Mod KK;
For j:=0 to 9*(K-1) do
For t:=0 to KK-1 do
if D[K-1,j,t]>0 then
if (V+i+j>=S)and(V+i+j<=F)and((t+M) Mod KK=0) then
Out:=Out+D[K-1,j,t];
end else
if Odd(N-K+1) then Force(Q+i*h[k-1],V+i,K-1) else
Force(Q+i*h[k-1],V+i,K-1);
end;

I've just copied to an editor (for instance Komodo, where you can select Pascal as language for syntax color highlighting) and reformatted the text you've wrote in a way I can read it myself.
procedure Force(Q:Int64;V,K:Integer);
var
i,j,t:Integer;
begin
if K<=0 then
if (Q>=A) and (Q Mod KK =0) and (V>=S) and (V<=F) then
Out:=Out+1
else
else
for i:=0 to 9 do begin
if (Q+(i+1)*h[k-1]>=A) and (Q+i*h[k-1] <= B) then
if (Q+(i+1)*h[K-1]<B) and (Q+i*h[k-1] >= A) then begin
M := (Q+i*h[k-1]) Mod KK;
for j:=0 to 9*(K-1) do begin
for t:=0 to KK-1 do begin
if D[K-1,j,t] > 0 then
if (V+i+j >= S) and (V+i+j <= F) and ((t+M) mod KK = 0) then
Out:=Out+D[K-1,j,t];
end; {for t}
end; {for j}
end else
if Odd(N-K+1) then
Force(Q+i*h[k-1],V+i,K-1)
else
Force(Q+i*h[k-1],V+i,K-1);
end;
end;
end;
Don't you think it is more understandable now?

It's quite often useful to use begin and end pairs even when they're not required by the syntax, just to make the code more readable and understandable. (Think of begin being the equivalent of { and end being the equivalent of }; while you can write for(int i = 0; i < 10; i++) SomeCode();, it's usually more clear to use for(int i = 0; i < 10; i++) { SomeCode(); }.
So the code you've posted, with begin and end pairs added where appropriate, a no-op else or two removed, and more appropriate formatting seems much more readable to me.
Procedure Force(Q: Int64; V, K: Integer);
Var
i, j, t: Integer;
begin
if K <= 0 then
begin
if (Q >= A) and (Q Mod KK = 0) and (V >= S) and (V <= F) then
Out := Out + 1;
end
else
begin
For i := 0 to 9 do
begin
if (Q + (i + 1) * h[K - 1] >= A) and (Q + i * h[K - 1] <= B) then
begin
if (Q + (i + 1) * h[K - 1] < B) and (Q + i * h[K - 1] >= A) then
begin
M := (Q + i * h[K - 1]) Mod KK;
For j := 0 to 9 * (K - 1) do
begin
For t := 0 to KK - 1 do
begin
if D[K - 1, j, t] > 0 then
begin
if (V + i + j >= S) and (V + i + j <= F) and
((t + M) Mod KK = 0) then
Out := Out + D[K - 1, j, t];
end;
end;
end;
end
else if Odd(N - K + 1) then
Force(Q + i * h[K - 1], V + i, K - 1)
else
Force(Q + i * h[K - 1], V + i, K - 1);
end;
end;
end;
end;

That is some horrible indentation. If we indent it better we can see what's going on:
if K<=0 then
if (Q>=A)and(Q Mod KK =0)and(V>=S)and(V<=F) then
Out:=Out+1
else
else
For i:=0 to 9 do
Here, the first else applies to the if (Q>=A), but it's empty.

Related

Coursera DSA Algorithmic toolbox week 4 2nd question- Partitioning Souvenirs

Problem Statement-
You and two of your friends have just returned back home after visiting various countries. Now you would
like to evenly split all the souvenirs that all three of you bought.
Problem Description
Input Format- The first line contains an integer ... The second line contains integers v1, v2, . . . ,vn separated by spaces.
Constraints- 1 . .. . 20, 1 . .... . 30 for all ...
Output Format- Output 1, if it possible to partition 𝑣1, 𝑣2, . . . , 𝑣𝑛 into three subsets with equal sums, and
0 otherwise.
What's Wrong with this solution? I am getting wrong answer when I submit(#12/75) I am solving it using Knapsack without repetition taking SUm/3 as my Weight. I back track my solution to replace them with 0. Test cases run correctly on my PC.
Although I did it using OR logic, taking a boolean array but IDK whats wrong with this one??
Example- 11
17 59 34 57 17 23 67 1 18 2 59
(67 34 17)are replaced with 0s. So that they dont interfare in the next sum of elements (18 1 23 17 59). Coz both of them equal to 118(sum/3) Print 1.
#include <iostream>
#include <vector>
using namespace std;
int partition3(vector<int> &w, int W)
{
int N = w.size();
//using DP to find out the sum/3 that acts as the Weight for a Knapsack problem
vector<vector<int>> arr(N + 1, vector<int>(W + 1));
for (int k = 0; k <= 1; k++)
{
//This loop runs twice coz if 2x I get sum/3 then that ensures that left elements will make up sum/3 too
for (int i = 0; i < N + 1; i++)
{
for (int j = 0; j < W + 1; j++)
{
if (i == 0 || j == 0)
arr[i][j] = 0;
else if (w[i - 1] <= j)
{
arr[i][j] = ((arr[i - 1][j] > (arr[i - 1][j - w[i - 1]] + w[i - 1])) ? arr[i - 1][j] : (arr[i - 1][j - w[i - 1]] + w[i - 1]));
}
else
{
arr[i][j] = arr[i - 1][j];
}
}
}
if (arr[N][W] != W)
return 0;
else
{
//backtrack the elements that make the sum/3 and = them to 0 so that they don't contribute to the next //elements that make sum/3
int res = arr[N][W];
int wt = W;
for (int i = N; i > 0 && res > 0; i--)
{
if (res == arr[i - 1][wt])
continue;
else
{
std::cout << w[i - 1] << " ";
res = res - w[i - 1];
wt = wt - w[i - 1];
w[i - 1] = 0;
}
}
}
}
if (arr[N][W] == W)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
int n;
std::cin >> n;
vector<int> A(n);
int sum = 0;
for (size_t i = 0; i < A.size(); ++i)
{
int k;
std::cin >> k;
A[i] = k;
sum += k;
}
if (sum % 3 == 0)
std::cout << partition3(A, sum / 3) << '\n';
else
std::cout << 0;
}
Sum/3 can be achieved by multiple ways!!!! So backtracking might remove a subset that has an element that should have been a part of some other subset
8 1 6 is 15 as well as 8 2 5 makes 15 so better is u check this
if(partition3(A, sum / 3) == sum / 3 && partition3(A, 2 * (sum / 3)) == 2 * sum / 3 && sum == partition3(A, sum))

Lexicographically minimal string rotation

Hi so I'm basically trying to understand this piece of code in regards to determining the lexicographically minimal string rotation but I just can't seem to understand why it works. I understand what the first two ifs do but the third one, when there is a new minimum, it takes the maximum between p and m+l+1. Does anyone have an explanation?
int p = 0, l = 0, m = 0, n = 0;
string inp;
cin >> inp;
n = inp.size();
p = l = 1;
while (p < n && m + l + 1 < n) {
if (inp[m + l] == inp[(p + l) % n])
++l;
if (inp[m + l] < inp[(p + l) % n])
p += l + 1, l = 0;
if (inp[m + l] > inp[(p + l) % n]) {
if (m + l + 1 < p) m = p;
else m = m + l + 1;
p = m + 1;
l = 0;
}
}
cout << m;

How to add c element in sorted vector without using standard algorithms?

My code does not work in some cases: when c1 is 4, it doesn't output anything, but it works for numbers greater than 9. Why is that?
#include<iostream>
#include<vector>
using namespace std;
void insertfast(vector<int>&v, int c)
{
if (c >= v[v.size()-1])v.push_back(c);
if (c <= v[0])v.insert(v.begin(), c);
int min = 1;
int max = v.size();
while (v.size() != 9) {
int i = (min + max) / 2;
if (v[i - 1] <= c && c <= v[i])v.insert(v.begin() + i, c);
if (v[i] <= c && c <= v[i + 1])v.insert(v.begin() + (i + 1), c);
if (c < v[i])
max = i;
else
min = i;
}
}
int main()
{
vector<int>v1 = { 2,5,9,22,44,55,88,777 };
int c1 = 4;
insertfast(v1, c1);
for (int i = 0; i < 9; i++)
cout << v1[i] << endl;
}
Let's just take a second to logically step through the code here, since I assume this is a homework question, it's important to understand how to do this. There are tools like debuggers that are used on larger projects and more difficult problems, but small logic errors like this happen all the time.
Ok, so insertfast() is a function to insert an int into a vector<int> in an ordered manner. The first thing you do is compare against the first and last elements of the vector.
if (c >= v[v.size() - 1])
v.push_back(c);
if (c <= v[0])
v.insert(v.begin(), c);
We can only be one of these things, and if either are true we are done. So the best option here is to just return from the function, we don't care about doing anything else. We know that, but the program doesn't. It'll keep on comparing things we don't want to compare and bug out.
if (c >= v[v.size() - 1]) {
v.push_back(c);
return;
}
if (c <= v[0]) {
v.insert(v.begin(), c);
return;
}
What if both of these statements are false, and we are still in the function? We still need to figure where to insert this value, so we loop through the elements.
while (v.size() != 9)
This is a very poor conditional loop, since it will only work if we pass a vector of size 8 into the function. With your particular arithmetic, you essentially want to loop until some value is added to the vector. I recommend an unconditional loop (we are trying to be "fast" after all) aka an infinite loop, and explicitly return or break within the loop.
int min = 1;
int max = v.size();
while (1) {
int i = (min + max) / 2;
if (v[i - 1] <= c && c <= v[i]) {
v.insert(v.begin() + i, c);
return;
}
if (v[i] <= c && c <= v[i + 1]) {
v.insert(v.begin() + (i + 1), c);
return;
}
if (c < v[i])
max = i;
else
min = i;
}
break instead of return will also work just fine here, since if you break out of this loop, the end of the function is hit and you just return anyways. So, we solved the problem just by rethinking the design and stepping through the code.
You have two logic problems in your code:
For your test data in insertfast() function you step into while(), when you step into first if (v[i - 1] <= c && c <= v[i]) you insert 4 value and in becomes v[1], and you have step right after that into next if (v[i] <= c && c <= v[i + 1]), so you need to set second if as else if, like this:
if (v[i - 1] <= c && c <= v[i])
{
v.insert(v.begin() + i, c);
}
else if (v[i] <= c && c <= v[i + 1])
{
v.insert(v.begin() + (i + 1), c);
}
From the previous item your vector increased for 2 elements, so his size becomes 10, and you had infinite loop while (v.size() != 9), I think you can just do break to leave loop in case of success insert:
if (v[i - 1] <= c && c <= v[i])
{
v.insert(v.begin() + i, c);
break;
}
else if (v[i] <= c && c <= v[i + 1])
{
v.insert(v.begin() + (i + 1), c);
break;
}
There is no need to run loop further, if you have inserted element.
Actually 2nd item with break will fix and else missing problem, in case of insertion it will leave loop and won't be able to step into second if.

Triangle: Determine if an array includes a triangular triplet (Codility)

This is the Triangle problem from Codility:
A zero-indexed array A consisting of N integers is given.
A triplet (P, Q, R) is triangular if 0 ≀ P < Q < R < N and:
A[P] + A[Q] > A[R],
A[Q] + A[R] > A[P],
A[R] + A[P] > A[Q].
Write a function:
int solution(vector<int> &A);
that, given a zero-indexed array A consisting of N integers, returns 1
if there exists a triangular triplet for this array and returns 0
otherwise.
For example, given array A such that:
A[0] = 10, A[1] = 2, A[2] = 5, A[3] = 1, A[4] = 8, A[5] = 20
Triplet (0, 2, 4) is triangular, the function should return 1.
Given array A such that:
A[0] = 10, A[1] = 50, A[2] = 5, A[3] = 1
function should return 0.
Assume that:
N is an integer within the range [0..100,000];
each element of array A is an integer within the range
[βˆ’2,147,483,648..2,147,483,647].
And here is my solution in C++:
int solution(vector<int> &A) {
if(A.size()<3) return 0;
sort(A.begin(), A.end());
for(int i=0; i<A.size()-2; i++){
//if(A[i] = A[i+1] = A[i+2]) return 1;
if(A[i]+A[i+1]>A[i+2] && A[i+1]+A[i+2]>A[i] && A[i+2]+A[i]>A[i+1]){
return 1;
}
}
return 0;
}
I've checked the comments there and all the solutions seems similar to mine.
However, while others claimed to have gotten 100%, I only got a 93% score.
I got all the tests cases correct EXCEPT for one:
extreme_arith_overflow1
overflow test, 3 MAXINTs
I assume this case has some input like this:
[2147483647, 2147483647, 2147483647]
So I add this to the custom test case, and the answer turns out to be 0 when it clearly should be 1.
I also tried [1900000000, 1900000000, 1900000000], and the answer is still 0.
However, [1000000000, 1000000000, 1000000000] is correct with answer of 1.
Can anyone clue me in on why this result occured?
Greatly appreciated.
My solution in Java with 100/100 and time complexity of O(N*log(N))
With comments explaining the logic
// 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;
if (N < 3) return 0;
Arrays.sort(A);
for (int i = 0; i < N - 2; i++) {
/**
* Since the array is sorted A[i + 2] is always greater or equal to previous values
* So A[i + 2] + A[i] > A[i + 1] ALWAYS
* As well ass A[i + 2] + A[i + 1] > A[i] ALWAYS
* Therefore no need to check those. We only need to check if A[i] + A[i + 1] > A[i + 2]?
* Since in case of A[i] + A[i + 1] > MAXINT the code would strike an overflow (ie the result will be greater than allowed integer limit)
* We'll modify the formula to an equivalent A[i] > A[i + 2] - A[i + 1]
* And inspect it there
*/
if (A[i] >= 0 && A[i] > A[i + 2] - A[i + 1]) {
return 1;
}
}
return 0;
}
Basically when you check X + Y value of integers, that is greater than integer limit the code will fail on overflow. so instead of checking if X + Y > Z, we can simply check the equivalent statement if X > Z - Y (simple math isn't it?). Alternatively you could always use long but it will be a worse solution memory wise.
Also make sure you skip the negatives as a triangle cannot have a negative side value.
Cheers
Java 100 %:
public int solution(int[] A){
Arrays.sort(A);
for(int i=0;i<A.length-2;i++){
if(
((long)A[i] + (long)A[i+1] > A[i+2]) &&
((long)A[i+1] + (long)A[i+2] > A[i]) &&
((long)A[i] + (long)A[i+2] > A[i+1])
)
return 1;
}
return 0;
}
Here's my clean solution in Python. I got a 100% in Codility.
This logic can be adapted to any other programming language.
Note: If the array is sorted, you only have to check that the sum of two consecutive elements is greater than the next element (A[i] + A[i+1] > A[i+2]), because in that case, the other two conditions (A[i+1]+A[i+2] > A[i], A[i]+A[i+2] > A[i+1]) will always be true.
I hope it helps.
def solution(A):
#edge case check
if len(A) < 3:
return 0
A.sort()
for i in range(len(A)-2):
if A[i]+A[i+1] > A[i+2]:
return 1
return 0
There are couple of issues here
Side of a triangle can't be 0, since it is a length. You have to add that check or you'll fail that corner case. i.e. Wouldn't get 100%.
Since you can have an input array of all INT_MAX or LONG_MAX (see http://www.cplusplus.com/reference/climits/), you need to store the sum in a double or long long.
You don't have to check all three conditions here i.e.
A[P] + A[Q] > A[R],
A[Q] + A[R] > A[P],
A[R] + A[P] > A[Q].
If you have sorted the array than
A[Q] + A[R] > A[P] &&
A[R] + A[P] > A[Q]
are always true because 0 ≀ P < Q < R i.e. R is greater than P and Q.
So you should only check for A[P] + A[Q] > A[R].
You have already placed a check for A.size() < 3 so that is good.
I have added a C implementation at https://github.com/naveedrasheed/Codility-Solutions/blob/master/Lesson6_Sorting/triangle.c.
You can compare it with solution.
I have used 3 for loop here( without sorting the array) to solve this problem.
public static int solution(int[] A) {
for (int p = 0; p < A.length; p++) {
for (int q = p + 1; q < A.length; q++) {
for (int r = q + 1; r < A.length; r++) {
if ((A[p] + A[q] > A[r]) && (A[q] + A[r] > A[p]) && (A[r] + A[p] > A[q])) {
System.out.println(A[p] + " " + A[q] + " " + A[r]);
return 1;
}
}
}
}
return 0;
}
the trick is to find a number on the array that is less the sum of the other two on the array so sorting the array then searching for that number will solve it. casting to long that on sometimes the value of summation wil exceed the allowed integer
public int solution(int[] A) {
int n = A.length;
if(n<3){
return 0;
}
Arrays.sort(A);
for(int i=2; i<n; i++){
if(A[i]<(long)A[i-1]+(long)A[i-2])
return 1;
}
return 0;
}
My solution in C# with 100 score.
using System;
class Solution {
public int solution(int[] A) {
// write your code in C# 6.0 with .NET 4.5 (Mono)
if(A.Length) <3)
return 0;
Array.Sort(A);
int p,q,r;
for(int i=A.Length-1;i>1; i--){
p = A[i];
q = A[i-1];
r = A[i-2];
if(p+q>r && q+r > p && r+p > q)
return 1;
}
return 0;
}
}
Straightforward solution in JavaScript.
Note: I excluded the options where any side could be 0 or less. The rest is the same.
function solution(A) {
if (A.length < 3) return 0;
A.sort((a, b) => (a - b));
for (i = A.length - 1; i >= 0; i--) {
if (A[i - 2] <= 0) return 0;
if (
A[i] + A[i - 1] > A[i - 2] &&
A[i] + A[i - 2] > A[i - 1] &&
A[i - 1] + A[i - 2] > A[i]
) return 1;
}
return 0;
}
javascript 100% on codility
function solution(a) {
if (a.length < 3) {
return 0;
}
a.sort((a, b) => a - b);
for (let i = 0; i < a.length - 2; i++) {
if (a[i] + a[i + 1] > a[i + 2]) {
return 1;
}
}
return 0;
}
My solution to this problem, written in Swift.
public func Triangle(_ A : inout [Int]) -> Int {
A.sort()
for i in 1..<A.count-1 {
if(A[i] + A[i-1] > A[i+1]) {
print("Triangle has edges: \(A[i-1]), \(A[i]), \(A[i+1])")
return 1
}
}
return 0
}
A = [10,2,5,1,8,20]
print("Triangle: ", Triangle(&A))
Or you can change the if clause, like below
if(A[i]>A[i+2]-A[i+1] && A[i+1]>A[i]-A[i+2] && A[i+2]>A[i+1]-A[i])
using subtraction instead of addition.
Works 100%, tested with different scenario's.
I think all the possibilities are not covered above solution
Combination with
P,Q,R
A[0] = 10, A[1] = 2, A[2] = 5, A[3] = 1, A[4] = 8, A[5] = 20
index combination
0+1>2, 1+2>0, 2+0>1
1+2>3, 2+3>1, 3+1>2
....
These are combinations needed to achieve this problem.
//Triangle
/**
* A[P] + A[Q] > A[R],
A[Q] + A[R] > A[P],
A[R] + A[P] > A[Q]
*/
public int triangleSolution(int[] A) {
int status = 0;
for(int i=0; i<A.length; i++) {
int[] B = removeTheElement(A, i);
for(int j=0; j<B.length; j++) {
int[] C = removeTheElement(B, j);
for(int k=0; k<C.length; k++) {
if((A[i] + B[j] > C[k]) &&
(B[j] + C[k] > A[i]) &&
(C[k] + A[i] > B[j])) {
return 1;
}
}
}
}
return status;
}
// Function to remove the element
public int[] removeTheElement(int[] arr, int index)
{
// Create another array of size one less
int[] anotherArray = new int[arr.length - 1];
// Copy the elements except the index
// from original array to the other array
for (int i = 0, k = 0; i < arr.length; i++) {
// if the index is
// the removal element index
if (i == index) {
continue;
}
// if the index is not
// the removal element index
anotherArray[k++] = arr[i];
}
//Java >8
//IntStream.range(0, arr.length).filter(i -> i != index).map(i -> arr[i]).toArray();
return anotherArray;
}
//My solution in C++ it avoid overflow
inline int Triangle(vector<int> &A) {
if(A.size() < 3) return 0;
sort(A.begin(), A.end());
for(int i = 0; i < (int)A.size() - 2; ++i){
int P = A[i], Q = A[i + 1], R =A[i + 2];
if(( R - P - Q < 0) && ( P - Q - R < 0) && (Q - R - P < 0))
return 1;
}
return 0;
}
Ruby 100% solution
def solution(a)
arr = a.select{|x| x >=0 }.sort
arr.each_with_index do |p, pi|
arr[(pi+1)..-1].each_with_index do |q, qi|
arr[(qi+pi+2)..-1].each do |r|
break if p+q <=r
break if p+r <=q
break if r+q <=p
return 1
end
end
end
0
end
It's javascript solution(TC: O(N*log(N)) though, in case you guys want :).
function solution(A) {
if(A.length<3) return 0;
A.sort((a,b)=>b - a);
for(let i = 0,j = i+1;j < A.length-1;j++){
let p = A[j],q = A[j+1],r = A[i]
if(r - p > q) i++;
else if(r - p < q) return 1;
}
return 0;
}
Sorting does not work now, It was a bug it was fixed by Codility. Now, I am using this piece of code to get 93%
You can see the results below:
Codility test Results
0 <= P < Q < R < N
public static int solution(int[] unfilteredArray) {
int[] array = filterLessThanOneElements(unfilteredArray);
for(int i = 0; i <= (array.length - 3) ; i++) {
long p = array[i];
for(int j = i+1; j <= (array.length - 2); j++) {
long q = array[j];
for(int k = j+1; k <= (array.length - 1); k++) {
long r = array[k];
if((p + q > r) && (q + r > p) && (r + p > q)) {
return 1;
}
}
}
}
return 0;
}
// The mose efficient way to remove duplicates
// TIME COMPLEXITY : O(N)
private static int[] filterLessThanOneElements(int[] unfilteredArray) {
int k = 0;
for(int i = 0; i < unfilteredArray.length; i++) {
if(unfilteredArray[i] > 0) {
unfilteredArray[k++] = unfilteredArray[i];
}
}
return Arrays.copyOfRange(unfilteredArray, 0, k);
}
Simple change: First, you observe that negative integers cannot be part of a triangular triplet. That means you can cast all ints to unsigned int, and there can’t be any overflow anymore.
100/100 JavaScript solution
function solution(A) {
let l = A.length;
if (l < 3) {
return 0;
}
A.sort((a, b) => a - b);
for (let i = 0; i < l - 2; i++) {
let [p, q, r] = [A[i], A[i + 1], A[i + 2]];
if (p + q > r && q + r > p && r + p > q) {
return 1;
}
}
return 0;
}
If you don't want to use Array.sort, the following works with 100% correctness and 100% performance with a complexity that codility detects at O(N*log(N)).
class Solution {
public int solution(int[] A) {
int ans = 0;
int p1 = -1;
int p2 = -1;
int p1Pos = 0;
int p2Pos = 1;
int cur = -1;
if(A.length > 2){
p1 = A[0];
p2 = A[1];
for(int i = p2Pos + 1; i < A.length; i++){
if(p1 > p2){
p2 = A[p1Pos];
p1 = A[p2Pos];
A[p2Pos] = p2;
A[p1Pos] = p1;
}
cur = A[i];
//System.out.println(p1 + " " + p2 + " " + cur);
if(p1 > -1 && p2 > -1){
//the test for a triangle
if (cur > -1 &&
((p1 == p2 && p2 == cur) ||
((p1 + p2 > cur) && (p1 + cur > p2) && ( cur + p2 > p1)))){
return 1;
//bubble sort...sort of
}else if (p2 > cur){
A[p2Pos] = cur;
A[i] = p2;
if(p1 < cur){
p1 = cur;
p1Pos = p2Pos;
}
p2Pos = i;
} else if(cur > -1
&&(p1 + p2 <= cur) ){
p2Pos++;
p1Pos++;
p1=p2;
p2=cur;
}
}else{
//find the first two positive numbers
if((p2 < 0 || p1 < 0) && cur > -1){
if(p1 < 0){
p1 = cur;
p1Pos = i;
}else{
p2 = A[i];
p2Pos = i;
}
}
}
}
}
return ans;
}
}
When I was making this I thought that maybe I could solve this while doing a modified Bubble sort. I chose two pivots (p1 and p2), while making sure p2 > p1.
As I iterated through the array, I made sure that p2 would bubble up if p2 > cur and that p1 would additionally bubble up if p1 > cur. I Furthermore, I noticed that any combination of three points that have a negative number cannot be a triangle. So I ignored negatives. I also realized that if the array happened to hold three and only maximal integers that I would have an issue. To solve this I tested for p1 == p2 == cur. Admittingly, it might be better to use BigInteger to solve it.
My 100% JavaScript solution with O(N*log(N)) time complexity:
function solution(A) {
A.sort((a, b) => a - b);
for (let i = 0, len = A.length - 2; i < len; i++) {
const [P, Q, R] = [A[i], A[i + 1], A[i + 2]];
if (P + Q > R && Q + R > P && R + P > Q) {
return 1;
}
}
return 0;
}
One would think that sorting the array first will violate the condition 0<=P<Q<R. But the question is does such a triple exist. For the example we find [10,2,5,1,8,20]. After sorting we still find the values 10, 5, and 8 as the triple, but in a different order.
A Python 3 solution with 100% score at Codility:
def triangle(A):
n = len(A)
if n < 3:
return 0
a = list(A)
if 0 not in a:
a.append(0)
a.sort()
#print(a)
n = len(a)
p_a = a[a.index(0)+1:n]
#print(p_a)
n = len(p_a)
for i in range(n-2):
p = p_a[i]
q = p_a[i+1]
r = p_a[i+2]
if (p+q>r):
return (1)
return 0
Better solutions for C++ is to change a little algorithm. Make subtraction instead of adding, here is an example:
int solution(vector<int> &A) {
if (A.size() < 3)
return 0;
sort(A.begin(), A.end());
for (int i = 0; i < A.size() - 2; i++) {
if (A[i] > 0 && (A[i] > A[i + 2] - A[i + 1]))
return 1;
}
return 0;
}
It's because of integer overflow.
Try out this one:
int a1 = 1900000000;
int a2 = 1900000000;
int sum = a1+a2; // sum will be -494967296
Edit: Use long long int.
long long int sum01 = A[i] + A[i+1];
long long int sum12 = A[i+1] + A[i+2];
long lont int sum02 = A[i] + A[i+2];
if (sum01 > A[i+2] && sum12 > A[i] && sum02 > A[i+1])
return 1;
My java Solution 100/100 Instead of comparing the Addition we compare the subtraction as we can have an Integer.MAX_VALUE an we will be getting corrupted data.
public static int solution(int[] A) {
int isATriangle = 0;
Arrays.sort(A);
if (A.length >= 3) {
for (int i = 0; i < A.length - 2; i++) {
if (A[i] > A[i + 2] - A[i + 1]
&& A[i + 2] > A[i] - A[i + 1]
&& A[i + 2] > A[i + 1] - A[i])
isATriangle = 1;
}
}
return isATriangle;
}

Mathematical derivation of O(n^3) complexity for general three nested loops

Time complexity of nested for-loop goes into the mathematical derivation through summation of two loops O(n2) complexity.
I tried an exercise to derive how i can get O(n3) for the following examples of three nested loops.
Simple three nested loops.
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= n; k++)
print(i * k * j);
Summation is
= (n + n + n + .... + n) + (n + n + n + ... + n) + ... + (n + n + n + ... + n)
= n^2 + n^2 + .... + n^2
n times n^2 = O(n^3)
Three nested loops not run n times from beginning
for(int i = 1; i <= n; i++)
for(int j = i; j <= n; j++)
for(int k = j; k <= n; k++)
print(i *j * k)
The above is a pretty common form of nested loops and i believe the summation would be something as follows
= (n + (n -1) + (n -2) + (n - 3) + ... + 1)
+ ((n -1) + (n - 2) + (n - 3) +... + 1)
+ ((n -2) + (n -3) + (n - 4) + ... + 1)
+ ...
+ ((n - (n -2)) + 1)
= n(n - 1) /2 + (n-1) (n -2) / 2 + (n-2)(n-3)/2 + .... + 1
=
From here i am slightly not sure if my logic is correct . I believe
each of the above evaluate to a polynomial whose greatest value is n2 and as thats what we care about in time complexity, the above equation breaks down to.
= n^2 + n^2 + n^2 +... +n^2
= which is n times n^2 = O(n^3).
Is my assumption correct?
Three nested loops not run n times from end
for(int i = 1; i <= n; i++)
for(int j = 1; j <= i; j++)
for(int k = 1; k <= j; k++)
print(i *j * k)
If the above was a two nested loop the summation would have been 1 + 2 + 3 + 4 + ... + n. However, for the three nested occurence i am deducing it to be
= 1 + (1 + 2) + (1 + 2 + 3) + (1 + 2 + 3) + (1 + 2 + 3 + .... + n)
From here i am not sure how to derive O(n^3) or how the above summation would be further simplified.
Using the fact that:
1+2+3+...+i =i*(i+1)/2, the summation above can be written as:
1*(1+1)/2 + 2*(2+1)/2 + ... + n*(n+1)/2.
Obviously i*(i+1) > i^2, therefore:
1*(1+1)/2 + 2*(2+1)/2 + ... + n*(n+1)/2 > (1^2+...+ n^2)/2, as we know:
1^2+...+n^2 = n^3/3 + n^2/2 + n/6 (can prove this by induction).
Therefore, the original sum S is bigger than:
n^3/6 + n^2/4 + n/12, which is O(n^3).