summaryrefslogtreecommitdiff
path: root/src/haversine_processor
diff options
context:
space:
mode:
authorRaymaekers Luca <luca@spacehb.net>2025-11-14 15:17:18 +0100
committerRaymaekers Luca <luca@spacehb.net>2025-11-14 15:17:18 +0100
commitd8beb0293bde2b758897df2f70118115d6620539 (patch)
treee7cea252e63bce2ffc0e456909ec2692d7a0d094 /src/haversine_processor
parentf0208e736ee473e80c8bc0d282ff9d9947374f15 (diff)
checkpointmain
Diffstat (limited to 'src/haversine_processor')
-rwxr-xr-xsrc/haversine_processor/build.sh2
-rw-r--r--src/haversine_processor/haversine_processor.cpp212
2 files changed, 149 insertions, 65 deletions
diff --git a/src/haversine_processor/build.sh b/src/haversine_processor/build.sh
index 2cd5f25..73991e9 100755
--- a/src/haversine_processor/build.sh
+++ b/src/haversine_processor/build.sh
@@ -8,7 +8,7 @@ cd "$ScriptDirectory"
#- Globals
CommonCompilerFlags="-DOS_LINUX=1 -fsanitize-trap -nostdinc++"
CommonWarningFlags="-Wall -Wextra -Wconversion -Wdouble-promotion -Wno-sign-conversion -Wno-sign-compare -Wno-double-promotion -Wno-unused-but-set-variable -Wno-unused-variable -Wno-write-strings -Wno-pointer-arith -Wno-unused-parameter -Wno-unused-function"
-LinkerFlags=""
+LinkerFlags="-lm"
DebugFlags="-g -ggdb -g3"
ReleaseFlags="-O3"
diff --git a/src/haversine_processor/haversine_processor.cpp b/src/haversine_processor/haversine_processor.cpp
index 8571627..ffb3a28 100644
--- a/src/haversine_processor/haversine_processor.cpp
+++ b/src/haversine_processor/haversine_processor.cpp
@@ -2,6 +2,7 @@
#define STB_SPRINTF_IMPLEMENTATION
#include "libs/stb_sprintf.h"
+#include <math.h>
#include <errno.h>
#include <unistd.h>
@@ -21,6 +22,46 @@ struct str8
global_variable u8 LogBuffer[Kilobytes(64)];
//~ Functions
+
+//- Haversine
+static f64 Square(f64 A)
+{
+ f64 Result = (A*A);
+ return Result;
+}
+
+static f64 RadiansFromDegrees(f64 Degrees)
+{
+ f64 Result = 0.01745329251994329577 * Degrees;
+ return Result;
+}
+
+// NOTE(casey): EarthRadius is generally expected to be 6372.8
+static f64 ReferenceHaversine(f64 X0, f64 Y0, f64 X1, f64 Y1, f64 EarthRadius)
+{
+ /* NOTE(casey): This is not meant to be a "good" way to calculate the Haversine distance.
+ Instead, it attempts to follow, as closely as possible, the formula used in the real-world
+ question on which these homework exercises are loosely based.
+ */
+
+ f64 lat1 = Y0;
+ f64 lat2 = Y1;
+ f64 lon1 = X0;
+ f64 lon2 = X1;
+
+ f64 dLat = RadiansFromDegrees(lat2 - lat1);
+ f64 dLon = RadiansFromDegrees(lon2 - lon1);
+ lat1 = RadiansFromDegrees(lat1);
+ lat2 = RadiansFromDegrees(lat2);
+
+ f64 a = Square(sin(dLat/2.0)) + cos(lat1)*cos(lat2)*Square(sin(dLon/2));
+ f64 c = 2.0*asin(sqrt(a));
+
+ f64 Result = EarthRadius * c;
+
+ return Result;
+}
+
//- Debug utilities
void AssertErrnoNotEquals(smm Result, smm ErrorValue)
{
@@ -51,6 +92,24 @@ void LogFormat(char *Format, ...)
AssertErrnoEquals(BytesWritten, Length);
}
+
+str8 ReadEntireFileIntoMemory(char *FileName)
+{
+ str8 Result = {};
+
+ int File = open(FileName, O_RDONLY);
+
+ struct stat StatBuffer = {};
+ int Error = fstat(File, &StatBuffer);
+ AssertErrnoNotEquals(Error, -1);
+
+ Result.Size = StatBuffer.st_size;
+ Result.Data = (u8 *)mmap(0, Result.Size, PROT_READ, MAP_PRIVATE, File, 0);
+ AssertErrnoNotEquals((smm)Result.Data, (smm)MAP_FAILED);
+
+ return Result;
+}
+
//- Parsing utilities
b32 IsWhiteSpace(u8 Char)
@@ -169,18 +228,34 @@ void ParseFloatNumber(umm Size, u8 *In, umm *Start, f64 *Value)
*Start = At;
}
+void ConsumeHaversineJsonNumber(umm Size, u8 *In, umm *Start, str8 Name, f64 *Value, b32 NumberLeft)
+{
+ umm At = *Start;
+
+ ConsumePastJsonString(Size, In, &At, Name);
+ ConsumeWhiteSpacePastChar(Size, In, &At, ':');
+ while(At < Size && IsWhiteSpace(In[At])) At += 1;
+ ParseFloatNumber(Size, In, &At, Value);
+
+ if(NumberLeft)
+ {
+ ConsumeWhiteSpacePastChar(Size, In, &At, ',');
+ }
+
+ *Start = At;
+}
+
//-
int main(int ArgsCount, char *Args[])
{
-
- char *JsonFileName = 0;
- char *AnswersFileName = 0;
-
+ str8 Answers = {};
+ umm AnswerIndex = 0;
+ str8 Json = {};
if(ArgsCount >= 2)
{
- JsonFileName = Args[1];
+ Json = ReadEntireFileIntoMemory(Args[1]);
}
else
{
@@ -189,75 +264,84 @@ int main(int ArgsCount, char *Args[])
if(ArgsCount >= 3)
{
- AnswersFileName = Args[1];
+ Answers = ReadEntireFileIntoMemory(Args[2]);
}
- if(JsonFileName)
+ if(Json.Size)
{
- int JsonFile = open(JsonFileName, O_RDONLY);
- if(JsonFile != -1)
- {
- struct stat StatBuffer = {};
- int Result = fstat(JsonFile, &StatBuffer);
- AssertErrnoNotEquals(Result, -1);
+ f64 X0 = 0.0;
+ f64 X1 = 0.0;
+ f64 Y0 = 0.0;
+ f64 Y1 = 0.0;
+
+ // Json Parsing
+ u8 *In = Json.Data;
+
+ umm At = 0;
+ ConsumeWhiteSpacePastChar(Json.Size, In, &At, '{');
+ ConsumePastJsonString(Json.Size, In, &At, S8Lit("pairs"));
+ ConsumeWhiteSpacePastChar(Json.Size, In, &At, ':');
+ ConsumeWhiteSpacePastChar(Json.Size, In, &At, '[');
+
+ f64 TotalSum = 0;
+ umm PairCount = 0;
+ b32 PairsRemaining = true;
+
+ // One pair
+ while(PairsRemaining && (At < Json.Size))
+ {
+ ConsumeWhiteSpacePastChar(Json.Size, In, &At, '{');
- umm FileSize = StatBuffer.st_size;
- u8 *JsonMemory = (u8 *)mmap(0, FileSize, PROT_READ, MAP_PRIVATE, JsonFile, 0);
- AssertErrnoNotEquals((smm)JsonMemory, (smm)MAP_FAILED);
+ ConsumeHaversineJsonNumber(Json.Size, In, &At, S8Lit("x0"), &X0, true);
+ ConsumeHaversineJsonNumber(Json.Size, In, &At, S8Lit("y0"), &Y0, true);
+ ConsumeHaversineJsonNumber(Json.Size, In, &At, S8Lit("x1"), &X1, true);
+ ConsumeHaversineJsonNumber(Json.Size, In, &At, S8Lit("y1"), &Y1, false);
- f64 X0 = 0.0;
- f64 X1 = 0.0;
- f64 Y0 = 0.0;
- f64 Y1 = 0.0;
+ f64 Sum = ReferenceHaversine(X0, Y0, X1, Y1, 6372.8);
+ TotalSum += Sum;
- // Json Parsing
- u8 *In = JsonMemory;
+ if(Answers.Size)
+ {
+ // NOTE(luca): What to do here?
+ //f64 AnswerSum = ((f64 *)Answers.Data)[AnswerIndex];
+
+ AnswerIndex += 1;
+ }
- umm At = 0;
- ConsumeWhiteSpacePastChar(FileSize, In, &At, '{');
- ConsumePastJsonString(FileSize, In, &At, S8Lit("pairs"));
- ConsumeWhiteSpacePastChar(FileSize, In, &At, ':');
- ConsumeWhiteSpacePastChar(FileSize, In, &At, '[');
+ ConsumeWhiteSpacePastChar(Json.Size, In, &At, '}');
- b32 PairsRemaining = true;
- // One pair
- while(PairsRemaining && (At < FileSize))
- {
- ConsumeWhiteSpacePastChar(FileSize, In, &At, '{');
-
- ConsumePastJsonString(FileSize, In, &At, S8Lit("x0"));
- ConsumeWhiteSpacePastChar(FileSize, In, &At, ':');
- while(At < FileSize && IsWhiteSpace(In[At])) At += 1;
- ParseFloatNumber(FileSize, In, &At, &X0);
- ConsumeWhiteSpacePastChar(FileSize, In, &At, ',');
-
- ConsumePastJsonString(FileSize, In, &At, S8Lit("y0"));
- ConsumeWhiteSpacePastChar(FileSize, In, &At, ':');
- while(At < FileSize && IsWhiteSpace(In[At])) At += 1;
- ParseFloatNumber(FileSize, In, &At, &Y0);
- ConsumeWhiteSpacePastChar(FileSize, In, &At, ',');
-
- ConsumePastJsonString(FileSize, In, &At, S8Lit("x1"));
- ConsumeWhiteSpacePastChar(FileSize, In, &At, ':');
- while(At < FileSize && IsWhiteSpace(In[At])) At += 1;
- ParseFloatNumber(FileSize, In, &At, &X1);
- ConsumeWhiteSpacePastChar(FileSize, In, &At, ',');
-
- ConsumePastJsonString(FileSize, In, &At, S8Lit("y1"));
- ConsumeWhiteSpacePastChar(FileSize, In, &At, ':');
- while(At < FileSize && IsWhiteSpace(In[At])) At += 1;
- ParseFloatNumber(FileSize, In, &At, &Y1);
-
- LogFormat("X0: %.15f, Y0: %.15f, X1: %.15f, Y1: %.15f\n", X0, Y0, X1, Y1);
-
- ConsumeWhiteSpacePastChar(FileSize, In, &At, '}');
-
- while(At < FileSize && IsWhiteSpace(In[At])) At += 1;
- PairsRemaining = (In[At] == '{' || At >= FileSize);
+ if(At < Json.Size && In[At] == ',')
+ {
+ At += 1;
}
- ConsumeWhiteSpacePastChar(FileSize, In, &At, ']');
- ConsumeWhiteSpacePastChar(FileSize, In, &At, '}');
+ while(At < Json.Size && IsWhiteSpace(In[At])) At += 1;
+ PairsRemaining = (In[At] == '{' || At >= Json.Size);
+
+ PairCount += 1;
+ }
+
+ ConsumeWhiteSpacePastChar(Json.Size, In, &At, ']');
+ ConsumeWhiteSpacePastChar(Json.Size, In, &At, '}');
+
+ f64 AverageSum = TotalSum / (f64)PairCount;
+ LogFormat("Input size: %lu\n"
+ "Pair count: %lu\n"
+ "Haversine sum: %.16f\n"
+ , Json.Size, PairCount, AverageSum);
+
+ if(Answers.Size)
+ {
+ f64 AnswerAverageSum = ((f64 *)Answers.Data)[AnswerIndex];
+ AnswerIndex += 1;
+
+ Assert((AnswerIndex * sizeof(f64)) == Answers.Size);
+
+ LogFormat("\nValidation\n"
+ "Reference sum: %.16f\n"
+ "Difference: %.16f\n"
+ , AnswerAverageSum, AnswerAverageSum - AverageSum);
+
}