From 8a2ad162ea84d4e15efb884ccf8f8e8110fd8c07 Mon Sep 17 00:00:00 2001
From: Ariel Almeida <69123486+ArielMAJ@users.noreply.github.com>
Date: Fri, 6 Oct 2023 21:39:57 -0300
Subject: [PATCH 1/2] Create 0912-sort-an-array.c

---
 c/0912-sort-an-array.c | 66 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)
 create mode 100644 c/0912-sort-an-array.c

diff --git a/c/0912-sort-an-array.c b/c/0912-sort-an-array.c
new file mode 100644
index 000000000..2e3894722
--- /dev/null
+++ b/c/0912-sort-an-array.c
@@ -0,0 +1,66 @@
+// This is optimized for arrays with repeated values. Simple quicksort in arrays with lots of repeated 
+// values will fall to O(n^2). This will hold it under O(nlogn) but end up slower and consuming more space overall.
+
+/**
+ * Note: The returned array must be malloced, assume caller calls free().
+ */
+
+void swap(int *first_value, int *second_value);
+int *partition3(int *array, int left, int right);
+void quicksort(int *array, int array_length);
+void _quicksort(int *array, int array_length, int left, int right);
+
+int LEFT_MOST = 0;
+int RIGHT_MOST = 1;
+
+int *sortArray(int *nums, int numsSize, int *returnSize) {
+  _quicksort(nums, numsSize, 0, numsSize - 1);
+  *returnSize = numsSize;
+  return nums;
+}
+
+void _quicksort(int *array, int array_length, int left, int right) {
+  while (left < right) {
+    int *middle = partition3(array, left, right);
+    if (middle[LEFT_MOST] - left < right - middle[RIGHT_MOST]) {
+      _quicksort(array, array_length, left, middle[LEFT_MOST] - 1);
+      left = middle[RIGHT_MOST] + 1;
+    } else {
+      _quicksort(array, array_length, middle[RIGHT_MOST] + 1, right);
+      right = middle[LEFT_MOST] - 1;
+    }
+    free(middle);
+  }
+}
+
+int *partition3(int *array, int left, int right) {
+  int pivot_position = left + (right - left) / 2;
+  int pivot = array[pivot_position];
+  swap(&array[left], &array[pivot_position]);
+
+  int *middle = (int *)malloc(2 * sizeof(int));
+
+  middle[LEFT_MOST] = left;
+  middle[RIGHT_MOST] = left;
+
+  for (int i = left + 1; i <= right; ++i) {
+    if (array[i] == pivot) {
+      middle[RIGHT_MOST]++;
+      swap(&array[middle[RIGHT_MOST]], &array[i]);
+    }
+    if (array[i] < pivot) {
+      middle[LEFT_MOST]++;
+      middle[RIGHT_MOST]++;
+      swap(&array[middle[RIGHT_MOST]], &array[i]);
+      swap(&array[middle[LEFT_MOST]], &array[middle[RIGHT_MOST]]);
+    }
+  }
+  swap(&array[left], &array[middle[LEFT_MOST]]);
+  return middle;
+}
+
+void swap(int *first_value, int *second_value) {
+  int tmp_value = *first_value;
+  *first_value = *second_value;
+  *second_value = tmp_value;
+}

From 6c410277a057d26ef43b68d26b029f23641f1c8b Mon Sep 17 00:00:00 2001
From: Ariel Almeida <69123486+ArielMAJ@users.noreply.github.com>
Date: Mon, 16 Oct 2023 19:17:16 -0300
Subject: [PATCH 2/2] Update 0912-sort-an-array.c

---
 c/0912-sort-an-array.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/c/0912-sort-an-array.c b/c/0912-sort-an-array.c
index 2e3894722..f4b705dd1 100644
--- a/c/0912-sort-an-array.c
+++ b/c/0912-sort-an-array.c
@@ -1,5 +1,7 @@
-// This is optimized for arrays with repeated values. Simple quicksort in arrays with lots of repeated 
-// values will fall to O(n^2). This will hold it under O(nlogn) but end up slower and consuming more space overall.
+// This is optimized for arrays with repeated values. Simple quicksort in arrays
+// with lots of repeated values will fall to O(n^2). This will hold it under
+// O(nlogn) but might end up running slower and consuming more space in average.
+// The array is sorted inplace.
 
 /**
  * Note: The returned array must be malloced, assume caller calls free().
@@ -7,11 +9,9 @@
 
 void swap(int *first_value, int *second_value);
 int *partition3(int *array, int left, int right);
-void quicksort(int *array, int array_length);
 void _quicksort(int *array, int array_length, int left, int right);
 
-int LEFT_MOST = 0;
-int RIGHT_MOST = 1;
+enum Position { LEFT_MOST, RIGHT_MOST };
 
 int *sortArray(int *nums, int numsSize, int *returnSize) {
   _quicksort(nums, numsSize, 0, numsSize - 1);
