Advertisement
sarumeister

AoC-2022 Day 13a -- single pass no allocations

Dec 13th, 2022 (edited)
776
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.60 KB | None | 0 0
  1. #include <stdio.h>
  2.  
  3. char input[] = R"([1,1,3,1,1]
  4. [1,1,5,1,1]
  5.  
  6. [[1],[2,3,4]]
  7. [[1],4]
  8.  
  9. [9]
  10. [[8,7,6]]
  11.  
  12. [[4,4],4,4]
  13. [[4,4],4,4,4]
  14.  
  15. [7,7,7,7]
  16. [7,7,7]
  17.  
  18. []
  19. [3]
  20.  
  21. [[[]]]
  22. [[]]
  23.  
  24. [1,[2,[3,[4,[5,6,7]]]],8,9]
  25. [1,[2,[3,[4,[5,6,0]]]],8,9]
  26. )";
  27.  
  28. /*
  29. *
  30. * LEFT := LIST
  31. * RIGHT := LIST
  32. * LIST := '[' (BODY)? ']'
  33. * BODY := ELEM (',' ELEM)*
  34. * ELEM := NUM | LIST
  35. *
  36. * TODO: s/int&/int*/
  37. */
  38.  
  39. int myParseCompareElem(const char* strL, int& posL, const char* strR, int& posR, int& order);
  40. int myParseCompareBody(const char* strL, int& posL, const char* strR, int& posR, int& order);
  41. int myParseCompareList(const char* strL, int& posL, const char* strR, int& posR, int& order);
  42.  
  43.  
  44. int myParseCompareElem(const char* strL, int& posL, const char* strR, int& posR, int& order)
  45. {
  46.     int res = 0;
  47.     char cl = strL[posL];
  48.     char cr = strR[posR];
  49.  
  50.     if (('[' != cl) && (cl < '0' || cl > '9'))
  51.         return posL;    // error
  52.     if (('[' != cr) && (cr < '0' || cr > '9'))
  53.         return posR;    // error
  54.  
  55.     bool isListL = ('[' == cl);
  56.     bool isListR = ('[' == cr);
  57.  
  58.     int vall = 0;
  59.     int valr = 0;
  60.     if (!isListL)
  61.     {
  62.         while (cl >= '0' && cl <= '9')
  63.         {
  64.             vall += vall * 10 + cl - '0';
  65.             posL++;
  66.             cl = strL[posL];
  67.         }
  68.     }
  69.  
  70.     if (!isListR)
  71.     {
  72.         while (cr >= '0' && cr <= '9')
  73.         {
  74.             valr += valr * 10 + cr - '0';
  75.             posR++;
  76.             cr = strR[posR];
  77.         }
  78.     }
  79.  
  80.     if (isListL && !isListR)
  81.     {
  82.         char buf[40];
  83.         sprintf_s(buf, "[%d]", valr);
  84.         int tempPos = 0;
  85.         res = myParseCompareList(strL, posL, buf, tempPos, order);
  86.         if (res)
  87.             return res;    // error
  88.         if (order)
  89.             return 0;
  90.     }
  91.     else if (!isListL && isListR)
  92.     {
  93.         char buf[40];
  94.         sprintf_s(buf, "[%d]", vall);
  95.         int tempPos = 0;
  96.         res = myParseCompareList(buf, tempPos, strR, posR, order);
  97.         if (res)
  98.             return res;    // error
  99.         if (order)
  100.             return 0;
  101.     }
  102.     else if (isListL && isListR)
  103.     {
  104.         res = myParseCompareList(strL, posL, strR, posR, order);
  105.         if (res)
  106.             return res;    // error
  107.         if (order)
  108.             return 0;
  109.     }
  110.     else if (!isListL && !isListR)
  111.     {
  112.         order = valr - vall;
  113.     }
  114.  
  115.     return 0;
  116. }
  117.  
  118. int myParseCompareBody(const char* strL, int& posL, const char* strR, int& posR, int& order)
  119. {
  120.     int res = 0;
  121.     res = myParseCompareElem(strL, posL, strR, posR, order);
  122.     if (res)
  123.         return res;    // error
  124.     if (order)
  125.         return 0;
  126.  
  127.     int contL = (',' == strL[posL]);
  128.     int contR = (',' == strR[posR]);
  129.  
  130.     order = contR - contL;
  131.     if (order)
  132.         return 0;
  133.  
  134.     while (contL && contR)
  135.     {
  136.         posL++;
  137.         posR++;
  138.  
  139.         res = myParseCompareElem(strL, posL, strR, posR, order);
  140.         if (res)
  141.             return res;    // error
  142.         if (order)
  143.             return 0;
  144.  
  145.         int contL = (',' == strL[posL]);
  146.         int contR = (',' == strR[posR]);
  147.  
  148.         order = contR - contL;
  149.         if (order)
  150.             return 0;
  151.     }
  152.  
  153.     return 0;
  154. }
  155.  
  156. int myParseCompareList(const char* strL, int & posL, const char* strR, int& posR, int & order)
  157. {
  158.     int res = 0;
  159.     if ('[' != strL[posL])
  160.         return posL;    // error
  161.     if ('[' != strR[posR])
  162.         return posR;    // error
  163.     posL++;
  164.     posR++;
  165.  
  166.     int bodyPresentL = (']' != strL[posL]);
  167.     int bodyPresentR = (']' != strR[posR]);
  168.  
  169.     order = bodyPresentR - bodyPresentL;
  170.     if (order)
  171.         return 0;
  172.  
  173.     if (bodyPresentL && bodyPresentR)
  174.     {
  175.         res = myParseCompareBody(strL, posL, strR, posR, order);
  176.         if (res)
  177.             return res;    // error
  178.         if (order)
  179.             return 0;
  180.     }
  181.  
  182.     posL++;
  183.     posR++;
  184.  
  185.     return 0;
  186. }
  187.  
  188.  
  189. int main()
  190. {
  191.     int i = 0;
  192.     int pos = 0;
  193.     int index = 0;
  194.     int score = 0;
  195.  
  196.     int beginL = 0;
  197.     int beginR = 0;
  198.  
  199.     while (input[i])
  200.     {
  201.         char c = input[i++];
  202.  
  203.         if ('\n' == c)
  204.         {
  205.             pos++;
  206.             pos %= 3;
  207.             if (0 == pos)
  208.                 beginL = i;
  209.             if (1 == pos)
  210.                 beginR = i;
  211.             if (2 == pos)
  212.             {
  213.                 int order = 0;
  214.  
  215.                 int err = myParseCompareList(input, beginL, input, beginR, order);
  216.  
  217.                 index++;
  218.                 if (order >= 0)
  219.                     score += index;
  220.             }
  221.             continue;
  222.         }
  223.     }
  224.  
  225.     printf("%d\n", score);
  226. }
  227.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement