From 18311ecbac20ff077bbed95dc36660d9ffd5b997 Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Wed, 16 Dec 2020 14:58:07 -0500 Subject: [PATCH] day 16 part 2 --- aoc2020.test/DayTests.cs | 2 +- aoc2020/Day16.cs | 48 +++++++++++++++++++++++++++++++++++----- aoc2020/Extensions.cs | 6 +++++ 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/aoc2020.test/DayTests.cs b/aoc2020.test/DayTests.cs index 6d2fce6..56e32ad 100644 --- a/aoc2020.test/DayTests.cs +++ b/aoc2020.test/DayTests.cs @@ -23,7 +23,7 @@ namespace aoc2020.test [DataRow(typeof(Day13), "171", "539746751134958")] [DataRow(typeof(Day14), "17481577045893", "4160009892257")] [DataRow(typeof(Day15), "257", "8546398")] - [DataRow(typeof(Day16), "19093", "")] + [DataRow(typeof(Day16), "19093", "5311123569883")] public void CheckAllDays(Type dayType, string part1, string part2) { // create day instance diff --git a/aoc2020/Day16.cs b/aoc2020/Day16.cs index c9c2b70..12230a2 100644 --- a/aoc2020/Day16.cs +++ b/aoc2020/Day16.cs @@ -9,8 +9,8 @@ namespace aoc2020 /// public sealed class Day16 : Day { - private List> _tickets; - private Dictionary> _rules; + private readonly Dictionary> _rules; + private readonly List> _tickets; public Day16() : base(16) { @@ -41,13 +41,51 @@ namespace aoc2020 public override string Part1() { + var allValues = _tickets.Skip(1).SelectMany(t => t); + var allRules = _rules.Values.SelectMany(r => r); return - $"{_tickets.Skip(1).SelectMany(t => t).Where(t => !_rules.Values.SelectMany(r => r).Any(r => t >= r.Start.Value && t <= r.End.Value)).Sum()}"; + $"{allValues.Where(t => !allRules.Any(r => r.Contains(t))).Sum()}"; } public override string Part2() { - return ""; + var ticketFields = _tickets + // valid tickets + .Where(ticket => ticket + .All(t => _rules.Values + .SelectMany(r => r) + .Any(r => r.Contains(t)))) + // group by index + .SelectMany(inner => inner.Select((item, index) => new {item, index})) + .GroupBy(i => i.index, i => i.item) + .Select(g => g.ToList()) + .Select((val, i) => new {Value = val, Index = i}) + .ToList(); + + var matchedRules = _rules + // find matching rules and indices + .SelectMany(x => ticketFields + .Where(y => y.Value.All(z => x.Value.Any(r => r.Contains(z)))) + .Select(y => (x.Key, y.Index)) + .ToList()) + .ToList(); + + matchedRules.Sort((a, b) => + matchedRules.Count(x => x.Key == a.Key) - matchedRules.Count(x => x.Key == b.Key)); + + while (matchedRules.Any(x => matchedRules.Count(y => y.Key == x.Key) > 1)) + foreach (var (key, index) in matchedRules.Where(y => + matchedRules.Count(z => z.Key == y.Key) == 1 && + matchedRules.Count(z => z.Index == y.Index) > 1)) + // filter matches by index + matchedRules = matchedRules + .Where(x => x.Index != index || x.Key == key) + .ToList(); + + var departureFields = matchedRules.Where(r => r.Key.StartsWith("departure")); + + return + $"{departureFields.Aggregate(1L, (l, match) => l * _tickets.First()[match.Index])}"; } } -} +} \ No newline at end of file diff --git a/aoc2020/Extensions.cs b/aoc2020/Extensions.cs index 88c1949..4c75d5e 100644 --- a/aoc2020/Extensions.cs +++ b/aoc2020/Extensions.cs @@ -1,3 +1,4 @@ +using System; using System.Diagnostics; namespace aoc2020 @@ -18,5 +19,10 @@ namespace aoc2020 { return 1_000 * stopwatch.ElapsedTicks / (double) Stopwatch.Frequency; } + + public static bool Contains(this Range range, int i) + { + return i >= range.Start.Value && i <= range.End.Value; + } } } \ No newline at end of file