'Version control for medications

I need some help with an algorithm.

I'm tracking medications taken by a patient. I'll end up with entries like these:

1/1/22 DrugA 5mg Started DrugA
1/1/22 DrugB 5mg Started DrugB
1/3/22 DrugA 10mg Increased dosage of DrugA
1/5/22 DrugB 0mg Stopped taking DrugB

And from that, I need to be able to produce the following:

1/1/22 DrugA 5mg; DrugB 5mg
1/2/22 DrugA 5mg; DrugB 5mg
1/3/22 DrugA 10mg; DrugB 5mg
1/4/22 DrugA 10mg; DrugB 5mg
1/5/22 DrugA 10mg
1/6/22 DrugA 10mg

In other words, from entries that describe changes to drug dosage, I need to be able to show exactly what drugs and dosages were taken on any given day.

It's a little like source control versioning in that you track changes but can reproduce the whole for any point in time.

To be clear, I would store this information in a database or something. It would be simpler just to store it in memory.

Can anyone suggest an algorithm that could handle this case? I would need to implement it in C#.



Solution 1:[1]

You've given us just the plain text input, so I'm going to make up a class to represent the data.

public class Prescription
{
    public DateTime Date { get; set; }
    public long PatientNumber { get; set; }
    public string DrugName { get; set; }
    public decimal DrugAmount { get; set; }
    public string Notes { get; set; }
}

Let's say you have a list of these records, for one specific patient, and you want to produce the output text. To model that, we need some more classes:

public class Administration
{
    public DateTime Date { get; set; }
    public List<Dosage> Dosages { get; set; }
}

public class Dosage
{
    public string DrugName { get; set; }
    public decimal DrugAmount { get; set; }
}

Your algorithm might look like this:

var prescriptions = GetPrescriptions(); // Load the list of prescriptions from the database
var administrations = new List<Administration>();
if (prescriptions.Count == 0)
    return administrations;

var start = prescriptions[0].Date;
var end = prescriptions[prescriptions.Count - 1].Date;

var date = start;
var dosages = new Dictionary<string, decimal>();
var index = 0;
while (date <= end)
{
    // Iterate through all the prescriptions that happened on this day, and update the dosage amounts
    while (index < prescription.Count)
    {
        var prescription = prescriptions[index];
        if (prescription.Date != date)
            break;

        if (prescription.DrugAmount == 0)
            dosages.Remove(prescription.DrugName);
        else
            dosages[prescription.DrugName] = prescription.DrugAmount;

        index++;
    }

    administrations.Add(new Administration
    {
        Date = date,
        Dosages = dosages.Select(pair => new Dosage
        {
            DrugName = pair.Key,
            DrugAmount = pair.Value,
        }).ToList(), 
    });

    date += TimeSpan.FromDays(1);
}

return administrations;

Solution 2:[2]

For further reference, on a high level view the accepted solution can be seen as the CQRS pattern in combination with the event sourcing pattern. There is some C# code examples in the links as well.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Andrew Williamson
Solution 2 user2505961