Advertisement
R7900

DaySixteen

Mar 31st, 2021
40
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.93 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using static AdventOfCode2020.Common;
  5.  
  6. namespace AdventOfCode2020.Days
  7. {
  8. public class DaySixteen
  9. {
  10. private readonly List<string> _input;
  11. private readonly List<long> _myTicket;
  12. private readonly List< List<int>> _nearbyTickets;
  13. private readonly Dictionary<string, (int Min, int Max)[]> _criteria;
  14.  
  15. public DaySixteen()
  16. {
  17. _criteria = new Dictionary<string, (int Min, int Max)[]>();
  18. _input = ReadRaw("daysixteen.txt").Split("\n\n").ToList();
  19. _input[0].Split("\n").ToList().ForEach(x => ProcessCriteria(x));
  20. _myTicket = _input[1].Split("\n")[1].Split(",").Select(long.Parse).ToList();
  21. _nearbyTickets = _input[2].Split("\n")[1..].Select(x => x.Split(",")).Select(x => x.Select(y => int.Parse(y)).ToList()).ToList();
  22. }
  23.  
  24. public void Process()
  25. {
  26. Console.WriteLine($"Part 1: {GetInvalid()}");
  27. Console.WriteLine($"Part 2: {GetDepartureSum()}");
  28. }
  29.  
  30. private void ProcessCriteria(string line)
  31. {
  32. var delimited = line.Split(" ");
  33. var key = string.Join(" ", delimited[..^3]);
  34. var value = new (int, int)[] { ProcessLimits(delimited[^1]), ProcessLimits(delimited[^3]) };
  35. _criteria.Add(key, value);
  36. }
  37.  
  38. private bool IsValid(List<(int Min, int Max)> allCriterion, List<int> ticket)
  39. {
  40. return ticket.All(x => allCriterion.ToList().Any(y => x >= y.Min && x <= y.Max));
  41. }
  42.  
  43. private long GetDepartureSum()
  44. {
  45. var usedCriteria = new HashSet<string>();
  46. var result = new List<int>();
  47.  
  48. var allCriterion = _criteria.SelectMany(x => x.Value).ToList();
  49. var validTickets = _nearbyTickets.Where(x => IsValid(allCriterion, x)).ToList();
  50. var transposedTickets = Transpose(validTickets);
  51.  
  52. var matchingFields = transposedTickets.Select((a, i) => (Fields: _criteria.Keys.Where(x => AllNumbersMatch(x, a)), Index: i)).OrderBy(x => x.Fields.Count()).ToList();
  53.  
  54. foreach(var _ in transposedTickets)
  55. {
  56. var firstMatch = matchingFields.First();
  57.  
  58. if (firstMatch.Fields.First().Contains("depart"))
  59. {
  60. result.Add(firstMatch.Index);
  61. }
  62.  
  63. usedCriteria.Add(firstMatch.Fields.First());
  64. matchingFields = matchingFields.Select(x => (Fields: x.Fields.Where(y => !usedCriteria.Contains(y)), x.Index)).Where(x => x.Fields.Count() > 0).OrderBy(x => x.Fields.Count()).ToList();
  65. }
  66.  
  67. return result.Select(x => _myTicket[x]).Aggregate((x,y) => x * y);
  68. }
  69.  
  70. private bool AllNumbersMatch(string key, List<int> tickets) => tickets.All(x => _criteria[key].Any(y => x >= y.Min && x <= y.Max));
  71.  
  72. private List<List<int>> Transpose(List<List<int>> input)
  73. {
  74. var result = new List<List<int>>();
  75. for (int i = 0; i < input[0].Count(); i++)
  76. {
  77. result.Add(input.Select(x => x[i]).ToList());
  78. }
  79. return result;
  80. }
  81.  
  82. private int GetInvalid()
  83. {
  84. var result = 0;
  85. var criteriaFlat = _criteria.SelectMany(x => x.Value);
  86. foreach (var ticket in _nearbyTickets)
  87. {
  88. foreach (var value in ticket)
  89. {
  90. if (!criteriaFlat.Any(x => value >= x.Min && value <= x.Max))
  91. result += value;
  92. }
  93.  
  94. }
  95. return result;
  96. }
  97.  
  98. private (int Min, int Max) ProcessLimits(string input)
  99. {
  100. var delimited = input.Split("-");
  101. return (int.Parse(delimited[0]), int.Parse(delimited[1]));
  102. }
  103. }
  104. }
  105.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement