diff --git a/Laporan Praktikum 2.docx b/Laporan Praktikum 2.docx
new file mode 100644
index 0000000000000000000000000000000000000000..85ad63d42fcc08b8262fb535f75b43cc9b4a3f69
Binary files /dev/null and b/Laporan Praktikum 2.docx differ
diff --git a/P_BucketSort2 b/P_BucketSort2
new file mode 100755
index 0000000000000000000000000000000000000000..c41ed56a5807fa8b19c141a75a7db4ace1b5b31d
Binary files /dev/null and b/P_BucketSort2 differ
diff --git a/Parallel_BucketSort2.c b/Parallel_BucketSort2.c
new file mode 100644
index 0000000000000000000000000000000000000000..db1c2a6d3f65b367a073e53ebb0fb5b204a739bd
--- /dev/null
+++ b/Parallel_BucketSort2.c
@@ -0,0 +1,150 @@
+#include <stdio.h> 
+#include <stdlib.h> 
+#include <time.h> 
+#include <mpi.h> 
+#include <assert.h> 
+
+#define tag_size 1
+#define tag_array 2
+#define main_process 0
+
+int *create_rand_nums(int num_elements) { 
+	int *rand_nums = (int *)malloc(sizeof(int) * num_elements); 
+	assert(rand_nums != NULL); 
+	int i; 
+	for (i = 0; i < num_elements; i++) { 
+		rand_nums[i] = (rand() % num_elements); 
+	} 
+	return rand_nums; 
+} 
+
+void print_array(int *array, int count) {
+	int i;
+	for (i=0;i<count;i++) {
+		printf("%d  ",array[i]);
+	}
+	printf("\n");
+}
+ 
+void *make_bucket(int *array,int *ar_result,int *num_res,int num_elements, int num_process,int total_process) {
+	int modr = num_elements % (total_process-1) ;
+	int bagi = num_elements / total_process ;
+	int batas_bawah = (num_process-1)*bagi ;
+	int batas_atas = batas_bawah + bagi - 1 ;
+	if (num_process==total_process-1) batas_atas = num_elements-1 ;
+	
+	int *array_temp=(int *)malloc(sizeof(int) * num_elements); 
+	int i,num=0 ;
+	for (i=0;i<num_elements;i++) {
+		if (array[i]>=batas_bawah && array[i]<=batas_atas) {
+			ar_result[num] = array[i];
+			num++;
+		}
+	}
+	*num_res = num;
+}
+
+int *sort_array(int *array, int num_elements) {
+	int i,j ;
+	int temp_;
+	int *result = NULL ;
+	result = array ;
+	for (i=i;i<num_elements;i++) {
+		j=i;
+		while (j>0 && result[j] < result[j-1]) {
+			temp_ = result[j] ;
+			result[j] = result[j-1];
+			result[j-1 ] = temp_;
+			j--;
+		}
+	}
+	return result;
+}
+
+
+int main(int argc, char** argv) { 
+	int counter,counter2=0,rc ;
+	MPI_Status Stat; 
+	double start,end ;
+	clock_t sc,ec ;
+	if (argc != 2) { 
+		fprintf(stderr, "Usage: avg num_elements_per_proc\n"); 
+		exit(1); 
+	} 
+	
+	int num_element = atoi(argv[1]); 
+	MPI_Init(NULL, NULL); 
+	int world_rank; 
+	MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); 
+	int world_size; 
+	MPI_Comm_size(MPI_COMM_WORLD, &world_size); 
+	
+	
+	int *sorted_array = NULL;
+	int *rand_nums = NULL; 
+	if (world_rank == 0) { 
+		rand_nums = create_rand_nums(num_element); 
+		//printf("Array : ") ; 
+		//print_array(rand_nums,num_element);
+	} 
+	int *final_array = (int *)malloc(sizeof(int) * num_element);
+	//sc = clock();
+	start = MPI_Wtime(); 
+	//Pengiriman dari proses utama
+	if (world_rank == main_process) {
+		for (counter = 1;counter<world_size;counter++) {
+			int *send_array =(int *)malloc(sizeof(int) * num_element); 
+			int size_send ;		
+			make_bucket(rand_nums,send_array,&size_send,num_element,counter,world_size);
+			printf("(MAIN) Send size %d and array to proc %d . . . \n",size_send,counter);
+			rc = MPI_Send(&size_send,1,MPI_INT,counter,tag_size,MPI_COMM_WORLD); //send num element
+			//print_array(send_array,size_send);
+			rc = MPI_Send(&send_array[0], size_send, MPI_FLOAT, counter, tag_array, MPI_COMM_WORLD); //send array
+			printf("(MAIN) Send to %d done \n",counter);
+		}
+		for (counter = 1;counter<world_size;counter++) {
+			int size_receive;
+			printf("(MAIN) Receiving size and array from proc %d. \n",counter);
+			MPI_Recv(&size_receive,1,MPI_INT,counter,tag_size,MPI_COMM_WORLD,&Stat);
+			
+			int *receive_array = (int *)malloc(sizeof(int) *size_receive); 
+			MPI_Recv(receive_array,size_receive,MPI_INT,counter,tag_array,MPI_COMM_WORLD,&Stat);
+			printf("(MAIN) Received size %d and array from proc %d. \n",size_receive,counter);
+			int i=0;
+			for (i=0;i<size_receive;i++) {
+				final_array[counter2] = receive_array[i];
+				counter2++;
+			}			
+		}
+		
+	} else if (world_rank != main_process) {
+		int size_receive ;
+		MPI_Recv(&size_receive,1,MPI_INT,0,tag_size,MPI_COMM_WORLD,&Stat);
+		int *receive_array = (int *)malloc(sizeof(int) *size_receive); 
+		printf("(Proc %d) Got size %d, now waiting for array . .  \n",world_rank,size_receive);
+		MPI_Recv(receive_array,size_receive,MPI_INT,0,tag_array,MPI_COMM_WORLD,&Stat);
+		printf("(Proc %d) Got array. Now sorting the array . . \n",world_rank);
+		//print_array(receive_array,size_receive);
+		sorted_array = sort_array(receive_array,size_receive);
+		printf("(Proc %d) Sort finish. Now send it to main process . . \n ",world_rank);
+		//print_array(sorted_array,size_receive);
+		rc = MPI_Send(&size_receive,1,MPI_INT,0,tag_size,MPI_COMM_WORLD); //send num element			
+		rc = MPI_Send(&sorted_array[0], size_receive, MPI_FLOAT, 0, tag_array, MPI_COMM_WORLD); //send array
+		printf("(Proc %d) Send finish \n",world_rank);		
+	}
+	
+	
+	if (world_rank == 0) { 
+			printf("Sorting array finished  \n");
+		//print_array(final_array,num_element);
+		end = MPI_Wtime();
+		//ec = clock();
+		//double cpu_time_used = ((double) (ec - sc)) / CLOCKS_PER_SEC;
+		printf("Time taken with MPI_TIme %.2f  second\n",end-start);
+		free(rand_nums); 
+		free(final_array);
+	} 
+	
+	MPI_Barrier(MPI_COMM_WORLD); 
+	MPI_Finalize(); 
+}