Тестовое задание про оптимальный розлив варенья по банкам
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

174 lines
5.0KB

  1. <template>
  2. <div v-if="isProcessing" class="progress">
  3. <progress>Разливаем...</progress>
  4. </div>
  5. <div v-else>
  6. <h2 v-if="result.state == 'error'" class="error">
  7. {{ result.message }}
  8. </h2>
  9. <div v-for="jam in jams" :key="jam.id">
  10. <h3>
  11. Варенье: {{ jam.id }}, всего сварено: {{ jam.vol }} мл,
  12. <span v-if="jam.restVol > 0" class="error"
  13. >осталось не розлито: {{ jam.restVol }} мл</span
  14. >
  15. <span v-else>розлито полностью</span>
  16. </h3>
  17. <ul>
  18. <li v-for="pot in jam.pots" :key="pot.id">
  19. <span
  20. >Банка <b>{{ pot.id }}</b> ({{ pot.vol }} мл)</span
  21. >
  22. &mdash;
  23. <span> залито {{ pot.jamVol }} мл</span>
  24. &mdash;
  25. <span v-if="pot.isFull"> полная</span>
  26. <b v-else class="error">
  27. недолив {{ pot.vol - pot.jamVol }} мл</b
  28. >
  29. </li>
  30. </ul>
  31. </div>
  32. <div v-if="emptyPots.length > 0">
  33. <hr>
  34. <h4>Остались пустые банки:</h4>
  35. <ul>
  36. <li v-for="pot in emptyPots" :key="pot.id">
  37. <b>{{ pot.id }}</b> ({{ pot.vol }} мл)
  38. </li>
  39. </ul>
  40. </div>
  41. </div>
  42. </template>
  43. <script>
  44. import { _ } from "vue-underscore";
  45. export default {
  46. props: ["propPots", "propJams"],
  47. data() {
  48. return {
  49. isProcessing: false,
  50. pots: [],
  51. jams: [],
  52. result: { state: "initial" },
  53. };
  54. },
  55. mounted: function () {
  56. this.isProcessing = true;
  57. this.pots = _.map(this.propPots, _.clone);
  58. this.jams = _.map(this.propJams, _.clone);
  59. this.result = fillPots(this.pots, this.jams);
  60. // console.log("result", this.result);
  61. // console.log("jams", this.jams);
  62. this.isProcessing = false;
  63. },
  64. computed: {
  65. emptyPots: function () {
  66. return this.pots.filter((p) => p.jamVol === 0);
  67. },
  68. },
  69. };
  70. function fillPots(pots, jams) {
  71. prepare(pots, jams);
  72. // Сперва попытаемся разлить варенья по банкам, заполняя их по максимуму
  73. // Приоритет отдаем самым большим банкам, чтобы не лазать в погреб лишний раз
  74. let isDone = false;
  75. let isFoundSolution;
  76. do {
  77. isFoundSolution = false;
  78. for (const jam of jams) {
  79. for (const pot of pots) {
  80. if (!pot.isFilled && pot.vol <= jam.restVol) {
  81. pot.jamId = jam.id;
  82. pot.jamVol = Math.min(pot.vol, jam.restVol);
  83. pot.isFilled = true;
  84. pot.isFull = true;
  85. jam.restVol -= pot.vol;
  86. jam.pots.push(pot);
  87. isFoundSolution = true;
  88. break;
  89. }
  90. }
  91. }
  92. } while (!isDone && isFoundSolution);
  93. // А теперь разливаем остатки по самым маленьким из оставшихся банок
  94. isDone = true;
  95. for (const jam of jams) {
  96. if (jam.restVol > 0) {
  97. for (let i = pots.length - 1; i > 0; i--) {
  98. if (!pots[i].isFilled && pots[i].vol >= jam.restVol) {
  99. pots[i].jamId = jam.id;
  100. pots[i].jamVol = jam.restVol;
  101. pots[i].isFilled = true;
  102. pots[i].isFull = pots[i].vol === jam.restVol;
  103. jam.restVol = 0;
  104. jam.pots.push(pots[i]);
  105. break;
  106. }
  107. }
  108. if (jam.restVol !== 0) {
  109. isDone = false;
  110. }
  111. }
  112. }
  113. if (!isDone) {
  114. return {
  115. state: "error",
  116. message: "Не удалось разлить варенья",
  117. };
  118. }
  119. return { state: "success" };
  120. function prepare(pots, jams) {
  121. pots.sort(sortByVolDesc);
  122. jams.sort(sortByVolDesc);
  123. for (const pot of pots) {
  124. pot.isFilled = false;
  125. pot.isFull = false;
  126. pot.jamId = null;
  127. pot.jamVol = 0;
  128. }
  129. for (const jam of jams) {
  130. jam.restVol = jam.vol;
  131. jam.pots = [];
  132. }
  133. function sortByVolDesc(a, b) {
  134. if (a.vol > b.vol) {
  135. return -1;
  136. } else if (a.vol < b.vol) {
  137. return 1;
  138. }
  139. return 0;
  140. }
  141. }
  142. }
  143. </script>
  144. <style lang="scss" scoped>
  145. .progress {
  146. height: 100%;
  147. display: flex;
  148. align-items: center;
  149. progress {
  150. width: 100%;
  151. }
  152. }
  153. .error {
  154. color: orangered;
  155. }
  156. </style>