day 16 part 2
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Ben Harris 2020-12-16 14:58:07 -05:00
parent deb765886d
commit 18311ecbac
3 changed files with 50 additions and 6 deletions

View File

@ -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

View File

@ -9,8 +9,8 @@ namespace aoc2020
/// </summary>
public sealed class Day16 : Day
{
private List<List<int>> _tickets;
private Dictionary<string, List<Range>> _rules;
private readonly Dictionary<string, List<Range>> _rules;
private readonly List<List<int>> _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])}";
}
}
}
}

View File

@ -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;
}
}
}