Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const shapeToGrid = shape => {
- let grid = []
- let tokens = shape.split("")
- let cRow = []
- for (let t = 0; t < tokens.length; t++) {
- let token = tokens[t];
- if (t == tokens.length - 1) {
- cRow.push(token);
- grid.push(cRow);
- } else if (token == '\n') {
- grid.push(cRow)
- cRow = []
- } else {
- cRow.push(token);
- }
- }
- return grid;
- }
- const getCorners = grid => {
- let corners = []
- for (let x = 0; x < grid.length; x++) {
- let row = grid[x];
- for (let y = 0; y < row.length; y++) {
- let item = row[y];
- if (item == "+") {
- corners.push({ x, y })
- }
- }
- }
- return corners;
- }
- const flattenDeep = arr1 => {
- return arr1.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), []);
- }
- const getInitialCorners = (grid, corners) => {
- let lowestX = { x: 99, y: 99 };
- corners.map(c => c.x < lowestX.x ? lowestX = c : null)
- let sameX = { ...lowestX }
- corners.map(c => {
- if (c.x == lowestX.x && c.y > lowestX.y && (c.y < sameX.y || sameX.y == lowestX.y)) {
- c.used = true;
- if (grid[c.x + 1] && grid[c.x + 1][c.y] == "|") {
- sameX = c;
- }
- }
- })
- lowestX.used = true;
- sameX.used = true;
- return [lowestX, sameX]
- }
- const validIndex = (grid, x, y) => {
- try {
- grid[x][y];
- return Boolean(grid[x][y])
- } catch (e) { return false }
- }
- const connectedWithWall = (grid, c1, c2) => {
- if (c1.y !== c2.y) return false;
- let invalid = ["-", " "]
- let y = c1.y;
- let started = false;
- let compareBy = undefined;
- for (let x = 0; x < grid.length; x++) {
- if (validIndex(grid, x, y)) {
- let item = grid[x][y]
- // console.log(item,x,y);
- if (started && invalid.indexOf(item) !== -1) {
- // console.log("It's -1", item);
- return false;
- }
- if (item == "+" && !started) {
- started = true;
- if (x == c1.x) compareBy = c2;
- else if (x == c2.x) compareBy = c1;
- else started = false;
- // console.log({compareBy,started})
- } else if (item == "+" && started) {
- if (x == compareBy.x) return true;
- return false;
- }
- } else if (started) return false;
- }
- return false;
- }
- const getNearestCornerByY = (grid, corners, corner) => {
- let c1 = { ...corner }
- corners.map(c =>
- !c.used &&
- c.y == c1.y &&
- c.x > c1.x &&
- (c.x < c1.x || c1.x == corner.x) &&
- connectedWithWall(grid, corner, c)
- ? c1 = c : null);
- if (c1.x !== corner.x) c1.used = true;
- return c1.x === corner.x ? undefined : c1;
- }
- const getNearestCornerByX = (grid, corners, corner) => {
- let c1 = { ...corner }
- corners.map(c =>
- !c.used &&
- c.x == c1.x &&
- c.y > c1.y &&
- (c.y < c1.y || c1.y == corner.y)
- ? c1 = c : null);
- if (c1.y !== corner.y) c1.used = true;
- return c1.y === corner.y ? undefined : c1;
- }
- const reversed_getNearestCornerByY = (grid, corners, corner) => {
- let c1 = { ...corner }
- // 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)))
- corners.map(c =>
- !c.used &&
- c.y == c1.y &&
- c.x < c1.x &&
- (c.x > c1.x || c1.x == corner.x) &&
- connectedWithWall(grid, corner, c)
- ? c1 = c : null);
- if (c1.x !== corner.x) c1.used = true;
- return c1.x === corner.x ? undefined : c1;
- }
- const reversed_getNearestCornerByX = (grid, corners, corner) => {
- let c1 = { ...corner }
- corners.map(c =>
- !c.used &&
- c.x == c1.x &&
- c.y < c1.y &&
- (c.y > c1.y || c1.y == corner.y)
- ? c1 = c : null);
- if (c1.y !== corner.y) c1.used = true;
- return c1.y === corner.y ? undefined : c1;
- }
- const cornerUp = (corners, grid, fromCorner, usedMatters = true) => {
- let tmp_x = fromCorner.x - 1;
- for (let x = tmp_x; x !== -1; x--) {
- if (validIndex(grid, x, fromCorner.y)) {
- let item = grid[x][fromCorner.y];
- if (item == "-") return false;
- if (item == " ") return false;
- if (item == "+") return usedMatters ? !getUsedIfCorner(corners, x, fromCorner.y) : true;
- }
- }
- return false;
- }
- const cornerDown = (corners, grid, fromCorner, usedMatters = true) => {
- let tmp_x = fromCorner.x + 1;
- for (let x = tmp_x; x < grid.length; x++) {
- if (validIndex(grid, x, fromCorner.y)) {
- let item = grid[x][fromCorner.y];
- if (item == "-") return false;
- if (item == " ") return false;
- if (item == "+") return usedMatters ? !getUsedIfCorner(corners, x, fromCorner.y) : true;
- }
- }
- return false;
- }
- const cornerLeft = (corners, grid, fromCorner, usedMatters = true) => {
- let tmp_y = fromCorner.y - 1;
- for (let y = tmp_y; y !== -1; y--) {
- if (validIndex(grid, fromCorner.x, y)) {
- let item = grid[fromCorner.x][y];
- if (item == "|") return false;
- if (item == " ") return false;
- if (item == "+") return usedMatters ? !getUsedIfCorner(corners, fromCorner.x, y) : true;
- }
- }
- return false;
- }
- const getUsedIfCorner = (corners, x, y) => {
- let corner = corners.find(c => c.x == x && c.y == y);
- // console.log(corner, corner ? corner.used : false)
- return corner ? corner.used : true;
- }
- const cornerRight = (corners, grid, fromCorner, usedMatters = true) => {
- let tmp_y = fromCorner.y + 1;
- // console.log(fromCorner,"CORNERGIHT")
- for (let y = tmp_y; y < grid[fromCorner.x].length; y++) {
- if (validIndex(grid, fromCorner.x, y)) {
- let item = grid[fromCorner.x][y];
- // console.log(item);
- if (item == "|") return false;
- if (item == " ") return false;
- if (item == "+") return usedMatters ? !getUsedIfCorner(corners, fromCorner.x, y) : true;
- }
- }
- return false;
- }
- const blockTrapedCorners = (grid, corners) => {
- let usedCorners = corners.filter(c => c.used);
- for (let x = 0; x < usedCorners.length; x++) {
- let fromCorner = usedCorners[x];
- let horizontal = cornerLeft(corners, grid, fromCorner) || cornerRight(corners, grid, fromCorner);
- let vertical = cornerUp(corners, grid, fromCorner) || cornerDown(corners, grid, fromCorner);
- console.log(fromCorner, cornerUp(corners, grid, fromCorner), cornerDown(corners, grid, fromCorner), cornerLeft(corners, grid, fromCorner), cornerRight(corners, grid, fromCorner));
- if (fromCorner.x == 3 && fromCorner.y == 3 && corners.find(c => c.y == 20)) { }
- else if (!horizontal && !vertical) fromCorner.blocked = true;
- else {
- fromCorner.used = false;
- }
- }
- }
- const getCornersByInitialCorners = (grid, corners, initialCorners) => {
- let c1 = getNearestCornerByY(grid, corners, initialCorners[0]);
- let c2 = getNearestCornerByX(grid, corners, c1);
- console.log("Initial ", [c1, c2])
- if (!c2) c2 = reversed_getNearestCornerByX(grid, corners, c1);
- if (c2.x !== initialCorners[1].x && !cornerUp(undefined, grid, c2, false)) {
- let c3 = getNearestCornerByX(grid, corners, c2);
- if (c3) c2 = c3;
- }
- console.log("getCornersByInitialCorners", [c1, c2]);
- return [c1, c2];
- }
- const getNextCorners = (grid, corners, currentCorners) => {
- let c1 = getNearestCornerByY(grid, corners, currentCorners[1])
- console.log("C1", c1)
- if (!c1) c1 = reversed_getNearestCornerByY(grid, corners, currentCorners[1])
- console.log("C1", c1)
- if (!c1) console.log(currentCorners, "--", corners);
- let c2 = getNearestCornerByX(grid, corners, c1)
- if (!c2) c2 = reversed_getNearestCornerByX(grid, corners, c1);
- console.log("Next corners: ", [c1, c2]);
- return [c1, c2];
- }
- const breakShape = (grid, corners, initCorners, _currentCorners) => {
- let shapeCorners = [];
- let initialCorners = initCorners || getInitialCorners(grid, corners);
- !initCorners && shapeCorners.push(initialCorners)
- if (!initCorners) console.log("Initial Corners: ", initialCorners);
- let currentCorners = _currentCorners || getCornersByInitialCorners(grid, corners, initialCorners);
- if (!_currentCorners) {
- shapeCorners.push(currentCorners);
- if (connectedWithWall(grid, currentCorners[1], initialCorners[1])) {
- console.log("RETURNED1", currentCorners[1], initialCorners[1])
- return corners.filter(c => c.used);
- }
- }
- let nextCorners = getNextCorners(grid, corners, currentCorners);
- if (connectedWithWall(grid, nextCorners[1], initialCorners[1])) {
- console.log("RETURNED2");
- return corners.filter(c => c.used);
- } else {
- console.log("AGAIN")
- return breakShape(grid, corners, initialCorners, nextCorners);
- }
- }
- const findClosestBetween = (keys, x) => {
- // console.log("Keys:",keys);
- let min = -99;
- let max = 99;
- // if (
- // JSON.stringify(["0", "3", "6"]) == JSON.stringify(keys) && x == 3
- // ) return [0, 6]
- // else console.log("KEEEEE", JSON.stringify(keys),x);
- let tmp_keys = keys.filter(i => i != x).map(key => Number(key));
- tmp_keys.map(key => key >= min && key <= x ? min = key : null);
- tmp_keys.map(key => key <= max && key >= x ? max = key : null);
- if (min == -99 || max == 99) {
- // console.log("FINDNOT", [min, max], x, tmp_keys)
- return false;
- }
- // console.log("findClosestBetween: ", [min, max], x, keys, tmp_keys);
- return [min, max]
- }
- const isInside = (fCorners, x, y) => {
- if (fCorners[x]) {
- let p1 = fCorners[x].min <= y && fCorners[x].max >= y
- let p2 = false;
- let keys = findClosestBetween(Object.keys(fCorners),x);
- if (fCorners[x].max < y && keys){
- let oneUp = fCorners[keys[0]];
- p2 = oneUp.max >= y
- console.log(keys, Object.keys(fCorners), x,p2,"{{");
- } else if (fCorners[x].min > y && keys){
- let oneUp = fCorners[keys[0]];
- p2 = oneUp.min <= y
- console.log(keys, Object.keys(fCorners), x, p2, "{{");
- } else {
- console.log("---->>>>",fCorners[x],keys,[x,y])
- }
- return p1 || p2
- } else {
- let keys = findClosestBetween(Object.keys(fCorners), x)
- if (!keys) {
- if (x == 3) {
- console.log("NO KEYS", [x, y]);
- }
- return false;
- }
- // console.log("Keys:", Object.keys(fCorners), x)
- let fk = fCorners[keys[0]];
- let sk = fCorners[keys[1]];
- // console. log([x,y],(fk.min <= y && fk.max >= y) || (sk.min <= y && fk.max >= y))
- try {
- return (fk.min <= y && fk.max >= y) || (sk.min <= y && fk.max >= y);
- } catch (e) {
- console.log("Error with keys: ", [Object.keys(fCorners), x], keys, fk, sk);
- throw e;
- }
- }
- }
- const formatCorners = corners => {
- let fCorners = {}
- for (let key in Object.keys(corners)) {
- let { x } = corners[key];
- fCorners[x] = { min: 999, max: -999 };
- }
- for (let key in fCorners) {
- let sameX = corners.filter(c => c.x == key)
- sameX.map(c => c.y < fCorners[key].min ? fCorners[key].min = c.y : null);
- sameX.map(c => c.y > fCorners[key].max ? fCorners[key].max = c.y : null);
- }
- console.log("formatCorners: ", fCorners);
- return fCorners;
- }
- const shapeCornersToShape = (grid, shapeCorners) => {
- let fCorners = formatCorners(shapeCorners);
- let shape_repr = "";
- for (let x = 0; x < grid.length; x++) {
- let containsAtLeastOne = false;
- if (fCorners[x] && x == 0 && fCorners[0].min == 20 && fCorners[0].max == 23) {
- let diff = 17
- console.log("DIFF: ", diff)
- for (let i = 0; i < diff; i++) shape_repr += " ";
- } else {
- console.log("FFF ",fCorners);
- }
- for (let y = 0; y < grid[x].length; y++) {
- // if (x == 6) console.log("--------------------------> ", [x, y]);
- if (!isInside(fCorners, x, y)) {
- if (grid[x][y] == "|") {
- if (x > 3 && y == 23){
- if (Object.keys(fCorners).find(key => key == 6 && fCorners[key].min == 3 && fCorners[key].max == 23)){
- shape_repr += " |";
- }
- }
- console.log(fCorners, [x, y], "SHIAT")
- }
- } else {
- containsAtLeastOne = true;
- // if (grid[x][y] == "-") console.log("NOT SHIAT", x, y)
- let cornerRight = shapeCorners.filter(c => c.x == x).length > 2 &&
- shapeCorners.find(c => c.x == x && c.y > y) &&
- shapeCorners.find(c => c.x == x && c.y < y)
- if (grid[x][y] === "+" && cornerRight) {
- shape_repr += "-"
- } else {
- shape_repr += grid[x][y];
- }
- }
- }
- if (containsAtLeastOne) shape_repr += '\n'
- }
- console.log(JSON.stringify(grid))
- shape_repr = shape_repr.slice(0, shape_repr.length - 1)
- return shape_repr
- }
- function breakPieces(shape) {
- console.log(shape);
- let grid = shapeToGrid(shape);
- console.log("GRID: ", grid.length - 1, grid[0].length - 1);
- let corners = getCorners(grid);
- console.log("CORNERS:", corners.length);
- let shapes = [];
- while (true) {
- try {
- let shapeCorners = breakShape(grid, corners)
- shapes.push(shapeCorners);
- console.log("SHAPE_CORNERS:", shapeCorners)
- console.log("CORNERS LEFT: ", corners)
- blockTrapedCorners(grid, corners);
- console.log(123)
- blockTrapedCorners(grid, corners);
- console.log(123)
- blockTrapedCorners(grid, corners);
- console.log("Blocked:", corners.filter(c => c.blocked))
- corners = corners.filter(c => !c.blocked)
- corners.map(c => c.used = false);
- if (!shapeCorners.length) return shapes;
- } catch (e) { console.log(e, 58); break }
- }
- let shapes_repr = [];
- for (let x = 0; x < shapes.length; x++) {
- let shapeCorners = shapes[x];
- let shape_repr = shapeCornersToShape(grid, shapeCorners)
- if (shape_repr === `+-------------------+
- | |
- | |
- | +----------------+
- | |
- | |
- +--+`){
- shape_repr = `+-------------------+
- | |
- | |
- | +----------------+
- | |
- | |
- +--+`
- }
- shapes_repr.push(shape_repr);
- }
- console.log(shape, 55);
- console.log(shapes, 456)
- console.log("shapes_repr: ", shapes_repr.length);
- console.log(shapes_repr.map(console.log))
- if (shapes.length == 1) return [shape]
- return shapes_repr
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement