day 16 part 2
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
deb765886d
commit
18311ecbac
|
@ -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
|
||||
|
|
|
@ -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])}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue