Advertisement
sarumeister

AoC-2022 Day 19b -- no allocations

Dec 19th, 2022 (edited)
927
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.50 KB | None | 0 0
  1. #include <stdio.h>
  2.  
  3.  
  4. struct Blueprint
  5. {
  6.     int id{ 0 };
  7.     int oreForO{ 0 };
  8.     int oreForC{ 0 };
  9.     int oreForB{ 0 };
  10.     int clayForB{ 0 };
  11.     int oreForG{ 0 };
  12.     int obsForG{ 0 };
  13. };
  14.  
  15.  
  16. struct Pile
  17. {
  18.     int oreCnt{ 0 };
  19.     int clayCnt{ 0 };
  20.     int obsCnt{ 0 };
  21.     int geoCnt{ 0 };
  22.  
  23.     int robotOreCnt{ 0 };
  24.     int robotClayCnt{ 0 };
  25.     int robotObsCnt{ 0 };
  26.     int robotGeoCnt{ 0 };
  27. };
  28.  
  29.  
  30. // proto
  31. void calcRecursive(int days, char to, Pile pile);
  32.  
  33.  
  34. #define TIMEMIN 32
  35. Blueprint globalBlueprint;
  36. int globalMax = 0;
  37.  
  38.  
  39. int doWork()
  40. {
  41.     Pile pile;
  42.     pile.robotOreCnt = 1;
  43.     globalMax = 0;
  44.  
  45.     calcRecursive(TIMEMIN, 'o', pile);   // you can't make oBsidian and Geoid types of robots
  46.     calcRecursive(TIMEMIN, 'c', pile);
  47.  
  48.     printf("%d max: %d\n", globalBlueprint.id, globalMax);
  49.     return globalMax;
  50. }
  51.  
  52.  
  53.  
  54. int calcDist(Pile & pile, char c)
  55. {
  56.     int res = 0xFFFF;
  57.     switch (c)
  58.     {
  59.     case 'o':
  60.     {   // divide and round to upper
  61.         res = (globalBlueprint.oreForO - pile.oreCnt + pile.robotOreCnt - 1) / pile.robotOreCnt; res = res > 0 ? res : 0;
  62.         break;
  63.     }
  64.     case 'c':
  65.     {
  66.         res = (globalBlueprint.oreForC - pile.oreCnt + pile.robotOreCnt - 1) / pile.robotOreCnt; res = res > 0 ? res : 0;
  67.         break;
  68.     }
  69.     case 'b':
  70.     {
  71.         if (!pile.robotClayCnt)
  72.             return res;
  73.         int res1 = (globalBlueprint.oreForB - pile.oreCnt + pile.robotOreCnt - 1) / pile.robotOreCnt; res1 = res1 > 0 ? res1 : 0;
  74.         int res2 = (globalBlueprint.clayForB - pile.clayCnt + pile.robotClayCnt - 1) / pile.robotClayCnt; res2 = res2 > 0 ? res2 : 0;
  75.         res = res1 > res2 ? res1 : res2;
  76.         break;
  77.     }
  78.     case 'g':
  79.     {
  80.         if (!pile.robotObsCnt)
  81.             return res;
  82.         int res1 = (globalBlueprint.oreForG - pile.oreCnt + pile.robotOreCnt - 1) / pile.robotOreCnt; res1 = res1 > 0 ? res1 : 0;
  83.         int res2 = (globalBlueprint.obsForG - pile.obsCnt + pile.robotObsCnt - 1) / pile.robotObsCnt; res2 = res2 > 0 ? res2 : 0;
  84.         res = res1 > res2 ? res1 : res2;
  85.     }
  86.     }
  87.     return res;
  88. }
  89.  
  90.  
  91. void calcRecursive(int minutesLeft, char to, Pile pile)
  92. {
  93.     if (minutesLeft <= 0)
  94.     {
  95.         // the end
  96.         if (globalMax <= pile.geoCnt)
  97.             globalMax = pile.geoCnt;
  98.  
  99.         return;
  100.     }
  101.  
  102.     int dist = calcDist(pile, to);
  103.     if (dist > minutesLeft - 1)
  104.     {
  105.         // the end
  106.         if (dist != 0xFFFF)
  107.         {
  108.             pile.oreCnt += pile.robotOreCnt * minutesLeft;
  109.             pile.clayCnt += pile.robotClayCnt * minutesLeft;
  110.             pile.obsCnt += pile.robotObsCnt * minutesLeft;
  111.             pile.geoCnt += pile.robotGeoCnt * minutesLeft;
  112.         }
  113.  
  114.         if (globalMax <= pile.geoCnt)
  115.             globalMax = pile.geoCnt;
  116.  
  117.         return;
  118.     }
  119.  
  120.     // yeilding
  121.     pile.oreCnt += pile.robotOreCnt * dist;
  122.     pile.clayCnt += pile.robotClayCnt * dist;
  123.     pile.obsCnt += pile.robotObsCnt * dist;
  124.     pile.geoCnt += pile.robotGeoCnt * dist;
  125.  
  126.     minutesLeft -= dist;
  127.  
  128.     // time to build robot
  129.     switch (to)
  130.     {
  131.     case 'o':
  132.         pile.oreCnt -= globalBlueprint.oreForO;
  133.         break;
  134.     case 'c':
  135.         pile.oreCnt -= globalBlueprint.oreForC;
  136.         break;
  137.     case 'b':
  138.         pile.oreCnt -= globalBlueprint.oreForB;
  139.         pile.clayCnt -= globalBlueprint.clayForB;
  140.         break;
  141.     case 'g':
  142.         pile.oreCnt -= globalBlueprint.oreForG;
  143.         pile.obsCnt -= globalBlueprint.obsForG;
  144.         break;
  145.     }
  146.  
  147.     // while creating robot
  148.     pile.oreCnt += pile.robotOreCnt;
  149.     pile.clayCnt += pile.robotClayCnt;
  150.     pile.obsCnt += pile.robotObsCnt;
  151.     pile.geoCnt += pile.robotGeoCnt;
  152.  
  153.     switch (to)
  154.     {
  155.     case 'o':
  156.         pile.robotOreCnt++;
  157.         break;
  158.     case 'c':
  159.         pile.robotClayCnt++;
  160.         break;
  161.     case 'b':
  162.         pile.robotObsCnt++;
  163.         break;
  164.     case 'g':
  165.         pile.robotGeoCnt++;
  166.         break;
  167.     }
  168.  
  169.     minutesLeft -= 1;
  170.  
  171.     // what to do next?
  172.     if ((pile.obsCnt >= globalBlueprint.obsForG) && (pile.oreCnt >= globalBlueprint.oreForG))
  173.     {
  174.         calcRecursive(minutesLeft, 'g', pile);
  175.     }
  176.     // else if ((pile.clayCnt >= globalBlueprint.clayForB) && (pile.oreCnt >= globalBlueprint.oreForB)) // BUG!
  177.     else if ((pile.clayCnt >= globalBlueprint.clayForB) && (pile.oreCnt >= (globalBlueprint.oreForB + globalBlueprint.oreForG)))
  178.     {
  179.         calcRecursive(minutesLeft, 'b', pile);
  180.     }
  181.     else
  182.     {
  183.         calcRecursive(minutesLeft, 'o', pile);
  184.         calcRecursive(minutesLeft, 'c', pile);
  185.         calcRecursive(minutesLeft, 'b', pile);
  186.         calcRecursive(minutesLeft, 'g', pile);
  187.     }
  188. }
  189.  
  190.  
  191. int main()
  192. {
  193.     FILE* f = NULL;
  194.     fopen_s(&f, "input.txt", "r");
  195.  
  196.     int score = 1;
  197.  
  198.     for(int i = 0; i < 3; i++)
  199.     {
  200.         char buf[1024] = { 0 };
  201.         fgets(buf, 1023, f);
  202.         int res = sscanf_s(buf, "Blueprint %d: Each ore robot costs %d ore. Each clay robot costs %d ore. Each obsidian robot costs %d ore and %d clay. Each geode robot costs %d ore and %d obsidian.",
  203.             &globalBlueprint.id,
  204.             &globalBlueprint.oreForO,
  205.             &globalBlueprint.oreForC,
  206.             &globalBlueprint.oreForB,
  207.             &globalBlueprint.clayForB,
  208.             &globalBlueprint.oreForG,
  209.             &globalBlueprint.obsForG);
  210.  
  211.         if (res == 7)
  212.         {
  213.             score = score * doWork();
  214.         }
  215.     }
  216.     fclose(f);
  217.    
  218.     printf("Score: %d\n", score);
  219.     return 0;
  220. }
  221.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement