Poiuy2010_2011

AoC D4

Dec 4th, 2020 (edited)
714
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Linq;
  3. using System.Text.RegularExpressions;
  4.  
  5. namespace D4_2
  6. {
  7.     class Program
  8.     {
  9.         // enum używany do maski bitowej, chodzi o to, żeby zamienić tekst na liczbę (cid = 0, pid = 1 itd.)
  10.         enum FieldType
  11.         {
  12.             cid, pid, ecl, hcl, hgt, eyr, iyr, byr
  13.         }
  14.  
  15.         static void Main()
  16.         {
  17.             var lines = System.IO.File.ReadAllLines(@"../../../input"); // wczytywanie pliki do tablicy stringów
  18.  
  19.             int validPassports = 0; // tu będziemy dodawać gdy znajdziemy poprawny paszport
  20.             string regex = @"(.+?):(.+?)\s"; // regex do wyszukowania w postaci słowo:słowo[spacja], nawiasy tworzą grupy, dzięki czemu będzie łatwo podzielić znaleziony tekst na kilka stringów
  21.             byte fields = 0b00000000; // pole bitowe gdzie każdy bit oznacza pole w paszporcie (pierwszy bit to byr, drugi to iyr itd.) (0 – nie ma pola, 1 – jest pole), 0b to przedrostek oznaczający liczbę binarną
  22.            
  23.             foreach (var line in lines) // iterujemy po każdej linijce tekstu
  24.             {
  25.                 if (line == "") // jeśli linijka jest pusta to znaczy, że skończył się paszport, weryfikujemy go i przygotowujemy się fo szukania następnego
  26.                 {
  27.                     if ((fields | 1) == 255)
  28.                         validPassports++; // jeśli wszystkie bity są 1 to znaczy, że wszystko jest i paszport jest poprawny, stosujemy najpierw maskę OR (|) z 00000001, żeby ostatni bit zawsze był 1 (bo to cid i go ignorujemy)
  29.                     Console.WriteLine($"{Convert.ToString(fields,2).PadLeft(8,'0')} {validPassports}"); // wypisuje pole bitowe paszportu do konsoli (dla debugowania)
  30.                     fields = 0b00000000; // resetuje pole bitowe, żeby kolejny paszport był "czysty"
  31.                     continue;
  32.                 }
  33.  
  34.                 string preparedLine = line + " ";
  35.                 var matches = Regex.Matches(preparedLine, regex); // szuka w linijce według stworzenego wcześniej regexu, najpierw na koniec do linijki dodajemy spację, bo środowisko ma problemy z wyszukiwaniem nowej linii (spacię jest łatwiej znaleźć)
  36.  
  37.                 for (int i = 0; i < matches.Count; i++)
  38.                 {
  39.                     // tu się dzieje czarna magia, ale tak w skrócie sprawdzamy, które pole znaleźliśmy i weryfikujemy według ustalonych warunków
  40.                     FieldType fieldType = (FieldType) Enum.Parse(typeof(FieldType), matches[i].Groups[1].Value);
  41.                     bool valid = false;
  42.                     string value = matches[i].Groups[2].Value;
  43.  
  44.                     switch (fieldType)
  45.                     {
  46.                         case FieldType.byr:
  47.                             valid = int.Parse(value) >= 1920 && int.Parse(value) <= 2002;
  48.                             break;
  49.                         case FieldType.iyr:
  50.                             valid = int.Parse(value) >= 2010 && int.Parse(value) <= 2020;
  51.                             break;
  52.                         case FieldType.eyr:
  53.                             valid = int.Parse(value) >= 2020 && int.Parse(value) <= 2030;
  54.                             break;
  55.                         case FieldType.hgt:
  56.                             valid = Regex.IsMatch(value, @"\d+cm") ? int.Parse(Regex.Match(value, @"\d+").Value) >= 150 && int.Parse(Regex.Match(value, @"\d+").Value) <= 193 : (Regex.IsMatch(value, @"\d+in") ? int.Parse(Regex.Match(value, @"\d+").Value) >= 59 && int.Parse(Regex.Match(value, @"\d+").Value) <= 76 : false);
  57.                             break;
  58.                         case FieldType.hcl:
  59.                             valid = value.Length == 7 && Regex.IsMatch(value, @"#[0-9a-f]+");
  60.                             break;
  61.                         case FieldType.ecl:
  62.                             valid = new[]{"amb", "blu", "brn", "gry", "grn", "hzl", "oth"}.Contains(value);
  63.                             break;
  64.                         case FieldType.pid:
  65.                             valid = value.Length == 9 && !Regex.IsMatch(value, @"\D");
  66.                             break;
  67.                     }
  68.                    
  69.                     if (valid)
  70.                         fields ^= (byte) (1 << (byte) fieldType); // jeśli warunek jest spełniony to ustawiamy odpowiedni bit na 1 (sztuczka z XORem i przusuwaniem bitów w masce)
  71.                 }
  72.             }
  73.            
  74.             Console.WriteLine($"There are {validPassports} valid passports"); // wypisujemy ile jest ostatecznie poprawnych paszportów
  75.         }
  76.     }
  77. }
RAW Paste Data