And here's mine.
I just tried it with 10,000 random values (between 0 and 0x7fff), it returns on the spot.
@MSD: I just tried your code with 10,000, but I think there's an overflow with currentDiff * diff > 0. I replaced it with
I just tried it with 10,000 random values (between 0 and 0x7fff), it returns on the spot.
@MSD: I just tried your code with 10,000, but I think there's an overflow with currentDiff * diff > 0. I replaced it with
if((currentDiff > 0) == (diff > 0))
Still the algorithm doesn't return. I would really appreciate it if you'd look at it for a bit, as I am comparing something in the algo's, and seeing if a particular thing I did spared me quadratic growth or not.
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <ctime>
using namespace std;
struct Solver{
vector<int> left;
vector<int> right;
int lsum;
int rsum;
Solver(vector<int> & v){
left.insert(left.begin(), v.begin(), v.begin() + v.size()/2);
right.insert(right.begin(), v.begin() + v.size()/2, v.end());
sort(left.begin(), left.end());
sort(right.begin(), right.end());
lsum = 0;
rsum = 0;
for(int i = 0; i < left.size(); i++)
lsum += left[i];
for(int i = 0; i < right.size(); i++)
rsum += right[i];
if(lsum > rsum){
swap(left, right);
swap(lsum, rsum);
}
while(step());
}
bool step(){
int diff = rsum - lsum;
for(auto curr = right.rbegin(); curr != right.rend(); curr++){
auto found = lower_bound(left.begin(), left.end(), *curr - diff/2);
if(found != left.end() && (diff + 2 * *found - 2 * *curr > 0) && (*found - *curr < 0)){
lsum += + *curr - *found;
rsum += - *curr + *found;
diff = rsum - lsum;
swap(*found, *curr);
sort(left.begin(), left.end());
sort(right.begin(), right.end());
return true;
}
}
return false;
}
};
int main(){
vector<int> v;
int const K = 10000;
for(int i = 0; i < K; i++){
v.push_back(rand());
}
vector<int> shuffled(K);
for(int i = 0; i < K; i++){
int index = rand()%v.size();
shuffled[i] = v[index];
v.erase(v.begin()+index);
}
Solver s(shuffled);
cout << "diff = " << s.rsum - s.lsum << endl;
cout << "on the left\n";
for_each(s.left.begin(), s.left.end(), [](int x){ cout << x << " ";});
cout << endl;
cout << "-----------\n";
cout << "on the right\n";
for_each(s.right.begin(), s.right.end(), [](int x){ cout << x << " ";});
cout << endl;
return 0;
}