public void TestEnumerateOccurrences_AllTrios(int individualCount, int targetGroupingCount)
        {
            var individuals = Enumerable
                              .Range(0, individualCount)
                              .Select(_ => Guid.NewGuid().ToString())
                              .ToList();
            var generator = new AllCombinationOccurrenceGenerator
            {
                Individuals         = individuals,
                TargetGroupingCount = targetGroupingCount
            };

            var occurrences = generator.EnumerateOccurrences().ToList();

            foreach (var individual in individuals)
            {
                foreach (var partnerA in individuals)
                {
                    if (individual != partnerA)
                    {
                        foreach (var partnerB in individuals)
                        {
                            if (individual != partnerB && partnerA != partnerB)
                            {
                                Assert.That(occurrences.Any(o => o.Groupings.Any(g =>
                                                                                 g.Contains(individual) && g.Contains(partnerA) && g.Contains(partnerB))),
                                            $"At least one occurrence should group {individual} with {partnerA} and {partnerB}");
                            }
                        }
                    }
                }
            }

            Assert.That(occurrences, Has.All.Property(nameof(Occurrence.Groupings)).All.Unique, "No one should ever meet with themself");
        }
        public void TestEnumerateOccurrences_GroupingSize(int individualCount, int targetGroupingCount)
        {
            var individuals = Enumerable
                              .Range(0, individualCount)
                              .Select(_ => Guid.NewGuid().ToString())
                              .ToList();
            var generator = new AllCombinationOccurrenceGenerator
            {
                Individuals         = individuals,
                TargetGroupingCount = targetGroupingCount
            };

            var occurrences = generator.EnumerateOccurrences().ToList();

            if (individualCount % targetGroupingCount == 0)
            {
                foreach (var occurrence in occurrences)
                {
                    Assert.That(occurrence.Groupings, Has.All.Count.EqualTo(targetGroupingCount));
                }
            }
            else
            {
                foreach (var occurrence in occurrences)
                {
                    Assert.Multiple(() =>
                    {
                        Assert.That(occurrence.Groupings.Take(occurrence.Groupings.Count() - 1), Has.All.Count.EqualTo(targetGroupingCount));
                        Assert.That(occurrence.Groupings.Last(), Has.Count.EqualTo(targetGroupingCount + individualCount % targetGroupingCount), "The last grouping should hold the remainder");
                    });
                }
            }
        }
예제 #3
0
        public void TestIntegration()
        {
            const string a = "A";
            const string b = "B";
            const string c = "C";
            const string d = "D";

            var history = new[] {
                new Occurrence(DateTime.UtcNow.AddDays(-1), new[] {
                    new[] { a, b },
                    new[] { c, d }
                }),
                new Occurrence(DateTime.UtcNow.AddDays(-2), new[] {
                    new[] { a, c },
                    new[] { b, d }
                })
            };

            var scorer = new HistoryBasedScorer(history);

            var generator = new AllCombinationOccurrenceGenerator
            {
                Individuals         = new[] { a, b, c, d },
                TargetGroupingCount = 2
            };

            var picker = new OccurrencePicker(generator, scorer);

            var occurrence = picker.PickBestOccurrence();

            Assert.That(occurrence.Groupings.ToList(), Has.Count.EqualTo(2));
            Assert.That(occurrence.Groupings.Any(x => x.Contains(a) && x.Contains(d)), $"{a} should meet with {d}");
            Assert.That(occurrence.Groupings.Any(x => x.Contains(b) && x.Contains(c)), $"{b} should meet with {c}");
        }
        public void TestEnumerateOccurrences_Date()
        {
            var expectedDate = DateTimeOffset.UtcNow;
            var individuals  = Enumerable
                               .Range(0, 5)
                               .Select(_ => Guid.NewGuid().ToString())
                               .ToList();
            var generator = new AllCombinationOccurrenceGenerator
            {
                Individuals         = individuals,
                TargetGroupingCount = 2,
                Date = expectedDate
            };

            var occurrences = generator.EnumerateOccurrences().ToList();

            Assert.That(occurrences, Has.All.Property(nameof(Occurrence.Date)).EqualTo(expectedDate));
        }
        public void TestEnumerateOccurrences_Exemptions([Values(10, 13, 20, 21)] int individualCount)
        {
            var individuals = Enumerable
                              .Range(0, individualCount)
                              .Select(_ => Guid.NewGuid().ToString())
                              .ToList();

            // these exemptions are just arbitrary
            var exemptA1 = individuals[1];
            var exemptA2 = individuals[4];
            var exemptA3 = individuals[2];
            var exemptB1 = individuals[6];
            var exemptB2 = individuals[9];

            var generator = new AllCombinationOccurrenceGenerator
            {
                Individuals         = individuals,
                TargetGroupingCount = 2,
                ExemptMeetings      = new[]
                {
                    new HashSet <string> {
                        exemptA1, exemptA2, exemptA3
                    },
                    new HashSet <string> {
                        exemptB1, exemptB2
                    }
                }
            };

            var occurrences = generator.EnumerateOccurrences().ToList();

            Assert.That(!occurrences.Any(o => o.Groupings.Where(g => g.Count() == 2).Any(g =>
                                                                                         g.Contains(exemptA1) && g.Contains(exemptA2))), $"{exemptA1} should not meet with {exemptA2}");
            Assert.That(!occurrences.Any(o => o.Groupings.Where(g => g.Count() == 2).Any(g =>
                                                                                         g.Contains(exemptA1) && g.Contains(exemptA3))), $"{exemptA1} should not meet with {exemptA3}");
            Assert.That(!occurrences.Any(o => o.Groupings.Where(g => g.Count() == 2).Any(g =>
                                                                                         g.Contains(exemptA2) && g.Contains(exemptA3))), $"{exemptA2} should not meet with {exemptA3}");
            Assert.That(!occurrences.Any(o => o.Groupings.Where(g => g.Count() == 2).Any(g =>
                                                                                         g.Contains(exemptB1) && g.Contains(exemptB2))), $"{exemptB1} should not meet with {exemptB2}");
        }
예제 #6
0
        static void Main()
        {
            var history     = ReadHistory();
            var roommates   = ReadRoommates();
            var individuals = ReadIndividuals();

            var occurrenceGenerator = new AllCombinationOccurrenceGenerator
            {
                Individuals    = new ReadOnlyCollection <string>(individuals),
                ExemptMeetings = roommates
            };

            var scorer = new HistoryBasedScorer(history);

            var splitter = new OccurrencePicker(occurrenceGenerator, scorer);

            var occurrence = splitter.PickBestOccurrence();

            WriteOccurrenceToConsole(occurrence);

            history.Add(occurrence);
            WriteHistory(history);
        }