Advertisement
Guest User

--- Day 16: Ticket Translation ---

a guest
Dec 16th, 2020
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.96 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <iterator>
  4. #include <fstream>
  5. #include <sstream>
  6. #include <string>
  7. #include <vector>
  8. #include <map>
  9. #include <numeric>
  10.  
  11. struct Field
  12. {
  13.     std::string name;
  14.     std::pair<int, int> range[2];
  15.  
  16.     bool IsValid(int num) const
  17.     {
  18.         for (unsigned int i = 0; i < 2; i++)
  19.         {
  20.             if (num >= range[i].first && num <= range[i].second) //if the number fits into at least one range, it must be valid
  21.                 return true;
  22.         }
  23.  
  24.         return false;
  25.     }
  26. };
  27.  
  28. int main()
  29. {
  30.     std::string text;
  31.     std::ifstream ifs;
  32.     ifs.open("data.txt", std::ifstream::in);
  33.  
  34.     unsigned long long part1Answer = 0;
  35.     unsigned long long part2Answer = 0;
  36.  
  37.     int turn = 0;
  38.     std::vector<Field> field;
  39.     std::vector<int> myTicket;
  40.     std::vector<std::vector<int>> validTicket;
  41.     while (getline(ifs, text))
  42.     {
  43.         if (text == "")
  44.         {
  45.             turn = 0;
  46.             continue;
  47.         }
  48.         else if (text == "your ticket:")
  49.         {
  50.             turn = 1;
  51.             continue;
  52.         }
  53.         else if (text == "nearby tickets:")
  54.         {
  55.             turn = 2;
  56.             continue;
  57.         }
  58.  
  59.         if (turn == 0) //parse fields
  60.         {
  61.             Field f;
  62.             f.name = text.substr(0, text.find(':'));
  63.             text.erase(0, text.find(':') + 1);
  64.  
  65.             std::istringstream iss(text);
  66.             std::vector<std::string> results((std::istream_iterator<std::string>(iss)), std::istream_iterator<std::string>());
  67.             f.range[0].first = atoi(results[0].substr(0, results[0].find('-')).c_str());
  68.             f.range[0].second = atoi(results[0].substr(results[0].find('-') + 1).c_str());
  69.             f.range[1].first = atoi(results[2].substr(0, results[2].find('-')).c_str());
  70.             f.range[1].second = atoi(results[2].substr(results[2].find('-') + 1).c_str());
  71.             field.push_back(f);
  72.         }
  73.         else if (turn == 1) //get my ticket
  74.         {
  75.             std::string s;
  76.             std::istringstream iss(text);
  77.             while (getline(iss, s, ','))
  78.                 myTicket.push_back(atoi(s.c_str()));
  79.         }
  80.         else //check nearby tickets
  81.         {
  82.             std::string s;
  83.             std::istringstream iss(text);
  84.  
  85.             std::vector<int> ticket;
  86.             bool valid = true;
  87.             int n = 0;
  88.             while (getline(iss, s, ','))
  89.             {
  90.                 int number = atoi(s.c_str());
  91.  
  92.                 int val = 0;
  93.                 for (unsigned int i = 0; i < field.size(); i++)
  94.                 {
  95.                     if (field[i].IsValid(number))
  96.                     {
  97.                         val++;
  98.                     }
  99.                 }
  100.  
  101.                 if (val == 0) //if at least one number is completely invalid, ticket is invalid
  102.                 {
  103.                     part1Answer += number;
  104.                     valid = false;
  105.                 }
  106.  
  107.                 ticket.push_back(number);
  108.                 n++;
  109.             }
  110.  
  111.             if (valid) //if ticket is valid, add to list.
  112.             {
  113.                 validTicket.push_back(ticket);
  114.             }
  115.         }
  116.     }
  117.  
  118.     std::cout << "Part 1 Answer: " << part1Answer << std::endl;
  119.  
  120.     //validTicket.push_back(myTicket); //add my ticket to the valid list
  121.  
  122.     std::vector<int> order(field.size());
  123.     std::fill(order.begin(), order.end(), -1);
  124.  
  125.     bool valid;
  126.     do
  127.     {
  128.         for (unsigned int i = 0; i < field.size(); i++)
  129.         {
  130.             int possibility = 0;
  131.             int pos = -1;
  132.  
  133.             const Field& f = field[i];
  134.  
  135.             for (unsigned int j = 0; j < myTicket.size(); j++)
  136.             {
  137.                 if (order[j] >= 0) //already set, so skip
  138.                     continue;
  139.  
  140.                 unsigned int k = 0;
  141.                 for (k; k < validTicket.size(); k++) //search through all valid tickets including mine
  142.                 {
  143.                     const std::vector<int>& ticket = validTicket[k];
  144.                     int theirs = ticket[j];
  145.                     if (!f.IsValid(theirs))
  146.                         break;
  147.                 }
  148.  
  149.                 if (k >= validTicket.size()) //Valid Field!
  150.                 {
  151.                     possibility++;
  152.                     pos = j;
  153.                 }
  154.             }
  155.  
  156.             if (possibility == 1)
  157.                 order[pos] = i;
  158.         }
  159.  
  160.         valid = true;
  161.         for (unsigned int i = 0; i < order.size(); i++)
  162.         {
  163.             if (order[i] < 0)
  164.                 valid = false;
  165.         }
  166.  
  167.     } while (!valid);
  168.  
  169.     for (unsigned int i = 0; i < myTicket.size(); i++)
  170.     {
  171.         int f = order[i];
  172.         int t = i;
  173.  
  174.         std::cout << field[f].name << ": " << myTicket[t] << std::endl;
  175.         if (field[f].name.find("departure") != std::string::npos)
  176.         {
  177.             if (part2Answer == 0)
  178.                 part2Answer = myTicket[t];
  179.             else
  180.                 part2Answer *= myTicket[t];
  181.         }
  182.     }
  183.  
  184.     std::cout << "Part 2 Answer: " << part2Answer << std::endl;
  185.  
  186.     return 0;
  187. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement