using System.Collections.Generic;
public int PersonKey { get; set; }
public int EventKey { get; set; }
public string ActionCode { get; set; }
public DateTime ActionDate { get; set; }
public static void Main()
var testData = new List<TestData>
new TestData { PersonKey = 1, EventKey = 1, ActionCode = "code1", ActionDate = new DateTime(2023, 1, 1, 10, 0, 0) },
new TestData { PersonKey = 1, EventKey = 2, ActionCode = "code3", ActionDate = new DateTime(2023, 1, 1, 10, 30, 0) },
new TestData { PersonKey = 1, EventKey = 3, ActionCode = "code4", ActionDate = new DateTime(2023, 1, 1, 11, 0, 0) },
new TestData { PersonKey = 1, EventKey = 4, ActionCode = "code1", ActionDate = new DateTime(2023, 1, 1, 12, 0, 0) },
new TestData { PersonKey = 1, EventKey = 5, ActionCode = "code3", ActionDate = new DateTime(2023, 1, 1, 12, 30, 0) },
new TestData { PersonKey = 1, EventKey = 6, ActionCode = "code4", ActionDate = new DateTime(2023, 1, 1, 13, 0, 0) },
new TestData { PersonKey = 1, EventKey = 7, ActionCode = "code2", ActionDate = new DateTime(2023, 1, 1, 14, 0, 0) },
new TestData { PersonKey = 1, EventKey = 8, ActionCode = "code1", ActionDate = new DateTime(2023, 1, 1, 15, 0, 0) },
new TestData { PersonKey = 1, EventKey = 9, ActionCode = "code2", ActionDate = new DateTime(2023, 1, 1, 15, 30, 0) },
new TestData { PersonKey = 1, EventKey = 10, ActionCode = "code5", ActionDate = new DateTime(2023, 1, 1, 16, 0, 0) },
new TestData { PersonKey = 1, EventKey = 11, ActionCode = "code2", ActionDate = new DateTime(2023, 1, 1, 16, 30, 0) }
int count = CalculateEventCombinationsCount(testData);
Console.WriteLine($"Total count: {count}");
public static int CalculateEventCombinationsCount(List<TestData> list)
var section2 = new { name = "Section 2", codes = new List<string>(new string[] { "code1", "code3" }) };
for (int year = 2010; year < 2023; year++)
var people_in_year = list.Where(x => x.ActionDate.Year == year)
.GroupBy(x => x.PersonKey);
foreach (var personGroup in people_in_year)
var events = personGroup.ToList();
for (int i = 0; i < events.Count - 1; i++)
var currentEvent = events[i];
var remainingEvents = events.Skip(i + 1);
var found = remainingEvents.Where(x =>
(x.ActionDate - currentEvent.ActionDate).TotalMinutes >= 0 && (x.ActionDate - currentEvent.ActionDate).TotalMinutes < 60
bool allCodesFound = section2.codes.All(code => found.Any(x => x.ActionCode == code));