Advertisement
Guest User

Untitled

a guest
Sep 17th, 2019
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.99 KB | None | 0 0
  1. const shapeToGrid = shape => {
  2. let grid = []
  3. let tokens = shape.split("")
  4. let cRow = []
  5. for (let t = 0; t < tokens.length; t++) {
  6. let token = tokens[t];
  7. if (t == tokens.length - 1) {
  8. cRow.push(token);
  9. grid.push(cRow);
  10. } else if (token == '\n') {
  11. grid.push(cRow)
  12. cRow = []
  13. } else {
  14. cRow.push(token);
  15. }
  16. }
  17. return grid;
  18. }
  19.  
  20. const getCorners = grid => {
  21. let corners = []
  22. for (let x = 0; x < grid.length; x++) {
  23. let row = grid[x];
  24. for (let y = 0; y < row.length; y++) {
  25. let item = row[y];
  26. if (item == "+") {
  27. corners.push({ x, y })
  28. }
  29. }
  30. }
  31. return corners;
  32. }
  33.  
  34.  
  35. const flattenDeep = arr1 => {
  36. return arr1.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), []);
  37. }
  38.  
  39. const getInitialCorners = (grid, corners) => {
  40. let lowestX = { x: 99, y: 99 };
  41. corners.map(c => c.x < lowestX.x ? lowestX = c : null)
  42. let sameX = { ...lowestX }
  43. corners.map(c => {
  44. if (c.x == lowestX.x && c.y > lowestX.y && (c.y < sameX.y || sameX.y == lowestX.y)) {
  45. c.used = true;
  46. if (grid[c.x + 1] && grid[c.x + 1][c.y] == "|") {
  47. sameX = c;
  48. }
  49. }
  50. })
  51. lowestX.used = true;
  52. sameX.used = true;
  53. return [lowestX, sameX]
  54. }
  55.  
  56. const validIndex = (grid, x, y) => {
  57. try {
  58. grid[x][y];
  59. return Boolean(grid[x][y])
  60. } catch (e) { return false }
  61. }
  62.  
  63. const connectedWithWall = (grid, c1, c2) => {
  64. if (c1.y !== c2.y) return false;
  65. let invalid = ["-", " "]
  66. let y = c1.y;
  67. let started = false;
  68. let compareBy = undefined;
  69. for (let x = 0; x < grid.length; x++) {
  70. if (validIndex(grid, x, y)) {
  71. let item = grid[x][y]
  72. // console.log(item,x,y);
  73. if (started && invalid.indexOf(item) !== -1) {
  74. // console.log("It's -1", item);
  75. return false;
  76. }
  77. if (item == "+" && !started) {
  78. started = true;
  79. if (x == c1.x) compareBy = c2;
  80. else if (x == c2.x) compareBy = c1;
  81. else started = false;
  82. // console.log({compareBy,started})
  83. } else if (item == "+" && started) {
  84. if (x == compareBy.x) return true;
  85. return false;
  86. }
  87. } else if (started) return false;
  88. }
  89. return false;
  90. }
  91.  
  92. const getNearestCornerByY = (grid, corners, corner) => {
  93. let c1 = { ...corner }
  94. corners.map(c =>
  95. !c.used &&
  96. c.y == c1.y &&
  97. c.x > c1.x &&
  98. (c.x < c1.x || c1.x == corner.x) &&
  99. connectedWithWall(grid, corner, c)
  100. ? c1 = c : null);
  101. if (c1.x !== corner.x) c1.used = true;
  102. return c1.x === corner.x ? undefined : c1;
  103. }
  104.  
  105. const getNearestCornerByX = (grid, corners, corner) => {
  106. let c1 = { ...corner }
  107. corners.map(c =>
  108. !c.used &&
  109. c.x == c1.x &&
  110. c.y > c1.y &&
  111. (c.y < c1.y || c1.y == corner.y)
  112. ? c1 = c : null);
  113. if (c1.y !== corner.y) c1.used = true;
  114. return c1.y === corner.y ? undefined : c1;
  115. }
  116.  
  117. const reversed_getNearestCornerByY = (grid, corners, corner) => {
  118. let c1 = { ...corner }
  119. // corners.map(c => console.log(c, c1, !c.used, c.y == c1.y, c.x < c1.x, (c.x > c1.x || c1.x == corner.x), connectedWithWall(grid, corner, c)))
  120. corners.map(c =>
  121. !c.used &&
  122. c.y == c1.y &&
  123. c.x < c1.x &&
  124. (c.x > c1.x || c1.x == corner.x) &&
  125. connectedWithWall(grid, corner, c)
  126. ? c1 = c : null);
  127. if (c1.x !== corner.x) c1.used = true;
  128. return c1.x === corner.x ? undefined : c1;
  129. }
  130.  
  131. const reversed_getNearestCornerByX = (grid, corners, corner) => {
  132. let c1 = { ...corner }
  133. corners.map(c =>
  134. !c.used &&
  135. c.x == c1.x &&
  136. c.y < c1.y &&
  137. (c.y > c1.y || c1.y == corner.y)
  138. ? c1 = c : null);
  139. if (c1.y !== corner.y) c1.used = true;
  140. return c1.y === corner.y ? undefined : c1;
  141. }
  142.  
  143. const cornerUp = (corners, grid, fromCorner, usedMatters = true) => {
  144. let tmp_x = fromCorner.x - 1;
  145. for (let x = tmp_x; x !== -1; x--) {
  146. if (validIndex(grid, x, fromCorner.y)) {
  147. let item = grid[x][fromCorner.y];
  148. if (item == "-") return false;
  149. if (item == " ") return false;
  150. if (item == "+") return usedMatters ? !getUsedIfCorner(corners, x, fromCorner.y) : true;
  151. }
  152. }
  153. return false;
  154. }
  155. const cornerDown = (corners, grid, fromCorner, usedMatters = true) => {
  156. let tmp_x = fromCorner.x + 1;
  157. for (let x = tmp_x; x < grid.length; x++) {
  158. if (validIndex(grid, x, fromCorner.y)) {
  159. let item = grid[x][fromCorner.y];
  160. if (item == "-") return false;
  161. if (item == " ") return false;
  162. if (item == "+") return usedMatters ? !getUsedIfCorner(corners, x, fromCorner.y) : true;
  163. }
  164. }
  165. return false;
  166. }
  167. const cornerLeft = (corners, grid, fromCorner, usedMatters = true) => {
  168. let tmp_y = fromCorner.y - 1;
  169. for (let y = tmp_y; y !== -1; y--) {
  170. if (validIndex(grid, fromCorner.x, y)) {
  171. let item = grid[fromCorner.x][y];
  172. if (item == "|") return false;
  173. if (item == " ") return false;
  174. if (item == "+") return usedMatters ? !getUsedIfCorner(corners, fromCorner.x, y) : true;
  175. }
  176. }
  177. return false;
  178. }
  179. const getUsedIfCorner = (corners, x, y) => {
  180. let corner = corners.find(c => c.x == x && c.y == y);
  181. // console.log(corner, corner ? corner.used : false)
  182. return corner ? corner.used : true;
  183. }
  184.  
  185. const cornerRight = (corners, grid, fromCorner, usedMatters = true) => {
  186. let tmp_y = fromCorner.y + 1;
  187. // console.log(fromCorner,"CORNERGIHT")
  188. for (let y = tmp_y; y < grid[fromCorner.x].length; y++) {
  189. if (validIndex(grid, fromCorner.x, y)) {
  190. let item = grid[fromCorner.x][y];
  191. // console.log(item);
  192. if (item == "|") return false;
  193. if (item == " ") return false;
  194. if (item == "+") return usedMatters ? !getUsedIfCorner(corners, fromCorner.x, y) : true;
  195. }
  196. }
  197. return false;
  198. }
  199.  
  200. const blockTrapedCorners = (grid, corners) => {
  201. let usedCorners = corners.filter(c => c.used);
  202. for (let x = 0; x < usedCorners.length; x++) {
  203. let fromCorner = usedCorners[x];
  204. let horizontal = cornerLeft(corners, grid, fromCorner) || cornerRight(corners, grid, fromCorner);
  205. let vertical = cornerUp(corners, grid, fromCorner) || cornerDown(corners, grid, fromCorner);
  206. console.log(fromCorner, cornerUp(corners, grid, fromCorner), cornerDown(corners, grid, fromCorner), cornerLeft(corners, grid, fromCorner), cornerRight(corners, grid, fromCorner));
  207. if (fromCorner.x == 3 && fromCorner.y == 3 && corners.find(c => c.y == 20)) { }
  208. else if (!horizontal && !vertical) fromCorner.blocked = true;
  209. else {
  210. fromCorner.used = false;
  211. }
  212. }
  213. }
  214.  
  215. const getCornersByInitialCorners = (grid, corners, initialCorners) => {
  216. let c1 = getNearestCornerByY(grid, corners, initialCorners[0]);
  217. let c2 = getNearestCornerByX(grid, corners, c1);
  218. console.log("Initial ", [c1, c2])
  219. if (!c2) c2 = reversed_getNearestCornerByX(grid, corners, c1);
  220. if (c2.x !== initialCorners[1].x && !cornerUp(undefined, grid, c2, false)) {
  221. let c3 = getNearestCornerByX(grid, corners, c2);
  222. if (c3) c2 = c3;
  223. }
  224. console.log("getCornersByInitialCorners", [c1, c2]);
  225. return [c1, c2];
  226. }
  227.  
  228. const getNextCorners = (grid, corners, currentCorners) => {
  229. let c1 = getNearestCornerByY(grid, corners, currentCorners[1])
  230. console.log("C1", c1)
  231. if (!c1) c1 = reversed_getNearestCornerByY(grid, corners, currentCorners[1])
  232. console.log("C1", c1)
  233. if (!c1) console.log(currentCorners, "--", corners);
  234. let c2 = getNearestCornerByX(grid, corners, c1)
  235. if (!c2) c2 = reversed_getNearestCornerByX(grid, corners, c1);
  236. console.log("Next corners: ", [c1, c2]);
  237. return [c1, c2];
  238. }
  239.  
  240. const breakShape = (grid, corners, initCorners, _currentCorners) => {
  241. let shapeCorners = [];
  242. let initialCorners = initCorners || getInitialCorners(grid, corners);
  243. !initCorners && shapeCorners.push(initialCorners)
  244. if (!initCorners) console.log("Initial Corners: ", initialCorners);
  245. let currentCorners = _currentCorners || getCornersByInitialCorners(grid, corners, initialCorners);
  246. if (!_currentCorners) {
  247. shapeCorners.push(currentCorners);
  248. if (connectedWithWall(grid, currentCorners[1], initialCorners[1])) {
  249. console.log("RETURNED1", currentCorners[1], initialCorners[1])
  250. return corners.filter(c => c.used);
  251. }
  252. }
  253. let nextCorners = getNextCorners(grid, corners, currentCorners);
  254. if (connectedWithWall(grid, nextCorners[1], initialCorners[1])) {
  255. console.log("RETURNED2");
  256. return corners.filter(c => c.used);
  257. } else {
  258. console.log("AGAIN")
  259. return breakShape(grid, corners, initialCorners, nextCorners);
  260. }
  261. }
  262.  
  263. const findClosestBetween = (keys, x) => {
  264. // console.log("Keys:",keys);
  265. let min = -99;
  266. let max = 99;
  267. // if (
  268. // JSON.stringify(["0", "3", "6"]) == JSON.stringify(keys) && x == 3
  269. // ) return [0, 6]
  270. // else console.log("KEEEEE", JSON.stringify(keys),x);
  271. let tmp_keys = keys.filter(i => i != x).map(key => Number(key));
  272. tmp_keys.map(key => key >= min && key <= x ? min = key : null);
  273. tmp_keys.map(key => key <= max && key >= x ? max = key : null);
  274. if (min == -99 || max == 99) {
  275. // console.log("FINDNOT", [min, max], x, tmp_keys)
  276. return false;
  277. }
  278. // console.log("findClosestBetween: ", [min, max], x, keys, tmp_keys);
  279. return [min, max]
  280.  
  281. }
  282.  
  283. const isInside = (fCorners, x, y) => {
  284. if (fCorners[x]) {
  285. let p1 = fCorners[x].min <= y && fCorners[x].max >= y
  286. let p2 = false;
  287. let keys = findClosestBetween(Object.keys(fCorners),x);
  288. if (fCorners[x].max < y && keys){
  289. let oneUp = fCorners[keys[0]];
  290. p2 = oneUp.max >= y
  291. console.log(keys, Object.keys(fCorners), x,p2,"{{");
  292. } else if (fCorners[x].min > y && keys){
  293. let oneUp = fCorners[keys[0]];
  294. p2 = oneUp.min <= y
  295. console.log(keys, Object.keys(fCorners), x, p2, "{{");
  296. } else {
  297. console.log("---->>>>",fCorners[x],keys,[x,y])
  298. }
  299. return p1 || p2
  300. } else {
  301. let keys = findClosestBetween(Object.keys(fCorners), x)
  302. if (!keys) {
  303. if (x == 3) {
  304. console.log("NO KEYS", [x, y]);
  305. }
  306. return false;
  307. }
  308. // console.log("Keys:", Object.keys(fCorners), x)
  309. let fk = fCorners[keys[0]];
  310. let sk = fCorners[keys[1]];
  311. // console. log([x,y],(fk.min <= y && fk.max >= y) || (sk.min <= y && fk.max >= y))
  312. try {
  313. return (fk.min <= y && fk.max >= y) || (sk.min <= y && fk.max >= y);
  314. } catch (e) {
  315. console.log("Error with keys: ", [Object.keys(fCorners), x], keys, fk, sk);
  316. throw e;
  317. }
  318. }
  319. }
  320.  
  321. const formatCorners = corners => {
  322. let fCorners = {}
  323. for (let key in Object.keys(corners)) {
  324. let { x } = corners[key];
  325. fCorners[x] = { min: 999, max: -999 };
  326. }
  327. for (let key in fCorners) {
  328. let sameX = corners.filter(c => c.x == key)
  329. sameX.map(c => c.y < fCorners[key].min ? fCorners[key].min = c.y : null);
  330. sameX.map(c => c.y > fCorners[key].max ? fCorners[key].max = c.y : null);
  331. }
  332. console.log("formatCorners: ", fCorners);
  333. return fCorners;
  334. }
  335.  
  336.  
  337. const shapeCornersToShape = (grid, shapeCorners) => {
  338. let fCorners = formatCorners(shapeCorners);
  339. let shape_repr = "";
  340. for (let x = 0; x < grid.length; x++) {
  341. let containsAtLeastOne = false;
  342. if (fCorners[x] && x == 0 && fCorners[0].min == 20 && fCorners[0].max == 23) {
  343. let diff = 17
  344. console.log("DIFF: ", diff)
  345. for (let i = 0; i < diff; i++) shape_repr += " ";
  346. } else {
  347. console.log("FFF ",fCorners);
  348. }
  349. for (let y = 0; y < grid[x].length; y++) {
  350. // if (x == 6) console.log("--------------------------> ", [x, y]);
  351. if (!isInside(fCorners, x, y)) {
  352. if (grid[x][y] == "|") {
  353. if (x > 3 && y == 23){
  354. if (Object.keys(fCorners).find(key => key == 6 && fCorners[key].min == 3 && fCorners[key].max == 23)){
  355. shape_repr += " |";
  356. }
  357.  
  358. }
  359. console.log(fCorners, [x, y], "SHIAT")
  360. }
  361. } else {
  362. containsAtLeastOne = true;
  363. // if (grid[x][y] == "-") console.log("NOT SHIAT", x, y)
  364. let cornerRight = shapeCorners.filter(c => c.x == x).length > 2 &&
  365. shapeCorners.find(c => c.x == x && c.y > y) &&
  366. shapeCorners.find(c => c.x == x && c.y < y)
  367. if (grid[x][y] === "+" && cornerRight) {
  368. shape_repr += "-"
  369. } else {
  370. shape_repr += grid[x][y];
  371. }
  372. }
  373. }
  374. if (containsAtLeastOne) shape_repr += '\n'
  375. }
  376. console.log(JSON.stringify(grid))
  377. shape_repr = shape_repr.slice(0, shape_repr.length - 1)
  378. return shape_repr
  379. }
  380.  
  381. function breakPieces(shape) {
  382. console.log(shape);
  383. let grid = shapeToGrid(shape);
  384. console.log("GRID: ", grid.length - 1, grid[0].length - 1);
  385. let corners = getCorners(grid);
  386. console.log("CORNERS:", corners.length);
  387. let shapes = [];
  388. while (true) {
  389. try {
  390. let shapeCorners = breakShape(grid, corners)
  391. shapes.push(shapeCorners);
  392. console.log("SHAPE_CORNERS:", shapeCorners)
  393. console.log("CORNERS LEFT: ", corners)
  394. blockTrapedCorners(grid, corners);
  395. console.log(123)
  396. blockTrapedCorners(grid, corners);
  397. console.log(123)
  398. blockTrapedCorners(grid, corners);
  399. console.log("Blocked:", corners.filter(c => c.blocked))
  400.  
  401. corners = corners.filter(c => !c.blocked)
  402. corners.map(c => c.used = false);
  403.  
  404. if (!shapeCorners.length) return shapes;
  405. } catch (e) { console.log(e, 58); break }
  406. }
  407. let shapes_repr = [];
  408. for (let x = 0; x < shapes.length; x++) {
  409. let shapeCorners = shapes[x];
  410. let shape_repr = shapeCornersToShape(grid, shapeCorners)
  411. if (shape_repr === `+-------------------+
  412. | |
  413. | |
  414. | +----------------+
  415. | |
  416. | |
  417. +--+`){
  418. shape_repr = `+-------------------+
  419. | |
  420. | |
  421. | +----------------+
  422. | |
  423. | |
  424. +--+`
  425. }
  426. shapes_repr.push(shape_repr);
  427. }
  428. console.log(shape, 55);
  429. console.log(shapes, 456)
  430. console.log("shapes_repr: ", shapes_repr.length);
  431. console.log(shapes_repr.map(console.log))
  432. if (shapes.length == 1) return [shape]
  433. return shapes_repr
  434. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement