mosredna

AoC 2021 day 16

Dec 18th, 2021 (edited)
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.47 KB | None | 0 0
  1. #include <Arduino.h>
  2. #include "types.h"
  3.  
  4. #define ADD 0
  5. #define MULTIPLY 1
  6. #define MIN 2
  7. #define MAX 3
  8. #define LITERAL 4
  9. #define GREATER 5
  10. #define LESS 6
  11. #define EQUAL 7
  12.  
  13. long checksum = 0;
  14. char operators[8][3] = {"+ ", "* ", "mn", "mx", "L ", "> ", "< ", "=="};
  15.  
  16. bool debugExp = false;
  17. int printExp(char *c)
  18. {
  19.   return debugExp && Serial.priant(c);
  20. }
  21.  
  22. bool debugTree = false;
  23. int printTree(char *c, int indent, char *op)
  24. {
  25.   if (debugTree)
  26.   {
  27.     for (int i = 0; i < indent - 1; i++)
  28.       Serial.print("|  ");
  29.     Serial.print(op);
  30.     Serial.print(".");
  31.     Serial.println(c);
  32.     return 1;
  33.   }
  34.   return 0;
  35. }
  36.  
  37. // const char data[] PROGMEM = {"020D78804D397973DB5B934D9280CC9F43080286957D9F60923592619D3230047C0109763976295356007365B37539ADE687F333EA8469200B666F5DC84E80232FC2C91B8490041332EB4006C4759775933530052C0119FAA7CB6ED57B9BBFBDC153004B0024299B490E537AFE3DA069EC507800370980F96F924A4F1E0495F691259198031C95AEF587B85B254F49C27AA2640082490F4B0F9802B2CFDA0094D5FB5D626E32B16D300565398DC6AFF600A080371BA12C1900042A37C398490F67BDDB131802928F5A009080351DA1FC441006A3C46C82020084FC1BE07CEA298029A008CCF08E5ED4689FD73BAA4510C009981C20056E2E4FAACA36000A10600D45A8750CC8010989716A299002171E634439200B47001009C749C7591BD7D0431002A4A73029866200F1277D7D8570043123A976AD72FFBD9CC80501A00AE677F5A43D8DB54D5FDECB7C8DEB0C77F8683005FC0109FCE7C89252E72693370545007A29C5B832E017CFF3E6B262126E7298FA1CC4A072E0054F5FBECC06671FE7D2C802359B56A0040245924585400F40313580B9B10031C00A500354009100300081D50028C00C1002C005BA300204008200FB50033F70028001FE60053A7E93957E1D09940209B7195A56BCC75AE7F18D46E273882402CCD006A600084C1D8ED0E8401D8A90BE12CCF2F4C4ADA602013BC401B8C11360880021B1361E4511007609C7B8CA8002DC32200F3AC01698EE2FF8A2C95B42F2DBAEB48A401BC5802737F8460C537F8460CF3D953100625C5A7D766E9CB7A39D8820082F29A9C9C244D6529C589F8C693EA5CD0218043382126492AD732924022CE006AE200DC248471D00010986D17A3547F200CA340149EDC4F67B71399BAEF2A64024B78028200FC778311CC40188AF0DA194CF743CC014E4D5A5AFBB4A4F30C9AC435004E662BB3EF0"};
  38. const char bitArray[] PROGMEM = {"000000100000110101111000100000000100110100111001011110010111001111011011010110111001001101001101100100101000000011001100100111110100001100001000000000101000011010010101011111011001111101100000100100100011010110010010011000011001110100110010001100000000010001111100000000010000100101110110001110010111011000101001010100110101011000000000011100110110010110110011011101010011100110101101111001101000011111110011001100111110101010000100011010010010000000001011011001100110111101011101110010000100111010000000001000110010111111000010110010010001101110000100100100000000010000010011001100101110101101000000000001101100010001110101100101110111010110010011001101010011000000000101001011000000000100011001111110101010011111001011011011101101010101111011100110111011111110111101110000010101001100000000010010110000000000100100001010011001101101001001000011100101001101111010111111100011110110100000011010011110110001010000011110000000000000110111000010011000000011111001011011111001001001001010010011110001111000000100100101011111011010010001001001011001000110011000000000110001110010010101101011101111010110000111101110000101101100100101010011110100100111000010011110101010001001100100000000001000001001001001000011110100101100001111100110000000001010110010110011111101101000000000100101001101010111111011010111010110001001101110001100101011000101101101001100000000010101100101001110011000110111000110101011111111011000000000101000001000000000110111000110111010000100101100000110010000000000000100001010100011011111000011100110000100100100001111011001111011110111011011000100110001100000000010100100101000111101011010000000001001000010000000001101010001110110100001111111000100010000010000000001101010001111000100011011001000001000000010000000001000010011111100000110111110000001111100111010100010100110000000001010011010000000001000110011001111000010001110010111101101010001101000100111111101011100111011101010100100010100010000110000000000100110011000000111000010000000000101011011100010111001001111101010101100101000110110000000000000101000010000011000000000110101000101101010000111010100001100110010000000000100001001100010010111000101101010001010011001000000000010000101110001111001100011010001000011100100100000000010110100011100000000000100000000100111000111010010011100011101011001000110111101011111010000010000110001000000000010101001001010011100110000001010011000011001100010000000001111000100100111011111010111110110000101011100000000010000110001001000111010100101110110101011010111001011111111101111011001110011001000000001010000000110100000000010101110011001110111111101011010010000111101100011011011010101001101010111111101111011001011011111001000110111101011000011000111011111111000011010000011000000000101111111000000000100001001111111001110011111001000100100100101001011100111001001101001001100110111000001010100010100000000011110100010100111000101101110000011001011100000000101111100111111110011111001101011001001100010000100100110111001110010100110001111101000011100110001001010000001110010111000000000010101001111010111111011111011001100000001100110011100011111111001111101001011001000000000100011010110011011010101101010000000000100000000100100010110010010010001011000010101000000000011110100000000110001001101011000000010111001101100010000000000110001110000000000101001010000000000110101010000000000100100010000000000110000000000001000000111010101000000000010100011000000000011000001000000000010110000000000010110111010001100000000001000000100000000001000001000000000111110110101000000000011001111110111000000000010100000000000000111111110011000000000010100111010011111101001001110010101011111100001110100001001100101000000001000001001101101110001100101011010010101101011110011000111010110101110011111110001100011010100011011100010011100111000100000100100000000101100110011010000000001101010011000000000000010000100110000011101100011101101000011101000010000000001110110001010100100001011111000010010110011001111001011110100110001001010110110100110000000100000000100111011110001000000000110111000110000010001001101100000100010000000000000100001101100010011011000011110010001010001000100000000011101100000100111000111101110001100101010000000000000101101110000110010001000000000111100111010110000000001011010011000111011100010111111111000101000101100100101011011010000101111001011011011101011101011010010001010010000000001101111000101100000000010011100110111111110000100011000001100010100110111111110000100011000001100111100111101100101010011000100000000011000100101110001011010011111010111011001101110100111001011011110100011100111011000100000100000000010000010111100101001101010011100100111000010010001001101011001010010100111000101100010011111100011000110100100111110101001011100110100000010000110000000010000110011100000100001001001100100100100101010110101110011001010010010010000000010001011001110000000000110101011100010000000001101110000100100100001000111000111010000000000000001000010011000011011010001011110100011010101000111111100100000000011001010001101000000000101001001111011011100010011110110011110110111000100111001100110111010111011110010101001100100000000100100101101111000000000101000001000000000111111000111011110000011000100011100110001000000000110001000101011110000110110100001100101001100111101110100001111001100000000010100111001001101010110100101101011111011101101001010010011110011000011001001101011000100001101010000000001001110011001100010101110110011111011110000"};
  39.  
  40. //  const char bitArray[] PROGMEM = {"1100001000000000101101000000101010000010"};
  41. //  char bitArray[((sizeof data / sizeof data[1])) *4] = {'\0'};
  42. //  const char binary[16][5] = {"0000", "0001", "0010", "0011", "0100", "0101","0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110","1111"};
  43. //  const String digits = "0123456789ABCDEF";
  44.  
  45. char *LL2Char(long long input)
  46. {
  47.   if (input == 0)
  48.     return "0\0";
  49.  
  50.   static char result[21] = "";
  51.   memset(&result[0], 0, sizeof(result));
  52.  
  53.   char temp[21] = "";
  54.   char c;
  55.   uint8_t base = 10;
  56.   while (input)
  57.   {
  58.     int num = input % base;
  59.     input /= base;
  60.     c = '0' + num;
  61.  
  62.     sprintf(temp, "%c%s", c, result);
  63.     strcpy(result, temp);
  64.   }
  65.   // strcat(result, "LL");
  66.   return result;
  67. }
  68.  
  69. long long char2LL(char *str, int size)
  70. {
  71.   long long result = 0LL;
  72.   int bit = 0;
  73.  
  74.   for (int i = size - 1; i >= 0; i--)
  75.     result += (long long)(str[i] - '0') << bit++;
  76.  
  77.   return result;
  78. }
  79.  
  80. int char2Int(char *c)
  81. {
  82.   return strtol(c, NULL, 2);
  83. }
  84.  
  85. long long processNumber(long long &value, long long v, int id, bool print = false)
  86. {
  87.   switch (id)
  88.   {
  89.   case ADD:
  90.     print &&printExp(" + ");
  91.     value += v;
  92.     break;
  93.   case MULTIPLY:
  94.     print &&printExp(" * ");
  95.     value *= v;
  96.     break;
  97.   case MIN:
  98.     print &&printExp(", ");
  99.     if (value == 0)
  100.       value = INFINITY;
  101.     value = min(value, v);
  102.     break;
  103.   case MAX:
  104.     print &&printExp(", ");
  105.     value = max(value, v);
  106.     break;
  107.   default:
  108.     Serial.println(F("UNKNOWN OPERATOR ID"));
  109.     break;
  110.   }
  111. }
  112.  
  113. packet partseData(int pointer, int indent, int print = 0);
  114. packet partseData(int pointer, int indent, int print = 0)
  115. {
  116.   packet pack;
  117.  
  118.   indent++;
  119.   int p = pointer;
  120.  
  121.   char version[4] = {'\0'};
  122.   char id[4] = {'\0'};
  123.   strncpy_P(version, bitArray + p, 3);
  124.   strncpy_P(id, bitArray + p + 3, 3);
  125.   p += 6;
  126.  
  127.   int idType = char2Int(id);
  128.   checksum += char2Int(version);
  129.  
  130.   if (idType == LITERAL)
  131.   {
  132.     char val[64] = {"\0"};
  133.     char num[5] = {"\0"};
  134.     char closeBit[1] = "1";
  135.     int size = 0;
  136.  
  137.     while (closeBit[0] == '1')
  138.     {
  139.       strncpy_P(closeBit, bitArray + p, 1);
  140.       strncpy_P(num, bitArray + p + 1, 4);
  141.       strcat(val, num);
  142.       p += 5;
  143.       size += 4;
  144.     }
  145.     pack.value = char2LL(val, size);
  146.  
  147.     if (print < 4)
  148.       printExp(LL2Char(pack.value));
  149.   }
  150.   else
  151.   {
  152.     char lengthType[2]{'\0'};
  153.     strncpy_P(lengthType, bitArray + p, 1);
  154.     p++;
  155.     int valueIndex = 0;
  156.  
  157.     long long values[2];
  158.     long long value = 0LL;
  159.  
  160.     if (idType == MIN)
  161.       printExp("min");
  162.     if (idType == MAX)
  163.       printExp("max");
  164.     printExp("(");
  165.  
  166.     if (lengthType[0] == '0')
  167.     {
  168.       char subPacketsLength[16] = {"\0s"};
  169.       memcpy_P(subPacketsLength, bitArray + p, 15);
  170.       long subL = char2Int(subPacketsLength);
  171.       p += 15;
  172.       int end = p + subL;
  173.       int round = 0;
  174.       while (p < end)
  175.       {
  176.         round++;
  177.         packet pck = partseData(p, indent, end > 2 ? 0:idType);
  178.         p = pck.index;
  179.  
  180.         if (idType < 4)
  181.         {
  182.           if (round == 1 && idType == 1)
  183.             value = 1;
  184.           processNumber(value, pck.value, idType, p < end);
  185.         }
  186.         else
  187.           values[valueIndex++] = pck.value;
  188.  
  189.         pack.value = value;
  190.         if (p < end)
  191.         {
  192.           idType == 5 && printExp(" > ");
  193.           idType == 6 && printExp(" < ");
  194.           idType == 7 && printExp(" == ");
  195.         }
  196.       }
  197.     }
  198.     else if (lengthType[0] == '1')
  199.     {
  200.       char numSubPackets[12] = {"\0s"};
  201.       memcpy_P(numSubPackets, bitArray + p, 11);
  202.       long num = char2Int(numSubPackets);
  203.       p += 11;
  204.       for (size_t i = 0; i < num; i++)
  205.       {
  206.         packet pck = partseData(p, indent, num == 2 ? 0:idType);
  207.         p = pck.index;
  208.  
  209.         if (idType < LITERAL)
  210.         {
  211.           if (i == 0 && idType == MULTIPLY)
  212.             value = 1;
  213.           processNumber(value, pck.value, idType, i < num - 1);
  214.         }
  215.         else
  216.           values[valueIndex++] = pck.value;
  217.  
  218.         if (i < num - 1)
  219.         {
  220.           idType == 5 && printExp(" > ");
  221.           idType == 6 && printExp(" < ");
  222.           idType == 7 && printExp(" == ");
  223.         }
  224.         pack.value = value;
  225.       }
  226.     }
  227.  
  228.     if (idType == GREATER && values[0] > values[1])
  229.       pack.value = 1LL;
  230.     if (idType == LESS && values[0] < values[1])
  231.       pack.value = 1LL;
  232.     if (idType == EQUAL && values[0] == values[1])
  233.       pack.value = 1LL;
  234.  
  235.     printExp(")");
  236.   }
  237.  
  238.   pack.index = p;
  239.  
  240.   printTree(LL2Char(pack.value), indent, operators[idType]);
  241.  
  242.   return pack;
  243. }
  244.  
  245. void setup()
  246. {
  247.   Serial.begin(9600);
  248.   while (!Serial)
  249.     ;
  250.  
  251.   Serial.println("START");
  252.   long time = millis();
  253.   // for (size_t i = 0; i < sizeof data / sizeof data[0]; i++)
  254.   // {
  255.   //    strcat(bitArray,binary[digits.indexOf( pgm_read_byte(data + i))]);
  256.   // }
  257.   //  Serial.println( bitArray );
  258.   packet p = partseData(0, 0, true);
  259.   debugExp && Serial.println();
  260.  
  261.   Serial.println("-----------------");
  262.   Serial.println(checksum);
  263.   Serial.println(LL2Char(p.value));
  264.   Serial.println();
  265.   Serial.println(millis() - time);
  266. }
  267.  
  268. void loop()
  269. {
  270. }
Add Comment
Please, Sign In to add comment