diff --git a/haversine_02/include/processor/proc_argparser.h b/haversine_02/include/processor/proc_argparser.h new file mode 100644 index 0000000..0632c93 --- /dev/null +++ b/haversine_02/include/processor/proc_argparser.h @@ -0,0 +1,12 @@ +#ifndef PROC_ARGPARSER_H +#define PROC_ARGPARSER_H + +#include "aliases.h" + +struct ProcessorArgs { + const char *filepath; +}; + +ProcessorArgs parse_args(i32 argc, char *argv[]); + +#endif // !PROC_ARGPARSER_H diff --git a/haversine_02/src/processor/main.cpp b/haversine_02/src/processor/main.cpp new file mode 100644 index 0000000..38ac16a --- /dev/null +++ b/haversine_02/src/processor/main.cpp @@ -0,0 +1,89 @@ +#include "haversine.h" +#include "point_types.h" +#include "processor/proc_argparser.h" +#include "json/dstring.h" +#include "json/json_entities.h" +#include "json/parser.h" +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + ProcessorArgs args = parse_args(argc, argv); + + jentity_t *root = load_json(args.filepath); + + assert(root->type == JENTITY_SINGLE && root->value.type == JVAL_COLLECTION); + + jentity_t *pairs = root->value.collection->begin; + + assert(pairs->type == JENTITY_PAIR && + pairs->pair.value.type == JVAL_COLLECTION); + + u64 pair_count = pairs->pair.value.collection->size; + + PointPair *point_pairs = (PointPair *)malloc(sizeof(PointPair) * pair_count); + memset(point_pairs, 0, pair_count); + + u64 index = 0; + + for (jentity_t *pair = pairs->pair.value.collection->begin; pair != NULL; + pair = pair->next) { + assert(index < pair_count && pair->type == JENTITY_SINGLE && + pair->value.type == JVAL_COLLECTION && + pair->value.collection->size == 4); + + jentity_t *x0 = pair->value.collection->begin; + jentity_t *y0 = x0->next; + jentity_t *x1 = y0->next; + jentity_t *y1 = x1->next; + + PointPair p = { + {x0->pair.value.num_dbl, y0->pair.value.num_dbl}, + {x1->pair.value.num_dbl, y1->pair.value.num_dbl}, + }; + + point_pairs[index++] = p; + } + + const char *filename = "count_and_distances"; + + FILE *fp = fopen(filename, "r"); + if (!fp) { + printf("Failed to open the %s file", filename); + } else { + // Skip the count + fseek(fp, sizeof(u64), SEEK_SET); + } + + f64 sum = 0.0; + f64 distance = 0.0; + f64 saved_distance = 0.0; + for (u64 i = 0; i < pair_count; ++i) { + distance = haversine_of_degrees(point_pairs[i], EARTH_RADIUS_KM); + + if (fp) { + fread(&saved_distance, sizeof(f64), 1, fp); + + if (fabs(distance - saved_distance) > FLT_EPSILON) { + printf("%llu: %.16f does not equal %.16f\n", (unsigned long long)i, + distance, saved_distance); + } + } + + sum += distance; + } + printf("\nAVERAGE DISTANCE: %f\n", sum / pair_count); + + if (fp) { + fclose(fp); + } + + free(point_pairs); + + return 0; +} diff --git a/haversine_02/src/processor/proc_argparser.cpp b/haversine_02/src/processor/proc_argparser.cpp new file mode 100644 index 0000000..3df1e17 --- /dev/null +++ b/haversine_02/src/processor/proc_argparser.cpp @@ -0,0 +1,44 @@ +#include "processor/proc_argparser.h" +#include "aliases.h" +#include + +INTERNAL error_t argp_parser(i32 key, char *arg, argp_state *state); + +INTERNAL argp parser = {}; + +ProcessorArgs parse_args(i32 argc, char *argv[]) { + ProcessorArgs args = {}; + + parser.options = {}; + parser.parser = argp_parser; + parser.args_doc = "JSON_FILEPATH"; + + argp_parse(&parser, argc, argv, 0, 0, &args); + + return args; +} + +error_t argp_parser(i32 key, char *arg, argp_state *state) { + ProcessorArgs *args = (ProcessorArgs *)state->input; + + switch (key) { + case ARGP_KEY_ARG: + if (state->arg_num >= 1) { + argp_usage(state); + } + + args->filepath = arg; + + break; + case ARGP_KEY_END: + if (state->arg_num < 1) { + argp_usage(state); + } + + break; + default: + return ARGP_ERR_UNKNOWN; + } + + return 0; +}