#include <iostream>
#include <cstdlib>
#include <random>
#include <chrono>
#include <algorithm>
using namespace std;
int partition_random(int a[], int p, int r);
int partition(int a[], int p, int r) {
int t = a[r];
int i = p - 1;
for (int j = p; j < r;j++){
if (a[j] <= t) {
i += 1;
std::swap(a[i], a[j]);
}
}
std::swap(a[i + 1], a[r]);
return i + 1;
}
int quick_select(int a[], int s, int n, int k) {
int r = partition_random(a, s, n);
if (r - s == k - 1) {return a[r];}
else {
if (k - 1 < r - s) {
return quick_select(a, s, r - 1, k);
}
else {
return quick_select(a, r + 1 , n, k - r + s - 1);
}
}
}
int partition_random(int a[], int p, int r) {
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<int> uni(p, r);
auto rn = uni(rng);
std::swap(a[r], a[rn]);
return partition(a, p, r);
}
float median(int a [], int n) {
if (n % 2 == 1)
return quick_select(a, 0, n - 1, n / 2 + 1);
int l = n / 2;
int r = n / 2 + 1;
return (1.0 * (quick_select(a, 0, n - 1, l) +
quick_select(a, 0, n - 1, r))) / 2;
}
int main() {
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
const int size = 5;
int am[size] {-2, -2, 1, 0, -1};
/*
srand(seed);
for(int i=0; i < size; i++) {
am[i] = (rand() % size) - (size/2);
}
*/
int expectedVal = -1;
for(int i=0; i < size * 2; i++) {
shuffle (am, am + size, std::default_random_engine(seed));
cout << "-- array: ";
for(int j=0; j < size; j++) {
cout << " " << am[j];
}
cout << "\n";
float med = median(am, size);
cout << "median: " << med << ", ok? " << (med == expectedVal ? "T": "F") << "\n";
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y3N0ZGxpYj4KI2luY2x1ZGUgPHJhbmRvbT4KI2luY2x1ZGUgPGNocm9ubz4KI2luY2x1ZGUgPGFsZ29yaXRobT4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgppbnQgcGFydGl0aW9uX3JhbmRvbShpbnQgYVtdLCBpbnQgcCwgaW50IHIpOwoKaW50IHBhcnRpdGlvbihpbnQgYVtdLCBpbnQgcCwgaW50IHIpIHsKIGludCB0ID0gYVtyXTsKIGludCBpID0gcCAtIDE7CiBmb3IgKGludCBqID0gcDsgaiA8IHI7aisrKXsKICBpZiAoYVtqXSA8PSB0KSB7CiAgIGkgKz0gMTsKICAgc3RkOjpzd2FwKGFbaV0sIGFbal0pOwogIH0KIH0KIHN0ZDo6c3dhcChhW2kgKyAxXSwgYVtyXSk7CiByZXR1cm4gaSArIDE7Cn0KCmludCBxdWlja19zZWxlY3QoaW50IGFbXSwgaW50IHMsIGludCBuLCBpbnQgaykgewogIGludCByID0gcGFydGl0aW9uX3JhbmRvbShhLCBzLCBuKTsKICBpZiAociAtIHMgPT0gayAtIDEpIHtyZXR1cm4gYVtyXTt9CiAgZWxzZSB7CiAgCiAgaWYgKGsgLSAxIDwgciAtIHMpIHsKICAgcmV0dXJuIHF1aWNrX3NlbGVjdChhLCBzLCByIC0gMSwgayk7CiAgfQogIGVsc2UgIHsKICAgcmV0dXJuIHF1aWNrX3NlbGVjdChhLCByICsgMSAsIG4sIGsgLSByICsgcyAtIDEpOwogIH0KIH0KfQoKaW50IHBhcnRpdGlvbl9yYW5kb20oaW50IGFbXSwgaW50IHAsIGludCByKSB7CiBzdGQ6OnJhbmRvbV9kZXZpY2UgcmQ7ICAgICAKIHN0ZDo6bXQxOTkzNyBybmcocmQoKSk7ICAgCiBzdGQ6OnVuaWZvcm1faW50X2Rpc3RyaWJ1dGlvbjxpbnQ+IHVuaShwLCByKTsgCiBhdXRvIHJuID0gdW5pKHJuZyk7CiBzdGQ6OnN3YXAoYVtyXSwgYVtybl0pOwogcmV0dXJuIHBhcnRpdGlvbihhLCBwLCByKTsKfQoKZmxvYXQgbWVkaWFuKGludCBhIFtdLCBpbnQgbikgewogaWYgKG4gJSAyID09IDEpCiAgcmV0dXJuIHF1aWNrX3NlbGVjdChhLCAwLCBuIC0gMSwgbiAvIDIgKyAxKTsKIGludCBsID0gbiAvIDI7CiBpbnQgciA9IG4gLyAyICsgMTsKIHJldHVybiAoMS4wICogKHF1aWNrX3NlbGVjdChhLCAwLCBuIC0gMSwgbCkgKyAKICAgcXVpY2tfc2VsZWN0KGEsIDAsIG4gLSAxLCByKSkpIC8gMjsKfQoKaW50IG1haW4oKSB7CgkgdW5zaWduZWQgc2VlZCA9IHN0ZDo6Y2hyb25vOjpzeXN0ZW1fY2xvY2s6Om5vdygpLnRpbWVfc2luY2VfZXBvY2goKS5jb3VudCgpOwoKCWNvbnN0IGludCBzaXplID0gNTsKCWludCBhbVtzaXplXSB7LTIsIC0yLCAxLCAwLCAtMX07CgkKLyoKICAgIHNyYW5kKHNlZWQpOwoJCglmb3IoaW50IGk9MDsgaSA8IHNpemU7IGkrKykgewoJICAgYW1baV0gPSAocmFuZCgpICUgc2l6ZSkgLSAoc2l6ZS8yKTsgCQoJfQoqLwoKCWludCBleHBlY3RlZFZhbCA9IC0xOwoJCglmb3IoaW50IGk9MDsgaSA8IHNpemUgKiAyOyBpKyspIHsKCSAgCXNodWZmbGUgKGFtLCBhbSArIHNpemUsIHN0ZDo6ZGVmYXVsdF9yYW5kb21fZW5naW5lKHNlZWQpKTsKCSAgCWNvdXQgPDwgIi0tIGFycmF5OiAiOwogICAgIAlmb3IoaW50IGo9MDsgaiA8IHNpemU7IGorKykgewogICAgIAkJY291dCA8PCAiICIgPDwgYW1bal07CiAgICAgCX0KICAgICAJY291dCA8PCAiXG4iOwoJICAJCgkgIAlmbG9hdCBtZWQgPSBtZWRpYW4oYW0sIHNpemUpOwoJICAJY291dCA8PCAibWVkaWFuOiAiIDw8IG1lZCA8PCAiLCBvaz8gIiA8PCAobWVkID09IGV4cGVjdGVkVmFsID8gIlQiOiAiRiIpIDw8ICJcbiI7Cgl9CgkKCXJldHVybiAwOwp9