Guest User

Untitled

a guest
Jun 22nd, 2018
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.39 KB | None | 0 0
  1. // Stringify a piece of cake
  2. function stringify(cake) {
  3. return cake.map(e => e.join('')).join('\n')
  4. }
  5.  
  6. // Check if this cut is a valid slice
  7. function isAValidSlice(cake, x, y, width, height) {
  8. // Is not valid if we exceed in width or height
  9. if ((x + width) > cake[0].length) return false;
  10. if ((y + height) > cake.length) return false;
  11.  
  12. console.log('Trying with', x, y, width, height);
  13.  
  14. // Do a real slice and convert it to a string
  15. const slice = cake.slice(y, y + height).map(e => e.slice(x, x + width));
  16. const slice_str = stringify(slice);
  17. console.log('The slice is ');
  18. console.log(slice_str);
  19.  
  20. // If this string has X, we cutted an already cutted cake
  21. if (slice_str.match(/x/)) {
  22. console.log('Already cut');
  23. return false;
  24. }
  25.  
  26. // If this string has exactly one O, then this is valid slice!
  27. const numberOfO = (slice_str.match(/o/g) || []).length;
  28. if (numberOfO != 1) {
  29. console.log('Invalid', numberOfO);
  30. return false;
  31. }
  32.  
  33. // And return this slice to append to the list of slices
  34. return slice_str;
  35. }
  36.  
  37. // Do a cut by inserting X when cake is cutted
  38. function doCut(cake, x, y, width, height) {
  39. console.log('Cutting', x, y, width, height);
  40. for (let i = y; i < (y + height); i++) {
  41. for (let j = x; j < (x + width); j++) {
  42. cake[i][j] = 'x';
  43. }
  44. }
  45. return cake;
  46. }
  47.  
  48. // Simply find a top left corner where cake is not cutted
  49. function findFirstTopLeftCorner(cake) {
  50. for (let i = 0; i < cake.length; i++) {
  51. for (let j = 0; j < cake[i].length; j++) {
  52. if (cake[i][j] !== 'x') {
  53. return [i,j];
  54. }
  55. }
  56. }
  57. }
  58.  
  59. function run(cake, size, slices) {
  60. console.log('RUN', slices);
  61. console.log(stringify(cake));
  62.  
  63. // First of all, find a top-left corner
  64. const corner = findFirstTopLeftCorner(cake);
  65. console.log('Corner', corner);
  66. // If a corner is not found, the cake is cutted completely
  67. if (null == corner) return slices;
  68.  
  69. let x = corner[1];
  70. let y = corner[0];
  71.  
  72. // Otherwise, cycle over all possibile combination of how we can write SIZE = WIDTH * HEIGHT,
  73. // but start when Width is the maximum value (for the rules of the Kata)
  74. for (let width = size; width >= 1; width--) {
  75. for (let height = 1; height <= size; height++) {
  76. if ((height * width) !== size) continue;
  77.  
  78. // If this is not valid slice, interrupt this cycle
  79. const slice = isAValidSlice(cake, x, y, width, height);
  80. if (!slice) continue;
  81.  
  82. // Instead if a valid slice append to the slices
  83. const newSlices = Object.assign([], slices);
  84. newSlices.push(slice);
  85.  
  86. // And cut the cake (before making a copy)
  87. let newCake = doCut(JSON.parse(JSON.stringify(cake)), x, y, width, height);
  88.  
  89. // And run the algorithm again
  90. let r = run(newCake, size, newSlices);
  91.  
  92. // If the result slice are not empty, we found a result
  93. if (r.length) {
  94. console.log('Found', r);
  95. return r;
  96. }
  97. }
  98. }
  99.  
  100. // Otherwise, there's no way to solve this problem bro.
  101. console.log('Not found');
  102. return [];
  103. }
  104.  
  105. function cut(cake) {
  106. // How many O
  107. const num = cake.match(/o/g).length;
  108. // Convert to array
  109. const cake_array = cake.split('\n').map(e => e.split(''));
  110.  
  111. // Calculate rows and cols
  112. const rows = cake_array.length;
  113. const cols = cake_array[0].length;
  114. // And then determine the size
  115. const size = (rows * cols) / num;
  116.  
  117. // And run the algorithm
  118. return run(cake_array, size, []);
  119. }
Add Comment
Please, Sign In to add comment