#include <bits/stdc++.h>
#define MAX 100
/*
con thieu may cai sort nua nhung khong biet thay co day khong
bo sung sau
*/
void print(int *a, int array_size);
void print(int *a, int left, int right);
void shuffle(int *array, size_t n)
{
srand(time(0));
if (n > 1)
{
size_t i;
for (i = 1; i < n - 1; i++)
{
size_t j = i + rand() / (RAND_MAX / (n - i) + 1);
int t = array[j];
array[j] = array[i];
array[i] = t;
}
}
}
// quicksort
void swap_(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
int partition_(int *a, int left, int right) {
int pivot = a[right];
int i = left - 1;
for(int j = left; j <= right - 1; j ++) {
if(a[j] < pivot) {
i++;
swap_(&a[j],&a[i]);
}
}
swap_(&a[i+1],&a[right]);
return (i+1);
}
int quicksort(int *a, int left, int right) {
int pivot_index;
if(left < right) {
int pivot_index = partition_(a, left, right);
printf("%d\n",pivot_index);
quicksort(a,left,pivot_index - 1);
print(a,left,pivot_index-1);
quicksort(a, pivot_index + 1, right);
print(a,pivot_index-1, right);
}
}
//
// merge sort
void merge_(int *a,int left, int mid, int right) {
int length = right - left + 1;
int tmp[right+1];
int i = left; // dau cua nua trai
int j = mid + 1; // dau cua nua phai;
for(int k = left ; k <= right ;k++) {
if(i > mid) {
tmp[k] = a[j];
j++;
} else if(j > right) {
tmp[k] = a[i];
i++;
} else {
if(a[i] < a[j]) {
tmp[k] = a[i];
i++;
} else if( a[i] > a[j]) {
tmp[k] = a[j];
j++;
}
}
}
for (int k = left; k <= right; k++)
{
a[k] = tmp[k];
}
}
void merge_sort(int *a,int left, int right) {
if( left < right) {
int mid = (left + right)/2;
merge_sort(a,left,mid);
merge_sort(a,mid+1,right);
merge_(a,left,mid,right);
}
print(a,left,right);
}
void print(int *a, int array_size) {
for(int i = 0 ; i < array_size ; i++) {
printf("%-5d",a[i]);
}
printf("\n");
}
void print(int *a, int left, int right) {
for(int i = left ; i <= right ; i++) {
printf("%-5d",a[i]);
}
printf("\n");
}
/*
sap xep chen
*/
void inserttion_sort(int *a, int array_size) {
int i,j, last;
for(i = 1; i < array_size ; i++) {
last = a[i];
j = i;
while((j > 0) && ( a[j-1] > last)) {
a[j] = a[j-1];
j = j - 1;
}
a[j] = last;
print(a,array_size);
}
}
/*
sap xep lua chon
*/
void selection_sort(int *a, int array_size) {
int i,j,min_,tmp;
for(i = 0; i < array_size - 1 ; i++) {
min_ = i;
for( j = i + 1; j < array_size ; j++) {
if(a[j] < a[min_]) {
min_ = j;
}
}
swap_(&a[i],&a[min_]);
print(a,array_size);
}
}
/*
sap xep noi bot
*/
void bubble_sort(int *a, int array_size) {
int i,j;
for(i = array_size - 1; i >= 0; i--) {
printf("i = %-10d\n",i);
for( j = 1 ; j <= i ; j++) {
if(a[j-1] > a[j]) {
swap_(&a[j],&a[j-1]);
print(a,array_size);
}
}
printf("\n");
}
}
/*
sap xep vun dong
*/
int root_tree(int *a) {
return a[1];
}
int left_child(int i) {
return (i<<1);
}
int right_child(int i) {
return 2*i+1;
}
int parent_node(int i) {
return i<<1 + 1;
}
int heap_size(int length_A) {
return length_A;
}
void max_heapify(int *a, int i, int heap_size) {
int left, right,n;
int largest;
n = heap_size;
left = left_child(i);
right = right_child(i);
if(left<= n && a[left] > a[i]) largest = left;
else largest = i;
if(right<=n && a[right] > a[largest]) largest = right;
if(largest != i) {
swap_(&a[i],&a[largest]); // nghia la phan tu max la con trai hoac con phai
max_heapify(a,largest,n);
}
}
void min_heapify(int *a, int i, int heap_size) {
int left, right,n;
int smallest;
n = heap_size;
left = left_child(i);
right = right_child(i);
if(left<= n && a[left] < a[i]) smallest = left;
else smallest = i;
if(right<=n && a[right] < a[smallest]) smallest = right;
if(smallest != i) {
swap_(&a[i],&a[smallest]); // nghia la phan tu max la con trai hoac con phai
min_heapify(a,smallest,n);
}
}
// neu chay bang mang thi phai set = 10
// neu chay bang hang doi thi set bang 3
int length_A = 10; // la kich thuoc that cua heap, khong chua phan tu a[0] = 0 mac dinh
/*
khoi phuc tinh chat dong cua ca cay O(logn)
*/
void build_max_heap(int *a) {
// printf("%d",a[2]);
int n = heap_size(length_A);
int i;
for(i = n/2 ; i>=1 ; i--) {
max_heapify(a,i,n);
}
}
void build_min_heap(int *a) {
int n = heap_size(length_A);
int i;
for(i = n/2 ; i>=1 ; i--) {
min_heapify(a,i,n);
}
}
/*
bat dau sap xep
*/
void heap_sort(int *a) {
// build_max_heap(a);
build_min_heap(a);
int i;
int n = heap_size(length_A);
for(i = n; i>=2 ; i--) {
swap_(&a[1],&a[i]);
// max_heapify(a,1,i-1);
min_heapify(a,1,i-1);
}
}
/*
hang doi uu tien
*/
int N; // so luong phan tu trong hang doi uu tien
/*
phai luon duy tri tinh chat dong
*/
void insert_element_queue_priority(int *a, int val) {
length_A = length_A + 1;
int i = length_A;
a[i] = val;
if(length_A >= 3) {
build_max_heap(a);
} else {
max_heapify(a,1,length_A);
}
}
/*
tra lai phan tu lon nhat trong hang doi uu tien
*/
int max_priority_queue(int *a) {
return a[1];
}
/*
tra lai phan tu lon nhat va loai bo no ra khoi hang doi
*/
int extract_max_priority_queue(int *a) {
if( length_A == 0) {
printf("queue empty\n");
return -1;
} else {
int tmp = a[length_A];
swap_(&a[1], &a[length_A]);
length_A = length_A - 1;
build_max_heap(a);
return a[length_A];
}
}
/*
tang khoa cua phan tu x(index) len gia tri k
suy ra k > x
*/
void increase_key(int *a,int x, int key) {
// voi truong hop max
if( key < a[x]) {
printf("khoa moi nho hon khoa hien tai\n");
} else {
a[x] = key;
build_max_heap(a);
}
}
int main() {
// int a[MAX] = {10,-75,-100,0,71,-48,58,34,-70,-32};
// int array_size = 10;
// print(a,array_size);
// inserttion_sort(a,array_size);
// selection_sort(a,array_size);
// bubble_sort(a,array_size);
// merge_sort(a,0,array_size-1);
// quicksort(a,0,array_size-1);
int A[MAX] = {0,4,1,3,2,16,9,10,14,8,7};
print(A,length_A + 1); // do bao gom phan tu dau tien = 0
shuffle(A,length_A + 1);
print(A,length_A + 1);
heap_sort(A);
print(A,length_A+1);
// int a[MAX];
// a[0] = 0;
// a[1] = 10;
// a[2] = 7;
// a[3] = 9;
// print(a,length_A+1);
// insert_element_queue_priority(a,15);
// print(a,length_A+1);
// printf("phan tu lon nhat trong hang doi uu tien %d\n", max_priority_queue(a));
// extract_max_priority_queue(a);
// print(a,length_A+1);
// extract_max_priority_queue(a);
// print(a,length_A+1);
// extract_max_priority_queue(a);
// print(a,length_A+1);
// extract_max_priority_queue(a);
// print(a,length_A+1);
// extract_max_priority_queue(a);
//
// insert_element_queue_priority(a,10);
// insert_element_queue_priority(a,7);
// insert_element_queue_priority(a,9);
// insert_element_queue_priority(a,15);
// print(a,length_A+1);
// increase_key(a,4,50);
// print(a,length_A+1);
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CiNkZWZpbmUgTUFYIDEwMAovKgpjb24gdGhpZXUgbWF5IGNhaSBzb3J0IG51YSBuaHVuZyBraG9uZyBiaWV0IHRoYXkgY28gZGF5IGtob25nCmJvIHN1bmcgc2F1CiovCnZvaWQgcHJpbnQoaW50ICphLCBpbnQgYXJyYXlfc2l6ZSk7CnZvaWQgcHJpbnQoaW50ICphLCBpbnQgbGVmdCwgaW50IHJpZ2h0KTsKCnZvaWQgc2h1ZmZsZShpbnQgKmFycmF5LCBzaXplX3QgbikKewogICAgc3JhbmQodGltZSgwKSk7CiAgICBpZiAobiA+IDEpCiAgICB7CiAgICAgICAgc2l6ZV90IGk7CiAgICAgICAgZm9yIChpID0gMTsgaSA8IG4gLSAxOyBpKyspCiAgICAgICAgewogICAgICAgICAgc2l6ZV90IGogPSBpICsgcmFuZCgpIC8gKFJBTkRfTUFYIC8gKG4gLSBpKSArIDEpOwogICAgICAgICAgaW50IHQgPSBhcnJheVtqXTsKICAgICAgICAgIGFycmF5W2pdID0gYXJyYXlbaV07CiAgICAgICAgICBhcnJheVtpXSA9IHQ7CiAgICAgICAgfQogICAgfQp9Ci8vIHF1aWNrc29ydAp2b2lkIHN3YXBfKGludCAqYSwgaW50ICpiKSB7CiAgICBpbnQgdG1wID0gKmE7CiAgICAqYSA9ICpiOwogICAgKmIgPSB0bXA7Cn0KCmludCBwYXJ0aXRpb25fKGludCAqYSwgaW50IGxlZnQsIGludCByaWdodCkgewogICAgaW50IHBpdm90ID0gYVtyaWdodF07CiAgICBpbnQgaSA9IGxlZnQgLSAxOwoKICAgIGZvcihpbnQgaiA9IGxlZnQ7IGogPD0gcmlnaHQgLSAxOyBqICsrKSB7CiAgICAgICAgaWYoYVtqXSA8IHBpdm90KSB7CiAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgc3dhcF8oJmFbal0sJmFbaV0pOwogICAgICAgIH0KICAgIH0KICAgIHN3YXBfKCZhW2krMV0sJmFbcmlnaHRdKTsKICAgIHJldHVybiAoaSsxKTsKfQoKaW50IHF1aWNrc29ydChpbnQgKmEsIGludCBsZWZ0LCBpbnQgcmlnaHQpIHsKICAgIGludCBwaXZvdF9pbmRleDsKICAgIGlmKGxlZnQgPCByaWdodCkgewogICAgICAgIGludCBwaXZvdF9pbmRleCA9IHBhcnRpdGlvbl8oYSwgbGVmdCwgcmlnaHQpOwogICAgICAgIHByaW50ZigiJWRcbiIscGl2b3RfaW5kZXgpOwogICAgICAgIHF1aWNrc29ydChhLGxlZnQscGl2b3RfaW5kZXggLSAxKTsKICAgICAgICBwcmludChhLGxlZnQscGl2b3RfaW5kZXgtMSk7CiAgICAgICAgcXVpY2tzb3J0KGEsIHBpdm90X2luZGV4ICsgMSwgcmlnaHQpOwogICAgICAgIHByaW50KGEscGl2b3RfaW5kZXgtMSwgcmlnaHQpOwoKICAgIH0KCn0KLy8KCi8vIG1lcmdlIHNvcnQKCnZvaWQgbWVyZ2VfKGludCAqYSxpbnQgbGVmdCwgaW50IG1pZCwgaW50IHJpZ2h0KSB7CiAgICBpbnQgbGVuZ3RoID0gcmlnaHQgLSBsZWZ0ICsgMTsKICAgIGludCB0bXBbcmlnaHQrMV07CiAgICBpbnQgaSA9IGxlZnQ7IC8vIGRhdSBjdWEgbnVhIHRyYWkKICAgIGludCBqID0gbWlkICsgMTsgLy8gZGF1IGN1YSBudWEgcGhhaTsKICAgIGZvcihpbnQgayA9IGxlZnQgOyBrIDw9IHJpZ2h0IDtrKyspIHsKICAgICAgICBpZihpID4gbWlkKSB7CiAgICAgICAgICAgIHRtcFtrXSA9IGFbal07CiAgICAgICAgICAgIGorKzsKICAgICAgICB9IGVsc2UgaWYoaiA+IHJpZ2h0KSB7CiAgICAgICAgICAgIHRtcFtrXSA9IGFbaV07CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYoYVtpXSA8IGFbal0pIHsKICAgICAgICAgICAgICAgIHRtcFtrXSA9IGFbaV07CiAgICAgICAgICAgICAgICBpKys7CiAgICAgICAgICAgIH0gZWxzZSBpZiggYVtpXSA+IGFbal0pIHsKICAgICAgICAgICAgICAgIHRtcFtrXSA9IGFbal07CiAgICAgICAgICAgICAgICBqKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBmb3IgKGludCBrID0gbGVmdDsgayA8PSByaWdodDsgaysrKQogICAgewogICAgICAgIGFba10gPSB0bXBba107CiAgICB9Cgp9Cgp2b2lkIG1lcmdlX3NvcnQoaW50ICphLGludCBsZWZ0LCBpbnQgcmlnaHQpIHsKICAgIGlmKCBsZWZ0IDwgcmlnaHQpIHsKICAgICAgICBpbnQgbWlkID0gKGxlZnQgKyByaWdodCkvMjsKICAgICAgICBtZXJnZV9zb3J0KGEsbGVmdCxtaWQpOwogICAgICAgIG1lcmdlX3NvcnQoYSxtaWQrMSxyaWdodCk7CiAgICAgICAgbWVyZ2VfKGEsbGVmdCxtaWQscmlnaHQpOwogICAgfQogICAgcHJpbnQoYSxsZWZ0LHJpZ2h0KTsKfQoKdm9pZCBwcmludChpbnQgKmEsIGludCBhcnJheV9zaXplKSB7CiAgICBmb3IoaW50IGkgPSAwIDsgaSA8ICBhcnJheV9zaXplIDsgaSsrKSB7CiAgICAgICAgcHJpbnRmKCIlLTVkIixhW2ldKTsKICAgIH0KICAgIHByaW50ZigiXG4iKTsKfQp2b2lkIHByaW50KGludCAqYSwgaW50IGxlZnQsIGludCByaWdodCkgewogICAgZm9yKGludCBpID0gbGVmdCA7IGkgPD0gIHJpZ2h0IDsgaSsrKSB7CiAgICAgICAgcHJpbnRmKCIlLTVkIixhW2ldKTsKICAgIH0KICAgIHByaW50ZigiXG4iKTsKfQovKgogICAgc2FwIHhlcCBjaGVuCiovCnZvaWQgaW5zZXJ0dGlvbl9zb3J0KGludCAqYSwgaW50IGFycmF5X3NpemUpIHsKICAgIGludCBpLGosIGxhc3Q7CiAgICBmb3IoaSA9IDE7IGkgPCBhcnJheV9zaXplIDsgaSsrKSB7CiAgICAgICAgbGFzdCA9IGFbaV07CiAgICAgICAgaiA9IGk7CiAgICAgICAgd2hpbGUoKGogPiAwKSAmJiAoIGFbai0xXSA+IGxhc3QpKSB7CiAgICAgICAgICAgIGFbal0gPSBhW2otMV07CiAgICAgICAgICAgIGogPSBqIC0gMTsKICAgICAgICB9CiAgICAgICAgYVtqXSA9IGxhc3Q7CiAgICAgICAgcHJpbnQoYSxhcnJheV9zaXplKTsKICAgIH0KfQovKgogICAgc2FwIHhlcCBsdWEgY2hvbgoqLwoKdm9pZCBzZWxlY3Rpb25fc29ydChpbnQgKmEsIGludCBhcnJheV9zaXplKSB7CiAgICBpbnQgaSxqLG1pbl8sdG1wOwogICAgZm9yKGkgPSAwOyBpIDwgYXJyYXlfc2l6ZSAtIDEgOyBpKyspIHsKICAgICAgICBtaW5fID0gaTsKICAgICAgICBmb3IoIGogPSBpICsgMTsgaiA8IGFycmF5X3NpemUgOyBqKyspIHsKICAgICAgICAgICAgaWYoYVtqXSA8IGFbbWluX10pIHsKICAgICAgICAgICAgICAgIG1pbl8gPSBqOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHN3YXBfKCZhW2ldLCZhW21pbl9dKTsKICAgICAgICBwcmludChhLGFycmF5X3NpemUpOwogICAgfQp9CgovKgogICAgc2FwIHhlcCBub2kgYm90CiovCgp2b2lkIGJ1YmJsZV9zb3J0KGludCAqYSwgaW50IGFycmF5X3NpemUpIHsKICAgIGludCBpLGo7CiAgICBmb3IoaSA9IGFycmF5X3NpemUgLSAxOyBpID49IDA7IGktLSkgewogICAgICAgIHByaW50ZigiaSA9ICUtMTBkXG4iLGkpOwogICAgICAgIGZvciggaiA9IDEgOyBqIDw9IGkgOyBqKyspIHsKICAgICAgICAgICAgaWYoYVtqLTFdID4gYVtqXSkgewogICAgICAgICAgICAgICAgc3dhcF8oJmFbal0sJmFbai0xXSk7CiAgICAgICAgICAgICAgICBwcmludChhLGFycmF5X3NpemUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHByaW50ZigiXG4iKTsKICAgIH0KfQoKCi8qCiAgICBzYXAgeGVwIHZ1biBkb25nCiovCgppbnQgcm9vdF90cmVlKGludCAqYSkgewogICAgcmV0dXJuIGFbMV07Cn0KCmludCBsZWZ0X2NoaWxkKGludCBpKSB7CiAgICByZXR1cm4gKGk8PDEpOwp9CgppbnQgcmlnaHRfY2hpbGQoaW50IGkpIHsKICAgIHJldHVybiAyKmkrMTsKfQoKaW50IHBhcmVudF9ub2RlKGludCBpKSB7CiAgICByZXR1cm4gaTw8MSArIDE7Cn0KCmludCBoZWFwX3NpemUoaW50IGxlbmd0aF9BKSB7CiAgICByZXR1cm4gbGVuZ3RoX0E7Cn0KCnZvaWQgbWF4X2hlYXBpZnkoaW50ICphLCBpbnQgaSwgaW50IGhlYXBfc2l6ZSkgewogICAgaW50IGxlZnQsIHJpZ2h0LG47CiAgICBpbnQgbGFyZ2VzdDsKICAgIG4gPSBoZWFwX3NpemU7CiAgICBsZWZ0ID0gbGVmdF9jaGlsZChpKTsKICAgIHJpZ2h0ID0gcmlnaHRfY2hpbGQoaSk7CiAgICBpZihsZWZ0PD0gbiAmJiBhW2xlZnRdID4gYVtpXSkgbGFyZ2VzdCA9IGxlZnQ7CiAgICBlbHNlIGxhcmdlc3QgPSBpOwogICAgaWYocmlnaHQ8PW4gJiYgYVtyaWdodF0gPiBhW2xhcmdlc3RdKSBsYXJnZXN0ID0gcmlnaHQ7CgogICAgaWYobGFyZ2VzdCAhPSBpKSAgewogICAgICAgIHN3YXBfKCZhW2ldLCZhW2xhcmdlc3RdKTsgLy8gbmdoaWEgbGEgcGhhbiB0dSBtYXggbGEgY29uIHRyYWkgaG9hYyBjb24gcGhhaQogICAgICAgIG1heF9oZWFwaWZ5KGEsbGFyZ2VzdCxuKTsKICAgIH0KCn0KCnZvaWQgbWluX2hlYXBpZnkoaW50ICphLCBpbnQgaSwgaW50IGhlYXBfc2l6ZSkgewogICAgaW50IGxlZnQsIHJpZ2h0LG47CiAgICBpbnQgc21hbGxlc3Q7CiAgICBuID0gaGVhcF9zaXplOwogICAgbGVmdCA9IGxlZnRfY2hpbGQoaSk7CiAgICByaWdodCA9IHJpZ2h0X2NoaWxkKGkpOwogICAgaWYobGVmdDw9IG4gJiYgYVtsZWZ0XSA8IGFbaV0pIHNtYWxsZXN0ID0gbGVmdDsKICAgIGVsc2Ugc21hbGxlc3QgPSBpOwogICAgaWYocmlnaHQ8PW4gJiYgYVtyaWdodF0gPCBhW3NtYWxsZXN0XSkgc21hbGxlc3QgPSByaWdodDsKCiAgICBpZihzbWFsbGVzdCAhPSBpKSAgewogICAgICAgIHN3YXBfKCZhW2ldLCZhW3NtYWxsZXN0XSk7IC8vIG5naGlhIGxhIHBoYW4gdHUgbWF4IGxhIGNvbiB0cmFpIGhvYWMgY29uIHBoYWkKICAgICAgICBtaW5faGVhcGlmeShhLHNtYWxsZXN0LG4pOwogICAgfQoKfQovLyBuZXUgY2hheSBiYW5nIG1hbmcgdGhpIHBoYWkgc2V0ID0gMTAKLy8gbmV1IGNoYXkgYmFuZyBoYW5nIGRvaSB0aGkgc2V0IGJhbmcgMwppbnQgbGVuZ3RoX0EgPSAxMDsgLy8gbGEga2ljaCB0aHVvYyB0aGF0IGN1YSBoZWFwLCBraG9uZyBjaHVhIHBoYW4gdHUgYVswXSA9IDAgbWFjIGRpbmgKLyoKICAgIGtob2kgcGh1YyB0aW5oIGNoYXQgZG9uZyBjdWEgY2EgY2F5IE8obG9nbikKKi8Kdm9pZCBidWlsZF9tYXhfaGVhcChpbnQgKmEpIHsKLy8gICAgcHJpbnRmKCIlZCIsYVsyXSk7CiAgICBpbnQgbiA9IGhlYXBfc2l6ZShsZW5ndGhfQSk7CiAgICBpbnQgaTsKICAgIGZvcihpID0gbi8yIDsgaT49MSA7IGktLSkgewogICAgICAgIG1heF9oZWFwaWZ5KGEsaSxuKTsKICAgIH0KfQoKdm9pZCBidWlsZF9taW5faGVhcChpbnQgKmEpIHsKICAgIGludCBuID0gaGVhcF9zaXplKGxlbmd0aF9BKTsKICAgIGludCBpOwogICAgZm9yKGkgPSBuLzIgOyBpPj0xIDsgaS0tKSB7CiAgICAgICAgbWluX2hlYXBpZnkoYSxpLG4pOwogICAgfQp9CgovKgogICAgYmF0IGRhdSBzYXAgeGVwCiovCgp2b2lkIGhlYXBfc29ydChpbnQgKmEpIHsKLy8gICAgYnVpbGRfbWF4X2hlYXAoYSk7CiAgICBidWlsZF9taW5faGVhcChhKTsKICAgIGludCBpOwogICAgaW50IG4gPSBoZWFwX3NpemUobGVuZ3RoX0EpOwogICAgZm9yKGkgPSBuOyBpPj0yIDsgaS0tKSB7CiAgICAgICAgc3dhcF8oJmFbMV0sJmFbaV0pOwovLyAgICAgICAgbWF4X2hlYXBpZnkoYSwxLGktMSk7CiAgICAgICAgICBtaW5faGVhcGlmeShhLDEsaS0xKTsKICAgIH0KfQoKCi8qCmhhbmcgZG9pIHV1IHRpZW4KKi8KaW50IE47IC8vIHNvIGx1b25nIHBoYW4gdHUgdHJvbmcgaGFuZyBkb2kgdXUgdGllbgovKgogICAgcGhhaSBsdW9uIGR1eSB0cmkgdGluaCBjaGF0IGRvbmcKKi8Kdm9pZCBpbnNlcnRfZWxlbWVudF9xdWV1ZV9wcmlvcml0eShpbnQgKmEsIGludCB2YWwpIHsKICAgIGxlbmd0aF9BID0gbGVuZ3RoX0EgKyAxOwogICAgaW50IGkgPSBsZW5ndGhfQTsKICAgIGFbaV0gPSB2YWw7CiAgICBpZihsZW5ndGhfQSA+PSAzKSB7CiAgICAgICAgYnVpbGRfbWF4X2hlYXAoYSk7CiAgICB9IGVsc2UgewogICAgICAgIG1heF9oZWFwaWZ5KGEsMSxsZW5ndGhfQSk7CiAgICB9Cn0KLyoKICAgIHRyYSBsYWkgcGhhbiB0dSBsb24gbmhhdCB0cm9uZyBoYW5nIGRvaSB1dSB0aWVuCiovCmludCBtYXhfcHJpb3JpdHlfcXVldWUoaW50ICphKSB7CiAgICByZXR1cm4gYVsxXTsKfQoKCi8qCiAgICB0cmEgbGFpIHBoYW4gdHUgbG9uIG5oYXQgdmEgbG9haSBibyBubyByYSBraG9pIGhhbmcgZG9pCiovCmludCBleHRyYWN0X21heF9wcmlvcml0eV9xdWV1ZShpbnQgKmEpIHsKICAgIGlmKCBsZW5ndGhfQSA9PSAwKSB7CiAgICAgICAgcHJpbnRmKCJxdWV1ZSBlbXB0eVxuIik7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfSBlbHNlIHsKICAgICAgICBpbnQgdG1wID0gYVtsZW5ndGhfQV07CiAgICAgICAgc3dhcF8oJmFbMV0sICZhW2xlbmd0aF9BXSk7CiAgICAgICAgbGVuZ3RoX0EgPSBsZW5ndGhfQSAtIDE7CiAgICAgICAgYnVpbGRfbWF4X2hlYXAoYSk7CiAgICAgICAgcmV0dXJuIGFbbGVuZ3RoX0FdOwogICAgfQp9Ci8qCiAgICB0YW5nIGtob2EgY3VhIHBoYW4gdHUgeChpbmRleCkgbGVuIGdpYSB0cmkgIGsKICAgIHN1eSByYSBrID4geAoqLwp2b2lkIGluY3JlYXNlX2tleShpbnQgKmEsaW50IHgsIGludCBrZXkpIHsKICAgIC8vIHZvaSB0cnVvbmcgaG9wIG1heAogICAgaWYoIGtleSA8IGFbeF0pIHsKICAgICAgICBwcmludGYoImtob2EgbW9pIG5obyBob24ga2hvYSBoaWVuIHRhaVxuIik7CgogICAgfSBlbHNlIHsKICAgICAgICBhW3hdID0ga2V5OwogICAgICAgIGJ1aWxkX21heF9oZWFwKGEpOwogICAgfQp9CmludCBtYWluKCkgewovLyAgICBpbnQgYVtNQVhdID0gezEwLC03NSwtMTAwLDAsNzEsLTQ4LDU4LDM0LC03MCwtMzJ9OwovLyAgICBpbnQgYXJyYXlfc2l6ZSA9IDEwOwovLyAgICBwcmludChhLGFycmF5X3NpemUpOwovLyAgICBpbnNlcnR0aW9uX3NvcnQoYSxhcnJheV9zaXplKTsKLy8gICAgc2VsZWN0aW9uX3NvcnQoYSxhcnJheV9zaXplKTsKLy8gICAgYnViYmxlX3NvcnQoYSxhcnJheV9zaXplKTsKLy8gICAgbWVyZ2Vfc29ydChhLDAsYXJyYXlfc2l6ZS0xKTsKLy8gICAgcXVpY2tzb3J0KGEsMCxhcnJheV9zaXplLTEpOwoKICAgIGludCBBW01BWF0gPSB7MCw0LDEsMywyLDE2LDksMTAsMTQsOCw3fTsKICAgIHByaW50KEEsbGVuZ3RoX0EgKyAxKTsgLy8gZG8gYmFvIGdvbSBwaGFuIHR1IGRhdSB0aWVuICA9IDAKICAgIHNodWZmbGUoQSxsZW5ndGhfQSArIDEpOwogICAgcHJpbnQoQSxsZW5ndGhfQSArIDEpOwogICAgaGVhcF9zb3J0KEEpOwogICAgcHJpbnQoQSxsZW5ndGhfQSsxKTsKCi8vICAgIGludCBhW01BWF07Ci8vICAgIGFbMF0gPSAwOwovLyAgICBhWzFdID0gMTA7Ci8vICAgIGFbMl0gID0gNzsKLy8gICAgYVszXSA9IDk7Ci8vICAgIHByaW50KGEsbGVuZ3RoX0ErMSk7Ci8vICAgIGluc2VydF9lbGVtZW50X3F1ZXVlX3ByaW9yaXR5KGEsMTUpOwovLyAgICBwcmludChhLGxlbmd0aF9BKzEpOwovLyAgICBwcmludGYoInBoYW4gdHUgbG9uIG5oYXQgdHJvbmcgaGFuZyBkb2kgdXUgdGllbiAlZFxuIiwgbWF4X3ByaW9yaXR5X3F1ZXVlKGEpKTsKLy8gICAgZXh0cmFjdF9tYXhfcHJpb3JpdHlfcXVldWUoYSk7Ci8vICAgIHByaW50KGEsbGVuZ3RoX0ErMSk7Ci8vICAgIGV4dHJhY3RfbWF4X3ByaW9yaXR5X3F1ZXVlKGEpOwovLyAgICBwcmludChhLGxlbmd0aF9BKzEpOwovLyAgICBleHRyYWN0X21heF9wcmlvcml0eV9xdWV1ZShhKTsKLy8gICAgcHJpbnQoYSxsZW5ndGhfQSsxKTsKLy8gICAgZXh0cmFjdF9tYXhfcHJpb3JpdHlfcXVldWUoYSk7Ci8vICAgIHByaW50KGEsbGVuZ3RoX0ErMSk7Ci8vICAgIGV4dHJhY3RfbWF4X3ByaW9yaXR5X3F1ZXVlKGEpOwovLwovLyAgICBpbnNlcnRfZWxlbWVudF9xdWV1ZV9wcmlvcml0eShhLDEwKTsKLy8gICAgaW5zZXJ0X2VsZW1lbnRfcXVldWVfcHJpb3JpdHkoYSw3KTsKLy8gICAgaW5zZXJ0X2VsZW1lbnRfcXVldWVfcHJpb3JpdHkoYSw5KTsKLy8gICAgaW5zZXJ0X2VsZW1lbnRfcXVldWVfcHJpb3JpdHkoYSwxNSk7Ci8vICAgIHByaW50KGEsbGVuZ3RoX0ErMSk7Ci8vICAgIGluY3JlYXNlX2tleShhLDQsNTApOwovLyAgICBwcmludChhLGxlbmd0aF9BKzEpOwoKICAgIHJldHVybiAwOwp9Cg==