Advertisement
Guest User

Untitled

a guest
Dec 9th, 2024
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.07 KB | None | 0 0
  1. #include <vector>
  2. #include <iostream>
  3. #include <fstream>
  4. #include <algorithm>
  5. #include <list>
  6. using namespace std;
  7.  
  8. uint64_t consecSum(uint64_t from, uint64_t to) {
  9. uint64_t a = to * (to+1) / 2;
  10. uint64_t b = (from - 1) * (from) / 2;
  11. return a - b;
  12. }
  13.  
  14. // 12345
  15. uint64_t getChecksumP1(vector<uint64_t> input) {
  16. uint64_t checksum = 0;
  17. uint64_t fIndex = 0;
  18.  
  19. for (int i=0; i<input.size(); ++i) {
  20. if (i % 2 == 0) { // represents a file of block size
  21. checksum += (i/2) * consecSum(fIndex, input[i] + fIndex - 1);
  22. fIndex += input[i];
  23. } else {
  24. while (input[i] > 0 && input.size() > i+1) {
  25. // get last non-empty val
  26. uint64_t loc = input.size()-1;
  27.  
  28. for (int j=0; j<input[i]; ++j) {
  29. if (input[loc] <= 0) break;
  30. input[loc] -= 1;
  31. input[i] -= 1; // one less free space to fill
  32.  
  33. checksum += uint64_t(loc/2) * (fIndex);
  34. fIndex ++;
  35. }
  36.  
  37. if (input[loc] == 0) {
  38. input.pop_back(); input.pop_back();
  39. }
  40. }
  41. }
  42. }
  43. return checksum;
  44. }
  45.  
  46. // 00 99[1] 2111777.44.333....5555.6666..... 8888[16] ..
  47.  
  48. class FreeList {
  49. struct Info {
  50. uint64_t start, cap;
  51. };
  52.  
  53. list<Info> freeList;
  54.  
  55. uint64_t addToList(uint64_t id, uint64_t cap, uint64_t prefixSum, uint64_t& checksum) {
  56. int start = prefixSum;
  57. for (auto it = freeList.begin(); it != freeList.end(); ++it) {
  58. if (it->cap >= cap) {
  59. if (it->start >= prefixSum) break;
  60. // cout << "found match: " << it->cap << " idx: " << it->start << " req: " << cap << endl;
  61.  
  62. // reduce cap of occupied block
  63. start = it->start;
  64. it->start += cap;
  65. it->cap -= cap;
  66. if (it->cap == 0) freeList.erase(it);
  67.  
  68. // add new empty block @ start pos of the moved block
  69. Info newInfo{prefixSum, cap};
  70. auto newInsertPos = freeList.end();
  71. for (auto addIt = freeList.begin(); addIt != freeList.end(); ++addIt) {
  72. if (addIt->start > prefixSum) {
  73. newInsertPos = addIt;
  74. break;
  75. }
  76. }
  77. freeList.insert(newInsertPos, newInfo);
  78. std::advance(newInsertPos, -1);
  79.  
  80. // COLLAPSE
  81. // if (id == 4) break;
  82.  
  83. auto lookAroundIt = newInsertPos;
  84. std::advance(lookAroundIt, -1); // previous
  85. // cout << "prev: " << lookAroundIt->start + lookAroundIt->cap << " == " << newInsertPos->start << endl;
  86.  
  87. if (newInsertPos != freeList.begin() && lookAroundIt->start + lookAroundIt->cap == newInsertPos->start) {
  88. newInsertPos->start = lookAroundIt->start;
  89. newInsertPos->cap += lookAroundIt->cap;
  90.  
  91. freeList.erase(lookAroundIt);
  92. // cout << "FRONT" << endl;
  93. }
  94. lookAroundIt = newInsertPos;
  95. std::advance(lookAroundIt, 1); // next
  96. // cout << "next: " << lookAroundIt->start << " curr: " << newInsertPos->start << endl;
  97. if (lookAroundIt != freeList.end() && newInsertPos->start + newInsertPos->cap == lookAroundIt->start) {
  98. newInsertPos->cap += lookAroundIt->cap;
  99.  
  100. freeList.erase(lookAroundIt);
  101.  
  102. // cout << "BACK" << endl;
  103. }
  104.  
  105. break;
  106. }
  107. }
  108.  
  109. // update checksum
  110. return id * consecSum(start, start + cap - 1);
  111. }
  112.  
  113. public:
  114.  
  115. uint64_t packFiles(const vector<uint64_t>& inputs) {
  116. // add to free list
  117. uint64_t sum = 0;
  118. vector<uint64_t> prefixSums;
  119. for (int i=0; i<inputs.size(); ++i) {
  120. prefixSums.emplace_back(sum);
  121. if (i % 2 == 1 && inputs[i] > 0) freeList.push_back(Info{sum, inputs[i]});
  122. sum += inputs[i];
  123. }
  124.  
  125. // iter over all filled spaces
  126. uint64_t checksum = 0;
  127.  
  128. for (int i=inputs.size()-1; i >= 0; --i) {
  129. if (i % 2 == 0) {
  130. checksum += addToList(i/2, inputs[i], prefixSums[i], checksum);
  131.  
  132. // print free list
  133. // cout << "adding: " << i/2 << " : " << inputs[i] << endl;
  134. // for (const auto& v : freeList)
  135. // cout << v.start << " : " << v.cap << " -> ";
  136. // cout << endl;
  137.  
  138. // if (i/2 == 4) break;
  139. }
  140. }
  141.  
  142. return checksum;
  143. }
  144. };
  145.  
  146. int main() {
  147. char ch;
  148. vector<uint64_t> inputs;
  149. while (cin >> ch) inputs.emplace_back(ch - '0');
  150.  
  151. cout << "part1: " << getChecksumP1(inputs) << endl;
  152.  
  153. FreeList f;
  154. cout << "part2: " << f.packFiles(inputs) << endl;
  155. }
  156.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement