Equd

AOC 2020 Day 4

Dec 4th, 2020
637
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #load "xunit"
  2. #load "AOC Connector"
  3. #load "AOC 2d Array"
  4.  
  5. void Main()
  6. {  
  7.     RunTests();  // Call RunTests() or press Alt+Shift+T to initiate testing.
  8.  
  9.     //get aoc data
  10.     var aoc = new AdventOfCode(2020, 4);
  11.    
  12.     var passPorts = GetPassPorts(aoc.InputLines);
  13.    
  14.     //solve A
  15.     aoc.SubmitAnswer(SolveA(passPorts), Part.A);
  16.  
  17.     //solve B
  18.     aoc.SubmitAnswer(SolveB(passPorts), Part.B);
  19. }
  20.  
  21. public PassPort[] GetPassPorts(string[] data)
  22. {
  23.     return string.Join("\r\n", data).Replace("\r\n\r\n", "*").Replace("\r\n", " ").Split('*')
  24.         .Select(x => x.Split(' ').Select(y => y.Split(':')).ToDictionary(z => z[0], z => z[1]))
  25.         .Select(x=> new PassPort(x)).ToArray();//.Dump();
  26. }
  27.  
  28.  
  29. public int SolveA(PassPort[] data) => data.Count(x => x.validA);
  30. public int SolveB(PassPort[] data) => data.Count(x => x.validB());
  31.  
  32. public record PassPort(Dictionary<string, string> data)
  33. {
  34.     static HashSet<string> validEyeColors = new HashSet<string>() { "amb", "blu","brn","gry","grn","hzl","oth"};
  35.     public bool validA => data.Count == 8 || (data.Count == 7 && !data.ContainsKey("cid"));
  36.     public bool validB()
  37.     {
  38.         //this.Dump(); 
  39.         if(!validA) return false;
  40.         if(!TestByr(data["byr"])) return false;
  41.         if(!TestIYR(data["iyr"])) return false;
  42.         if(!TestEYR(data["eyr"])) return false;
  43.         if(!TestHGT(data["hgt"])) return false;        
  44.         if(!TestHCL(data["hcl"])) return false;        
  45.         if(!TestECL(data["ecl"])) return false;                    
  46.         if(!TestPID(data["pid"])) return false;        
  47.                    
  48.         return true;   
  49.     }
  50.    
  51.     public static bool TestByr(string s) => int.Parse(s) is >= 1920 and <= 2002 ? true : false;
  52.     public static bool TestIYR(string s) => int.Parse(s) is >= 2010 and <= 2020 ? true : false;
  53.     public static bool TestEYR(string s) => int.Parse(s) is >= 2020 and <= 2030 ? true : false;
  54.     public static bool TestHGT(string len)
  55.     {
  56.         if (!(len.EndsWith("in") || len.EndsWith("cm"))) return false;
  57.             int lenN = int.Parse(len.Substring(0, len.Length - 2));
  58.         if (len.EndsWith("cm") && (lenN is < 150 or > 193)) return false;
  59.         if (len.EndsWith("in") && (lenN is < 59 or > 76)) return false;
  60.         return true;
  61.     }
  62.     public static bool TestHCL(string s) => Regex.Match(s, "^#([[0-9a-f]{6})$").Success;
  63.     public static bool TestECL(string s) => validEyeColors.Contains(s);
  64.     public static bool TestPID(string s) => s.Length == 9 && int.TryParse(s, out int _);
  65. }
  66.  
  67. // You can define other methods, fields, classes and namespaces here
  68.  
  69. #region private::Tests
  70. #region test data
  71. string[] testData = new []
  72. {
  73. "ecl:gry pid:860033327 eyr:2020 hcl:#fffffd",
  74. "byr:1937 iyr:2017 cid:147 hgt:183cm",
  75. "",
  76. "iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884",
  77. "hcl:#cfa07d byr:1929",
  78. "",
  79. "hcl:#ae17e1 iyr:2013",
  80. "eyr:2024",
  81. "ecl:brn pid:760753108 byr:1931",
  82. "hgt:179cm",
  83. "",
  84. "hcl:#cfa07d eyr:2025 pid:166559648",
  85. "iyr:2011 ecl:brn hgt:59in",
  86. };
  87.  
  88. string[] invalidP = new []
  89. {
  90. "eyr:1972 cid:100",
  91. "hcl:#18171d ecl:amb hgt:170 pid:186cm iyr:2018 byr:1926",
  92. "",
  93. "iyr:2019",
  94. "hcl:#602927 eyr:1967 hgt:170cm",
  95. "ecl:grn pid:012533040 byr:1946",
  96. "",
  97. "hcl:dab227 iyr:2012",
  98. "ecl:brn hgt:182cm pid:021572410 eyr:2020 byr:1992 cid:277",
  99. "",
  100. "hgt:59cm ecl:zzz",
  101. "eyr:2038 hcl:74454a iyr:2023",
  102. "pid:3556412378 byr:2007",
  103. };
  104.  
  105. string[] validP = new []
  106. {
  107. "pid:087499704 hgt:74in ecl:grn iyr:2012 eyr:2030 byr:1980",
  108. "hcl:#623a2f",
  109. "",
  110. "eyr:2029 ecl:blu cid:129 byr:1989",
  111. "iyr:2014 pid:896056539 hcl:#a97842 hgt:165cm",
  112. "",
  113. "hcl:#888785",
  114. "hgt:164cm byr:2001 iyr:2015 cid:88",
  115. "pid:545766238 ecl:hzl",
  116. "eyr:2022",
  117. "",
  118. "iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719",
  119. };
  120. #endregion
  121. //tests
  122. [Fact] void TestA() => Assert.Equal(2, SolveA(GetPassPorts(testData)));
  123. [Fact] void TestValid() => Assert.Equal(4, SolveB(GetPassPorts(validP)));
  124. [Fact] void TestInvalid() => Assert.Equal(0, SolveB(GetPassPorts(invalidP)));
  125.  
  126. [Theory]
  127. [InlineData(1919, false)]
  128. [InlineData(1920, true)]
  129. [InlineData(2002, true)]
  130. [InlineData(2003, false)]
  131. void TestBYR(int test, bool validResult) => Assert.Equal(PassPort.TestByr(test.ToString()), validResult);
  132.  
  133. [Theory]
  134. [InlineData(2009, false)]
  135. [InlineData(2010, true)]
  136. [InlineData(2020, true)]
  137. [InlineData(2021, false)]
  138. void TestIYR(int test, bool validResult) => Assert.Equal(PassPort.TestIYR(test.ToString()), validResult);
  139.  
  140. [Theory]
  141. [InlineData(2019, false)]
  142. [InlineData(2020, true)]
  143. [InlineData(2030, true)]
  144. [InlineData(2031, false)]
  145. void TestEYR(int test, bool validResult) => Assert.Equal(PassPort.TestEYR(test.ToString()), validResult);
  146.  
  147. [Theory]
  148. [InlineData("149cm", false)]
  149. [InlineData("150cm", true)]
  150. [InlineData("193cm", true)]
  151. [InlineData("194cm", false)]
  152. [InlineData("58in", false)]
  153. [InlineData("59in", true)]
  154. [InlineData("76in", true)]
  155. [InlineData("77in", false)]
  156. [InlineData("77", false)]
  157. void TestHGT(string test, bool validResult) => Assert.Equal(PassPort.TestHGT(test), validResult);
  158.  
  159. [Theory]
  160. [InlineData("#123456", true)]
  161. [InlineData("#7890ab", true)]
  162. [InlineData("#cdef01", true)]
  163. [InlineData("#1234567", false)]
  164. [InlineData("1#123456", false)]
  165. void TestHCL(string test, bool validResult) => Assert.Equal(PassPort.TestHCL(test), validResult);
  166.  
  167. [Theory]
  168. [InlineData("amb", true)]
  169. [InlineData("150cm", false)]
  170. [InlineData("as", false)]
  171. void TestECL(string test, bool validResult) => Assert.Equal(PassPort.TestECL(test), validResult);
  172.  
  173. [Theory]
  174. [InlineData("000000001", true)]
  175. [InlineData("0123456789", false)]
  176. [InlineData("as", false)]
  177. void TestPID(string test, bool validResult) => Assert.Equal(PassPort.TestPID(test), validResult);
  178. #endregion
  179.  
  180.  
RAW Paste Data