Advertisement
finalmail

Untitled

Oct 25th, 2019
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const readline = require("readline").createInterface({
  2.   input: process.stdin,
  3.   output: process.stdout
  4. });
  5.  
  6. let N = 8;
  7. let boardSize = 3;
  8. let finalBoard = [];
  9. let initialBoard = [];
  10.  
  11. const checkIfCompleted = (initial, final) => {
  12.   for (let i = 0; i < boardSize; i++) {
  13.     for (let j = 0; j < boardSize; j++) {
  14.       if (initial[i][j] !== final[i][j]) {
  15.         return false;
  16.       }
  17.     }
  18.   }
  19.  
  20.   return true;
  21. };
  22.  
  23. const cellDistance = (board, row, col) => {
  24.   const boardValue = board[row][col];
  25.   const { row: wantedRow, col: wantedCol } = findCoordinatesOfValue(
  26.     finalBoard,
  27.     boardValue
  28.   );
  29.  
  30.   return boardValue === 0
  31.     ? 0
  32.     : Math.abs(row - wantedRow) + Math.abs(col - wantedCol);
  33. };
  34.  
  35. const getHeuristicScore = board => {
  36.   let sum = 0;
  37.  
  38.   for (let i = 0; i < boardSize; i++) {
  39.     for (let j = 0; j < boardSize; j++) {
  40.       sum += cellDistance(board, i, j);
  41.     }
  42.   }
  43.  
  44.   return sum;
  45. };
  46.  
  47. const findCoordinatesOfValue = (board, value) => {
  48.   for (let i = 0; i < boardSize; i++) {
  49.     for (let j = 0; j < boardSize; j++) {
  50.       if (board[i][j] === value) {
  51.         return {
  52.           row: i,
  53.           col: j
  54.         };
  55.       }
  56.     }
  57.   }
  58. };
  59.  
  60. const swapPositions = (from, board) => to => {
  61.   const newBoard = board.map(x => x.slice());
  62.  
  63.   const temp = newBoard[from.row][from.col];
  64.   newBoard[from.row][from.col] = newBoard[to.row][to.col];
  65.   newBoard[to.row][to.col] = temp;
  66.  
  67.   return newBoard;
  68. };
  69.  
  70. const getChildren = boardState => {
  71.   const zeroCoordinates = findCoordinatesOfValue(boardState, 0);
  72.   const swapPositionsWithZero = swapPositions(zeroCoordinates, boardState);
  73.   const { row, col } = zeroCoordinates;
  74.  
  75.   let children = [];
  76.   if (row !== 0) {
  77.     const board = swapPositionsWithZero({ row: row - 1, col });
  78.     children.push({ board, direction: "down" });
  79.   }
  80.   if (row !== boardSize - 1) {
  81.     const board = swapPositionsWithZero({ row: row + 1, col });
  82.     children.push({ board, direction: "up" });
  83.   }
  84.   if (col !== 0) {
  85.     const board = swapPositionsWithZero({ row, col: col - 1 });
  86.     children.push({ board, direction: "right" });
  87.   }
  88.   if (col !== boardSize - 1) {
  89.     const board = swapPositionsWithZero({ row, col: col + 1 });
  90.     children.push({ board, direction: "left" });
  91.   }
  92.  
  93.   return children;
  94. };
  95.  
  96. const DFS = (state, g, threshold, stack) => {
  97.   const h = getHeuristicScore(state);
  98.   const f = g + h;
  99.  
  100.   if (f > threshold) {
  101.     return f;
  102.   }
  103.  
  104.   if (checkIfCompleted(state, finalBoard)) {
  105.     return -1;
  106.   }
  107.  
  108.   const children = getChildren(state);
  109.   let minF = Infinity;
  110.  
  111.   for (child of children) {
  112.     stack.push(child.direction);
  113.  
  114.     const childF = DFS(child.board, g + 1, threshold, stack);
  115.  
  116.     if (childF === -1) {
  117.       return -1;
  118.     }
  119.  
  120.     if (childF < minF) {
  121.       minF = childF;
  122.     }
  123.     stack.pop();
  124.   }
  125.  
  126.   return minF;
  127. };
  128.  
  129. const generateFinalBoard = (boardSize, zeroIndex) => {
  130.   const index = zeroIndex === -1 ? boardSize * boardSize - 1 : zeroIndex;
  131.   let nextValue = 1;
  132.  
  133.   const finalBoard = [];
  134.  
  135.   for (let i = 0; i < boardSize; i++) {
  136.     finalBoard[i] = [];
  137.     for (let j = 0; j < boardSize; j++) {
  138.       finalBoard[i][j] = i * boardSize + j === index ? 0 : nextValue++;
  139.     }
  140.   }
  141.  
  142.   return finalBoard;
  143. };
  144.  
  145. const main = () => {
  146.   let threshold = getHeuristicScore(initialBoard);
  147.  
  148.   while (true) {
  149.     const stack = [];
  150.  
  151.     const newThreshold = DFS(initialBoard, 0, threshold, stack);
  152.  
  153.     if (newThreshold === -1) {
  154.       console.log(stack.length);
  155.       stack.forEach(direction => console.log(direction));
  156.       return;
  157.     }
  158.  
  159.     threshold = newThreshold;
  160.   }
  161. };
  162.  
  163. let linesRead = 0;
  164.  
  165. readline.on("line", line => {
  166.   linesRead += 1;
  167.  
  168.   if (linesRead === 1) {
  169.     N = Number(line);
  170.     boardSize = Math.sqrt(N + 1);
  171.   } else if (linesRead === 2) {
  172.     const zeroIndex = Number(line);
  173.     finalBoard = generateFinalBoard(boardSize, zeroIndex);
  174.   } else {
  175.     const nextBoardLine = line.split(" ").map(Number);
  176.     initialBoard[linesRead - 3] = nextBoardLine;
  177.   }
  178.  
  179.   if (linesRead === boardSize + 2) {
  180.     main();
  181.     readline.close();
  182.   }
  183. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement