# Calculating variable distances

I'm attempting to write an algorithm that calculates the distance between vertebrae. The text parser already works perfectly in picking out vertebral references (cervical 6, c-6, c6, c six, cervical six).

It currently references a linear string array, and matches Vertebrae to their index, and then subtracts `Min` from `Max`. The solves 95% of cases.

The issue comes in from two scenarios:

• Distance is not necessarily linear. L5 to Pelvis and L5 to Sacrum are both considered one level.
• Genetic anomalies can produce extra vertebrae. Most people have 12 Thoracic vertebrae, some have up to 14.

If I only needed to solve one or the other, it wouldn't an issue. I'm now looking at a complicated mess of workarounds to make this work, and I'm certain there is a simpler answer.

``````private static int CalculateLevelNumber(IEnumerable<string> levels)
{
List<int> levelindexes = new List<int>();
List<string> spinemap = new List<string> { "occiput", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "t10", "t11", "t12", "l1", "l2", "l3", "l4", "l5", "s1", "s2" };

foreach(string level in levels)
{
}

return levelindexes.Max() - levelindexes.Min();
}
``````

Here is what I mean by ugly workaround:

``````private static int CalculateLevelNumber(IEnumerable<string> levels)
{
List<int> levelindexes = new List<int>();
List<string> spinemap = new List<string> { "occiput", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "t10", "t11", "t12", "l1", "l2", "l3", "l4", "l5", "s1", "s2" };

if(levels.Contains("t15"))
{
spinemap.InsertRange(spinemap.IndexOf("t12"), new List<string> { "t13", "t14", "t15" });
}
else if(levels.Contains("t14"))
{
spinemap.InsertRange(spinemap.IndexOf("t12"), new List<string> { "t13", "t14" });
}
else if (levels.Contains("t13"))
{
spinemap.InsertRange(spinemap.IndexOf("t12"), new List<string> { "t13" });
}

foreach (string level in levels)
{
if(level == "pelvis" || level == "ilium")
else
}

return levelindexes.Max() - levelindexes.Min();
}
``````
• How would a doctor or domain expert address and resolve those issues? When that is known then it can easily be solved in programming. Otherwise, you'd use machine learning, which is most likely overkill for this. Commented Apr 14, 2016 at 16:07
• Good question @ErikEidt. They would just understand that the references change distance with additional vertebrae and reset the measure, or understand that the positional distance of pelvis, ilium and sacram 1 are analgous. Commented Apr 14, 2016 at 16:11
• @ErikEidt This is what I mean by ugly workaround. I can literally add how a doctor would think about the situation, but it's not pretty. Commented Apr 14, 2016 at 16:20

Alright, for starters, I guess I would precompute several `spinemap` lists in advance, and keep them immutable during execution of the calculations, instead just picking the right one to use for each case.

To finish up, I'd use array of `int` instead of array of `string` for the `spinemap`s. I'd transform the `level`s from `string` form to an `enum`, and use that `enum` to index into `spinemap`. The `spinemap` arrays would store the `int` position directly at each `enum level`'s index.

So, we'd have four(?) `spinemap`s as array of `int` position indexable by `enum level`, precomputed and unmodified during calculation.

There are any number of other possibilities, including defining a class to group names together with positions, which might take a bit more searching, but perhaps be more maintainable. We could also start with a set of easly maintained and readable definitions, and then build the precomputed data structures needed from that so we don't have to do so much searching during calculation.