summaryrefslogtreecommitdiff
path: root/kattis-kth/alginda-quicksort/radix.c
diff options
context:
space:
mode:
authormathiasmagnusson <mathiasmagnussons@gmail.com>2022-12-09 18:00:41 +0100
committermathiasmagnusson <mathiasmagnussons@gmail.com>2022-12-09 18:00:41 +0100
commita1eb38bebe6ce1668c3f96489506c3b05b9fe5cb (patch)
treecccf0fd4763dba123efab7c896292dc18d1eb458 /kattis-kth/alginda-quicksort/radix.c
parente41e6c8bc72e3300a0fa137f198454341bc315b1 (diff)
downloadprogramming-problem-solving-a1eb38bebe6ce1668c3f96489506c3b05b9fe5cb.tar.gz
Move stuff around
Diffstat (limited to 'kattis-kth/alginda-quicksort/radix.c')
-rw-r--r--kattis-kth/alginda-quicksort/radix.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/kattis-kth/alginda-quicksort/radix.c b/kattis-kth/alginda-quicksort/radix.c
new file mode 100644
index 0000000..93bd111
--- /dev/null
+++ b/kattis-kth/alginda-quicksort/radix.c
@@ -0,0 +1,108 @@
+/* https://kth.kattis.com/problems/kth.alginda.quicksort */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+
+// longest int: -2147483648
+#define BUFFER_MAX (12 * 600000)
+char buffer[BUFFER_MAX];
+int xs[600000];
+int tmp[600000];
+
+void radix_sort(int n) {
+ int *out = xs;
+ int *in = tmp;
+ // we loop an even amount of times so the final sorted array will be in xs.
+ // if we looped an odd amount of times this would not be the case
+ for (int m = 0; m < 32; m += 8) {
+ int *tmp = out;
+ out = in;
+ in = tmp;
+
+ int counts[256] = { 0 };
+ for (int i = 0; i < n; i++)
+ counts[(uint8_t) (in[i] >> m)]++;
+
+ int sum = 0;
+ for (int i = 0; i < 256; i++) {
+ sum += counts[i];
+ counts[i] = sum;
+ }
+ for (int i = n - 1; i >= 0; i--) {
+ uint8_t fx = in[i] >> m;
+ counts[fx]--;
+ out[counts[fx]] = in[i];
+ }
+ }
+}
+
+int main() {
+ /* char *buffer = malloc(BUFFER_MAX); */
+ /* ssize_t len = 0; */
+ /* while (true) { */
+ /* if (len >= BUFFER_MAX) return 1; */
+ /* ssize_t r = read(0, &buffer[len], BUFFER_MAX - len); */
+ /* len += r; */
+ /* if (r == 0) */
+ /* break; */
+ /* } */
+ ssize_t len = read(0, buffer, BUFFER_MAX);
+
+ char *p = buffer;
+ char *end = &buffer[len];
+ int n = 0;
+ while (*p != ' ') {
+ n *= 10;
+ n += *p - '0';
+ p++;
+ }
+ while (*p == ' ' || *p == '\n') p++;
+
+ // 18 ms
+ for (int i = 0; i < n; i++) {
+ int x = 0;
+ bool neg = false;
+ if (*p == '-') {
+ neg = true;
+ p++;
+ }
+ while (p < end && *p != ' ' && *p != '\n') {
+ x *= 10;
+ x += *p - '0';
+ p++;
+ }
+ while (p < end && (*p == ' ' || *p == '\n')) p++;
+
+ if (neg) x = -x;
+ xs[i] = x ^ (1 << 31);
+ }
+
+ // 10 ms
+ radix_sort(n);
+
+ // 17 ms
+ p = &buffer[BUFFER_MAX - 1];
+ char *last = p;
+ *p-- = '\n';
+ for (int i = n - 1; i >= 0; i--) {
+ int signedx = xs[i] ^ (1 << 31);
+ bool neg = signedx < 0;
+ uint32_t x;
+ if (neg) x = -signedx;
+ else x = signedx;
+ do {
+ *p-- = (x % 10) + '0';
+ x /= 10;
+ } while (x > 0);
+ if (neg) *p-- = '-';
+ if (i > 0) *p-- = '\n';
+ }
+ write(1, p + 1, last - p);
+
+ /* ssize_t c = 0; */
+ /* while (c < len) c += write(1, &buffer[c], len - c); */
+}