Advertisement
Guest User

Untitled

a guest
Feb 21st, 2019
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.21 KB | None | 0 0
  1. var fs = require('fs');
  2. var createInterface = require('readline').createInterface;
  3. var createReadStream = fs.createReadStream;
  4. var EOL = require('os').EOL;
  5. var slices = [];
  6. var heatMatrix = [];
  7.  
  8. var files = [
  9. 'example',
  10. 'small',
  11. 'medium',
  12. 'big',
  13. ];
  14.  
  15. var rectangularPlots = [
  16. [2, 3],
  17. [3, 2],
  18. [5, 1],
  19. [1, 5],
  20. ];
  21.  
  22. var file = files[1];
  23.  
  24. var lineReader = createInterface({
  25. input: createReadStream('in/' + file + '.in'),
  26. });
  27.  
  28. class Pizza {
  29. constructor() {
  30. this.rows = 0;
  31. this.cols = 0;
  32. this.l = 0;
  33. this.max = 0;
  34. this.cells = [];
  35. this.all = [];
  36. this.slices = [];
  37. }
  38.  
  39. log() {
  40. console.log(EOL);
  41. for (var y = 0; y < this.rows; y += 1) {
  42. for (var x = 0; x < this.cols; x += 1) {
  43. process.stdout.write(this.getCell(x, y).busy ? 'X' : 'O');
  44. }
  45. console.log(EOL);
  46. }
  47. }
  48.  
  49. getCell(x, y) {
  50. if (x < 0 || y < 0 || x >= this.cols || y >= this.rows) return null;
  51. return this.cells[y][x];
  52. }
  53.  
  54. takeSlice(cell, w, h) {
  55. const cells = [];
  56. const ingredients = { M: 0, T: 0 };
  57. for (var x = cell.x; x < cell.x + w; x += 1) {
  58. for (var y = cell.y; y < cell.y + h; y += 1) {
  59. const cell = this.getCell(x, y);
  60. if (!cell || cell.busy) return null;
  61. ingredients[cell.t] += 1;
  62. cells.push(cell);
  63. }
  64. }
  65. if (ingredients.M < this.l || ingredients.T < this.l) return null;
  66. cells.forEach((c) => { c.busy = true; });
  67. this.slices.push({
  68. cells,
  69. out: [cell.y, cell.x, cell.y + h - 1, cell.x + w - 1],
  70. });
  71. }
  72. }
  73.  
  74. var pizza = new Pizza();
  75.  
  76. var count = 0;
  77.  
  78. function readDescLine(line) {
  79. var values = line.split(' ');
  80. pizza.rows = parseInt(values[0], 10);
  81. pizza.cols = parseInt(values[1], 10);
  82. pizza.l = parseInt(values[2], 10);
  83. pizza.max = parseInt(values[3], 10);
  84. }
  85.  
  86. class Cell {
  87. constructor(x, y, t) {
  88. this.x = x;
  89. this.y = y;
  90. this.t = t;
  91. this.busy = false;
  92. }
  93. }
  94.  
  95. function readPizzaLine(line) {
  96. var pieces = line.split('');
  97. pizza.cells.push(pieces.map((piece, x) => {
  98. const cell = new Cell(x, pizza.cells.length, piece);
  99. pizza.all.push(cell);
  100. return cell;
  101. }));
  102. }
  103.  
  104. function divisors(n) {
  105. var c = [];
  106. var map = {};
  107. for (var i = 1; i < n; i++) {
  108. if (n % i === 0) {
  109. var f = i;
  110. var s = n / i;
  111. if (!map[`${f}-${s}`]) {
  112. map[`${f}-${s}`] = true;
  113. c.push([f, s]);
  114. }
  115. if (!map[`${s}-${f}`]) {
  116. map[`${s}-${f}`] = true;
  117. c.push([s, f]);
  118. }
  119. }
  120. }
  121. return c;
  122. }
  123.  
  124. function shuffle(a) {
  125. for (let i = a.length - 1; i > 0; i--) {
  126. const j = Math.floor(Math.random() * (i + 1));
  127. [a[i], a[j]] = [a[j], a[i]];
  128. }
  129. return a;
  130. }
  131.  
  132. function makeCountArray(type, lessIngridient) {
  133. var array = [];
  134. var count = 0;
  135. if (type === 'r') {
  136. for (var i = 0; i < pizza.rows; i++) {
  137. for (var j = 0; j < pizza.cols; j++) {
  138. if (pizza.cells[i][j].t === lessIngridient) {
  139. count++;
  140. }
  141. }
  142. array[i] = count;
  143. count = 0;
  144. }
  145. }
  146. else if (type === 'c') {
  147. for (var i = 0; i < pizza.cols; i++) {
  148. for (var j = 0; j < pizza.rows; j++) {
  149. if (pizza.cells[j][i].t === lessIngridient) {
  150. count++;
  151. }
  152. }
  153. array[i] = count;
  154. count = 0;
  155. }
  156. }
  157. return array;
  158. }
  159.  
  160. function getValue(x, array) {
  161. if (x >= 0 && x < array.length)
  162. return array[x];
  163. else return 0;
  164. }
  165. function calculateHeatMatrix(columnArray, rowArray) {
  166. for (var i = 0; i < rowArray.length; i++) {
  167. heatMatrix[i] = [];
  168. for (var j = 0; j < columnArray.length; j++) {
  169. heatMatrix[i][j] = rowArray[i] + getValue(1 + i, rowArray) + getValue(i - 1, rowArray) + columnArray[j] + getValue(j + 1, columnArray) + getValue(j - 1, columnArray);
  170. }
  171. }
  172. }
  173.  
  174. function findLowest() {
  175. var lowestValue = 999999;
  176. var xIndex = 0;
  177. var yIndex = 0;
  178. for (var i = 0; i < heatMatrix.length; i++) {
  179. for (var j = 0; j < heatMatrix[i].length; j++) {
  180. if (heatMatrix[i][j] != -1 && lowestValue > heatMatrix[i][j]) {
  181. lowestValue = heatMatrix[i][j];
  182. xIndex = i;
  183. yIndex = j;
  184. }
  185. }
  186. }
  187. return [xIndex, yIndex];
  188. }
  189. function findBiggest(starti, imax, startj, jmax) {
  190. var bigestValue = -1;
  191. var xIndex = 0;
  192. var yIndex = 0;
  193. for (var i = starti; i <= imax; i++) {
  194. for (var j = startj; j <= jmax; j++) {
  195. if (heatMatrix[i][j] != -1 && bigestValue <= heatMatrix[i][j]) {
  196. bigestValue = heatMatrix[i][j];
  197. xIndex = i;
  198. yIndex = j;
  199. }
  200. }
  201. }
  202. return [xIndex, yIndex];
  203. }
  204. class Slice {
  205. constructor(x, y, endx, endy) {
  206. this.startx = x;
  207. this.starty = y;
  208. this.endx = endx;
  209. this.endy = endy;
  210. this.busy = true;
  211. }
  212. log() {
  213. [this.startx, this.starty, this.endx, this.endy];
  214. }
  215. }
  216. function findBest(i, imax, j, jmax, x, y, oldSlice) {
  217. let [sliceEndX, sliceEndY] = findBiggest(i, imax, j, jmax);
  218. var slice = new Slice(x, y, sliceEndX, sliceEndY);
  219.  
  220. if(oldSlice != null && slice.startx === oldSlice.startx && slice.starty === oldSlice.starty &&slice.endx === oldSlice.endx &&slice.endy === oldSlice.endy)
  221. {
  222. let [lowestX, lowestY] = findLowest();
  223. additionalSlice = getRectangualar(lowestX, lowestY, rectangularPlots[3]);
  224. // if(slice.startx === additionalSlice.startx && slice.starty === additionalSlice.starty &&slice.endx === additionalSlice.endx &&slice.endy === additionalSlice.endy)
  225. {
  226. console.log("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
  227. return null;
  228. }
  229. }
  230. //console.log("slice:" + x, y, sliceEndX, sliceEndY);
  231. if (x >= sliceEndX && y >= sliceEndY) {
  232. if (isSliceGood(sliceEndX, sliceEndY, x, y)) {
  233. console.log("good");
  234. markHeatMapWithslices(sliceEndX, sliceEndY, x, y);
  235. }
  236. else {
  237. heatMatrix[sliceEndX][sliceEndY] = 0;
  238. slice = findBest(i, imax, j, jmax, x, y, slice);
  239. }
  240. }
  241. else if (x <= sliceEndX && y <= sliceEndY) {
  242. if (isSliceGood(x, y, sliceEndX, sliceEndY)) {
  243. console.log("good");
  244. markHeatMapWithslices(x, y, sliceEndX, sliceEndY);
  245. }
  246. else {
  247. heatMatrix[sliceEndX][sliceEndY] = 0;
  248. slice = findBest( i, imax, j, jmax,x, y, slice);
  249. }
  250. }
  251. else if (x >= sliceEndX && y <= sliceEndY) {
  252. if (isSliceGood(sliceEndX, y, x, sliceEndY)) {
  253. console.log("good");
  254. markHeatMapWithslices(sliceEndX, y, x, sliceEndY);
  255. }
  256. else {
  257. heatMatrix[sliceEndX][sliceEndY] = 0;
  258. slice = findBest( i, imax, j, jmax,x, y, slice);
  259. }
  260. }
  261. else if (x <= sliceEndX && y >= sliceEndY) {
  262. if (isSliceGood(x, sliceEndY, sliceEndX, y)) {
  263. console.log("good");
  264. markHeatMapWithslices(x, sliceEndY, sliceEndX, y);
  265. }
  266. else {
  267. heatMatrix[sliceEndX][sliceEndY] = 0;
  268. slice = findBest( i, imax, j, jmax,x, y, slice);
  269. }
  270. }
  271. return slice;
  272. }
  273. function getRectangualar(x, y, plot) {
  274. var maxX = plot[0] - 1;
  275. var maxY = plot[1] - 1;
  276. var sum = 0;
  277.  
  278. // var rectangularCells = [];
  279. // rectangularCells.push(new Coordinate(x, y));
  280.  
  281. var i = x - maxX > 0 ? x - maxX : 0;
  282. var imax = x + maxX < pizza.rows ? x + maxX : pizza.rows - 1;
  283. var j = y - maxY > 0 ? y - maxY : 0;
  284. var jmax = y + maxY < pizza.cols ? y + maxY : pizza.cols - 1;
  285. console.log(i, imax, j, jmax);
  286.  
  287. return findBest(i, imax, j, jmax, x, y, null);
  288.  
  289. }
  290. function markHeatMapWithslices(startX, startY, sliceEndX, sliceEndY) {
  291. for (var i = startX; i <= sliceEndX; i++) {
  292. for (var j = startY; j <= sliceEndY; j++) {
  293. heatMatrix[i][j] = -1;
  294. }
  295. }
  296. }
  297.  
  298. function isSliceGood(startX, startY, sliceEndX, sliceEndY) {
  299. var countT = 0;
  300. var countM = 0;
  301. for (var i = startX; i <= sliceEndX; i++) {
  302. for (var j = startY; j <= sliceEndY; j++) {
  303. if(heatMatrix[i][j] === 1)
  304. return false;
  305. if (pizza.cells[i][j].t === 'T') {
  306. countT++;
  307. }
  308. else if (pizza.cells[i][j].t === 'M') {
  309. countM++;
  310. }
  311. }
  312. }
  313. if (countT < pizza.l || countM < pizza.l)
  314. return false;
  315. else return true;
  316. }
  317. function start() {
  318.  
  319. var mushrooms = pizza.all.filter(c => c.t === 'M').length;
  320. var tomatoes = pizza.all.length - mushrooms;
  321. const lessIngridient = mushrooms >= tomatoes ? 'T' : 'M';
  322. console.log('mushrooms/tomatoes', mushrooms, tomatoes);
  323.  
  324. let rowCountArray = makeCountArray('r', lessIngridient);
  325. let columnCountArray = makeCountArray('c', lessIngridient);
  326.  
  327. calculateHeatMatrix(columnCountArray, rowCountArray);
  328.  
  329. console.log(heatMatrix);
  330.  
  331. for (var i = 0; i < 8; i++) {
  332. let j = 0;
  333. let [lowestX, lowestY] = findLowest();
  334. console.log(lowestX, lowestY);
  335. var slice = getRectangualar(lowestX, lowestY, rectangularPlots[2]);
  336. if(slice != null)
  337. {
  338. slices[i] = slice
  339. }
  340. console.log(heatMatrix);
  341. }
  342. /*
  343. [lowestX, lowestY] = findLowest(heatMatrix);
  344. [heatMatrix, slices[1]] = getRectangualar(heatMatrix, lowestX, lowestY, rectangularPlots[1]);
  345. console.log(heatMatrix);
  346. [lowestX, lowestY] = findLowest(heatMatrix);
  347. [heatMatrix, slices[2]] = getRectangualar(heatMatrix, lowestX, lowestY, rectangularPlots[1]);
  348. console.log(heatMatrix);
  349. */
  350. /* var divs = [];
  351. for (var i = pizza.max; i >= pizza.l*2; i--) {
  352. divs = divs.concat(divisors(i));
  353. }
  354.  
  355. pizza.all.forEach((cell) => {
  356. divs.forEach((d) => {
  357. var w = d[0];
  358. var h = d[1];
  359. pizza.takeSlice(cell, w, h);
  360. })
  361. });
  362. */
  363. points();
  364. write();
  365. }
  366.  
  367. function points() {
  368. console.log(slices.length);
  369. for (var i = 0; i < slices.length; i++) {
  370. console.log(slices[i].startx, slices[i].starty, slices[i].endx, slices[i].endy);
  371. }
  372. //console.log('points', pizza.all.filter(c => c.busy).length, pizza.all.length);
  373. }
  374.  
  375. function write() {
  376. var out = `${slices.length}`;
  377. slices.forEach(slice => {
  378. out = `${out}
  379. ${slice.startx} ${slice.starty} ${slice.endx} ${slice.endy}`;
  380. });
  381. fs.writeFile(`out/${file}.out`, out, () => { });
  382. }
  383.  
  384. lineReader.on('line', function (line) {
  385. if (count === 0) readDescLine(line);
  386. else readPizzaLine(line);
  387. count++;
  388. if (count === 1 + pizza.rows) start();
  389. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement