diff options
author | gennyble <gen@nyble.dev> | 2025-07-06 15:16:03 -0500 |
---|---|---|
committer | gennyble <gen@nyble.dev> | 2025-07-06 15:16:03 -0500 |
commit | b1aef90e6d4bc231a057b034a452e748ef59e783 (patch) | |
tree | 98960211ff0cd6a7371f1197865ed9b33e12ed3b | |
download | senseless-b1aef90e6d4bc231a057b034a452e748ef59e783.tar.gz senseless-b1aef90e6d4bc231a057b034a452e748ef59e783.zip |
meow
-rw-r--r-- | .vscode/settings.json | 3 | ||||
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | readme | 26 | ||||
-rw-r--r-- | senseless.h | 106 | ||||
-rw-r--r-- | test.c | 50 |
5 files changed, 193 insertions, 0 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b0d0749 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.formatOnSave": false +} \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1eee1a6 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +CC = gcc + +test: + $(CC) test.c -o test + ./test + +clean: + rm test \ No newline at end of file diff --git a/readme b/readme new file mode 100644 index 0000000..ae04c7f --- /dev/null +++ b/readme @@ -0,0 +1,26 @@ +senseless directions +---------------------- + +convert a series of cardinal directions into a measure of degree +because we all know that NWWWNNNWWN is a sensible way to direct. + +#INCLUDE "senseless.h" + senseless directions can be used as a single-header library. you'll + want the file called senseless.h in the root of the repository. then + just include it in your code and you're good. + +INTERFACE + double senseless_directions(const char *directions, size_t length); + takes a string of [NnEeSsWw] characters and produces a + measure of degree. + +MAKEFILE + if you have make installed you can use the following subcommands. if + make is not installed, you can look at the Makefile for the commands + that are run. + + test + compile and run the tests. + + clean + remove artifacts created by the makefile \ No newline at end of file diff --git a/senseless.h b/senseless.h new file mode 100644 index 0000000..e84eed4 --- /dev/null +++ b/senseless.h @@ -0,0 +1,106 @@ +#ifndef SENSELESS_H +#define SENSELESS_H + +#include <stddef.h> // size_t +#include <stdio.h> + +void _clamp(double lower, double upper, double *value) { + if (*value < lower) { + *value = lower; + } else if (*value > upper) { + *value = upper; + } +} + +void _wrap(double *degree) { + do { + if (*degree < 0) + *degree += 360; + + if (*degree >= 360) + *degree -= 360; + } while (*degree < 0 || *degree >= 360); +} + +void _min(double *value, double lower) { + if (*value < lower) + *value = lower; +} + +void _max(double *value, double upper) { + if (*value > upper) + *value = upper; +} + +double senseless_directions(const char *directions, size_t length) { + double degrees = 0.0; + double factor = 90.0; + size_t consumed = 0; + + do { + if (length - consumed == 0) + return degrees; + + char current = directions[consumed]; + if (consumed == 0) { + switch (current) { + case 'N': case 'n': degrees = 0; break; + case 'E': case 'e': degrees = 90; break; + case 'S': case 's': degrees = 180; break; + case 'W': case 'w': degrees = 270; break; + } + _wrap(°rees); + continue; + } + + factor /= 2; + switch (current) { + case 'N': case 'n': + if (degrees >= 180) { + degrees += factor; + } else { + degrees -= factor; + } + + _clamp(0, 360, °rees); + break; + case 'S': case 's': + if (degrees >= 0 && degrees < 180) { + degrees += factor; + + _clamp(0, 180, °rees); + } else { + degrees -= factor; + + _clamp(180, 360, °rees); + } + break; + case 'W': case 'w': + if (degrees >= 90 && degrees < 270) { + // Covers the bottom-arc + degrees += factor; + _clamp(90, 270, °rees); + } else if (degrees < 90 && degrees < factor) { + // Covers the top-right quadrant + degrees = 360 - (factor - degrees); + } else { + degrees -= factor; + _clamp(0, 360, °rees); + } + break; + case 'E': case 'e': + if (degrees >= 270 || degrees < 90) { + degrees += factor; + _wrap(°rees); + } else { + degrees -= factor; + _wrap(°rees); + } + break; + } + } while (++consumed); + + return 0.0; +} + +#endif // SENSELESS_H \ No newline at end of file diff --git a/test.c b/test.c new file mode 100644 index 0000000..d414038 --- /dev/null +++ b/test.c @@ -0,0 +1,50 @@ +#include <stdio.h> +#include <string.h> +#include <float.h> +#include <math.h> + +#include "senseless.h" + +double assert(const char *directions, double expected) { + size_t len = strlen(directions); + double degrees = senseless_directions(directions, len); + + if (fabs(degrees - expected) <= DBL_EPSILON) { + printf("✅ "); + } else { + printf("❌ "); + } + printf("%s = %.2f\n", directions, expected); + + return degrees; +} + +int main(int argc, char **argv) { + // Cardinal + printf("== Cardinal ==\n"); + assert("N", 0.0); + assert("E", 90.0); + assert("S", 180.0); + assert("W", 270.0); + + // Ordinal + printf("\n=== Ordinal ==\n"); + assert("NE", 45.0); + assert("SE", 135.0); + assert("SW", 225.0); + assert("NW", 315.0); + + // Gross + printf("\n==== Gross ===\n"); + printf("(pulls clockwise)\n"); + assert("NS", 45.0); + assert("SN", 225.0); + assert("EW", 135.0); + assert("WE", 315.0); + + // Exciting + printf("\n== Exciting ==\n"); + assert("NNW", 337.5); + assert("SEESE", 118.125); + assert("NESW", 56.25); +} \ No newline at end of file |