Finding shortest path in two dimensional array (Javascript) Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!Finding shortest path in 2d arrayHow can I merge properties of two JavaScript objects dynamically?How do I check if an array includes an object in JavaScript?Compare two dates with JavaScriptHow to insert an item into an array at a specific index (JavaScript)?How can I create a two dimensional array in JavaScript?How do I empty an array in JavaScript?Loop through an array in JavaScriptEasy interview question got harder: given numbers 1..100, find the missing number(s)How do I remove a particular element from an array in JavaScript?For-each over an array in JavaScript?

Noise in Eigenvalues plot

How can I list files in reverse time order by a command and pass them as arguments to another command?

How does TikZ render an arc?

Does the main washing effect of soap come from foam?

Table formatting with tabularx?

Any stored/leased 737s that could substitute for grounded MAXs?

Did pre-Columbian Americans know the spherical shape of the Earth?

draw a pulley system

How does the body cool itself in a stillsuit?

Was the pager message from Nick Fury to Captain Marvel unnecessary?

Why do the Z-fighters hide their power?

3D Masyu - A Die

An isoperimetric-type inequality inside a cube

Are there any irrational/transcendental numbers for which the distribution of decimal digits is not uniform?

Where and when has Thucydides been studied?

why doesn't university give past final exams' answers

How to make triangles with rounded sides and corners? (squircle with 3 sides)

Marquee sign letters

What does Sonny Burch mean by, "S.H.I.E.L.D. and HYDRA don't even exist anymore"?

Why not use the yoke to control yaw, as well as pitch and roll?

Problem with display of presentation

Can I cut the hair of a conjured korred with a blade made of precious material to harvest that material from the korred?

Improvising over quartal voicings

How to achieve cat-like agility?



Finding shortest path in two dimensional array (Javascript)



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!Finding shortest path in 2d arrayHow can I merge properties of two JavaScript objects dynamically?How do I check if an array includes an object in JavaScript?Compare two dates with JavaScriptHow to insert an item into an array at a specific index (JavaScript)?How can I create a two dimensional array in JavaScript?How do I empty an array in JavaScript?Loop through an array in JavaScriptEasy interview question got harder: given numbers 1..100, find the missing number(s)How do I remove a particular element from an array in JavaScript?For-each over an array in JavaScript?



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








3















I am trying to implement an algorithm, that finds the shortest path in the following two dimensional array (from the top left corner, to the right bottom corner):



 [ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ]


The rules are, that the path must alternate between A's and B's.



The output must be a number specifying the smallest number of steps it will take to go through the array. (In the example the expected output is 13)



Does anyone know of a simple Graph implementation that can help me solve this problem?










share|improve this question
























  • Shortest path from and to?

    – nick zoum
    Mar 19 at 11:01











  • Whats is each value in the Array? Can you provide an sample output you are expecting from the provided data.

    – Dipak
    Mar 19 at 11:01











  • Can you give more inputs to your problem statement

    – Kartikeya Sharma
    Mar 19 at 11:01











  • Sorry, it is from the top left corner to the right bottom corner

    – Boris Grunwald
    Mar 19 at 11:02











  • I've updated the question, please let me know if you need more information

    – Boris Grunwald
    Mar 19 at 11:04

















3















I am trying to implement an algorithm, that finds the shortest path in the following two dimensional array (from the top left corner, to the right bottom corner):



 [ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ]


The rules are, that the path must alternate between A's and B's.



The output must be a number specifying the smallest number of steps it will take to go through the array. (In the example the expected output is 13)



Does anyone know of a simple Graph implementation that can help me solve this problem?










share|improve this question
























  • Shortest path from and to?

    – nick zoum
    Mar 19 at 11:01











  • Whats is each value in the Array? Can you provide an sample output you are expecting from the provided data.

    – Dipak
    Mar 19 at 11:01











  • Can you give more inputs to your problem statement

    – Kartikeya Sharma
    Mar 19 at 11:01











  • Sorry, it is from the top left corner to the right bottom corner

    – Boris Grunwald
    Mar 19 at 11:02











  • I've updated the question, please let me know if you need more information

    – Boris Grunwald
    Mar 19 at 11:04













3












3








3


1






I am trying to implement an algorithm, that finds the shortest path in the following two dimensional array (from the top left corner, to the right bottom corner):



 [ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ]


The rules are, that the path must alternate between A's and B's.



The output must be a number specifying the smallest number of steps it will take to go through the array. (In the example the expected output is 13)



Does anyone know of a simple Graph implementation that can help me solve this problem?










share|improve this question
















I am trying to implement an algorithm, that finds the shortest path in the following two dimensional array (from the top left corner, to the right bottom corner):



 [ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ]


The rules are, that the path must alternate between A's and B's.



The output must be a number specifying the smallest number of steps it will take to go through the array. (In the example the expected output is 13)



Does anyone know of a simple Graph implementation that can help me solve this problem?







javascript algorithm graph-theory






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 19 at 11:09







Boris Grunwald

















asked Mar 19 at 10:59









Boris GrunwaldBoris Grunwald

496412




496412












  • Shortest path from and to?

    – nick zoum
    Mar 19 at 11:01











  • Whats is each value in the Array? Can you provide an sample output you are expecting from the provided data.

    – Dipak
    Mar 19 at 11:01











  • Can you give more inputs to your problem statement

    – Kartikeya Sharma
    Mar 19 at 11:01











  • Sorry, it is from the top left corner to the right bottom corner

    – Boris Grunwald
    Mar 19 at 11:02











  • I've updated the question, please let me know if you need more information

    – Boris Grunwald
    Mar 19 at 11:04

















  • Shortest path from and to?

    – nick zoum
    Mar 19 at 11:01











  • Whats is each value in the Array? Can you provide an sample output you are expecting from the provided data.

    – Dipak
    Mar 19 at 11:01











  • Can you give more inputs to your problem statement

    – Kartikeya Sharma
    Mar 19 at 11:01











  • Sorry, it is from the top left corner to the right bottom corner

    – Boris Grunwald
    Mar 19 at 11:02











  • I've updated the question, please let me know if you need more information

    – Boris Grunwald
    Mar 19 at 11:04
















Shortest path from and to?

– nick zoum
Mar 19 at 11:01





Shortest path from and to?

– nick zoum
Mar 19 at 11:01













Whats is each value in the Array? Can you provide an sample output you are expecting from the provided data.

– Dipak
Mar 19 at 11:01





Whats is each value in the Array? Can you provide an sample output you are expecting from the provided data.

– Dipak
Mar 19 at 11:01













Can you give more inputs to your problem statement

– Kartikeya Sharma
Mar 19 at 11:01





Can you give more inputs to your problem statement

– Kartikeya Sharma
Mar 19 at 11:01













Sorry, it is from the top left corner to the right bottom corner

– Boris Grunwald
Mar 19 at 11:02





Sorry, it is from the top left corner to the right bottom corner

– Boris Grunwald
Mar 19 at 11:02













I've updated the question, please let me know if you need more information

– Boris Grunwald
Mar 19 at 11:04





I've updated the question, please let me know if you need more information

– Boris Grunwald
Mar 19 at 11:04












4 Answers
4






active

oldest

votes


















0














Since it represents an undirected unweighted graph, you can simply use BFS:






const m =
[ [ 'A', 'A', 'A', 'B', 'A' ],
[ 'B', 'B', 'B', 'B', 'B' ],
[ 'A', 'B', 'A', 'A', 'A' ],
[ 'A', 'B', 'B', 'B', 'B' ],
[ 'A', 'A', 'A', 'A', 'A' ] ]

let successors = (root, m) =>
let connectedCells = [
[root[0] - 1, root[1]],
[root[0], root[1] - 1],
[root[0] + 1, root[1]],
[root[0], root[1] + 1]
]

const validCells = connectedCells.filter(
(cell) => (
cell[0] >= 0 && cell[0] < m.length
&& cell[1] >= 0 && cell[1] < m[0].length)
)

const successors = validCells.filter(
(cell) => (m[cell[0]][cell[1]] !== m[root[0]][root[1]])
)

return successors


const buildPath = (traversalTree, to) =>
let path = [to]
let parent = traversalTree[to]
while (parent)
path.push(parent)
parent = traversalTree[parent]

return path.reverse()


const bfs = (from, to) =>
let traversalTree = []
let visited = new Set
let queue = []
queue.push(from)

while (queue.length)
let subtreeRoot = queue.shift()
visited.add(subtreeRoot.toString())

if (subtreeRoot.toString() == to.toString()) return buildPath(traversalTree, to)

for (child of successors(subtreeRoot, m))
if (!visited.has(child.toString()))
traversalTree[child] = subtreeRoot
queue.push(child)






console.log(bfs([0,0], [4,4]).length) // => 13








share|improve this answer






























    2














    Well you can use grids as graphs without converting them to usual graph adjacency list representation.



    So every pair (row,column) is a node,



    You can go to next node only if: 2 nodes are neighbors and have different values,



    The purpose of adjacency list is to get neighboring nodes efficient, but with grid cells you can just always check all 4 directions and process nodes that exist.



    Sample code:






    let A = [ [ 'A', 'A', 'A', 'B', 'A' ],
    [ 'B', 'B', 'B', 'B', 'B' ],
    [ 'A', 'B', 'A', 'A', 'A' ],
    [ 'A', 'B', 'B', 'B', 'B' ],
    [ 'A', 'A', 'A', 'A', 'A' ] ];

    let visited = new Set();
    let rows = A.length;
    let columns = A[0].length;
    let distance = Array(rows).fill().map(() => Array(columns).fill(-1));
    distance[0][0]=0;
    let Q = []; //Queue
    Q.push([0,0]);
    visited.add([0,0].toString());

    let dr = [-1,1,0,0];
    let dc = [0,0,-1,1];

    while(Q.length > 0)

    let cur = Q.shift();
    let row = cur[0];
    let col = cur[1];

    for(let k=0; k<4; k++)

    let newRow = row + dr[k];
    let newCol = col + dc[k];

    if(!visited.has([newRow,newCol].toString()) && newRow>=0 && newCol >=0 && newRow < rows && newCol < columns && A[newRow][newCol] !== A[row][col])

    visited.add([newRow,newCol].toString());
    distance[newRow][newCol] = distance[row][col] + 1;
    Q.push([newRow,newCol]);




    if(distance[rows-1][columns-1] === -1)console.log("Path does not exist");
    else console.log(distance[rows-1][columns-1]);








    share|improve this answer






























      2














      One way to solve your problem is to first represent your 2D array as a graph, where each letter is a node, and there exists an edge between two nodes if the letter they represent are neighbor in the array, and these letters are different (one A and one B).

      Then all you have to do is to use a classical shortest path algorithm, such as Dijkstra's, or A*, to find the shortest path between two nodes of your graph. This will be equivalent to finding the shortest path between two letters of your array.



      Edit:
      here is a pseudocode to answer the question you asked in the comment.



      nodes = init_a_2d_array_of_graph_nodes(ARRAY_WIDTH, ARRAY_HEIGHT)
      for i from 1 to ARRAY_WIDTH:
      for j from 1 to ARRAY_HEIGHT:
      if i < ARRAY_WIDTH and array[i][j] != array[i+1][j]:
      add_edge(nodes[i][j], nodes[i+1][j])
      if j < ARRAY_HEIGHT and array[i][j] != array[i][j+1]:
      add_edge(nodes[i][j], nodes[i][j+1])


      First, you need to initialize a graph structure. If you don't know how to do that, check online, there must be plenty of ways to do it, it is rather simple.



      Then, you need to create one node for each letter in your array. It is convenient to store these node in a 2D array as well, so you can find out easily which letter of your array corresponds to which node in your graph.
      Then, for all neighbor letters, you check if these letters are different (that is what is checked in the 2 if conditions). If it is the case, you connect the two nodes with an edge.



      After that, you'll need to run a shortest path algorithm on your graph, between your source node and destination node. Dijkstra's algorithm is the best way to get started with shortest path algorithm, it is the most widely used, and is fast enough in most of the situations you'll encounter.



      Finally, once you have your path, you need to retrieve the index (row and column) of the nodes of your graph, that will give you the corresponding path in your letters array.



      Feel free to comment again if there is still something you do not understand.






      share|improve this answer

























      • That is exactly what I am trying to do right now. What I am having trouble with right now, is finding a way to create an adjacency list from the array.

        – Boris Grunwald
        Mar 19 at 13:24


















      0















      Does anyone know of a simple Graph implementation that can help me solve this problem?




      The Dijkstra algortihm is used to find the shortest path between two nodes. Every position in your two-dimensional array represents a node, the edges are dynamically derived from the surrounding nodes that fulfill your "alternating" rule.



      You can further optimise it for your use case with bidirectional search and a goal metric (A*).






      share|improve this answer























      • IMO it would be simpler (and in any opinion - asymptotically faster) to use BFS for undirected non-weighted graphs.

        – akurtser
        Mar 19 at 15:34











      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55239386%2ffinding-shortest-path-in-two-dimensional-array-javascript%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      0














      Since it represents an undirected unweighted graph, you can simply use BFS:






      const m =
      [ [ 'A', 'A', 'A', 'B', 'A' ],
      [ 'B', 'B', 'B', 'B', 'B' ],
      [ 'A', 'B', 'A', 'A', 'A' ],
      [ 'A', 'B', 'B', 'B', 'B' ],
      [ 'A', 'A', 'A', 'A', 'A' ] ]

      let successors = (root, m) =>
      let connectedCells = [
      [root[0] - 1, root[1]],
      [root[0], root[1] - 1],
      [root[0] + 1, root[1]],
      [root[0], root[1] + 1]
      ]

      const validCells = connectedCells.filter(
      (cell) => (
      cell[0] >= 0 && cell[0] < m.length
      && cell[1] >= 0 && cell[1] < m[0].length)
      )

      const successors = validCells.filter(
      (cell) => (m[cell[0]][cell[1]] !== m[root[0]][root[1]])
      )

      return successors


      const buildPath = (traversalTree, to) =>
      let path = [to]
      let parent = traversalTree[to]
      while (parent)
      path.push(parent)
      parent = traversalTree[parent]

      return path.reverse()


      const bfs = (from, to) =>
      let traversalTree = []
      let visited = new Set
      let queue = []
      queue.push(from)

      while (queue.length)
      let subtreeRoot = queue.shift()
      visited.add(subtreeRoot.toString())

      if (subtreeRoot.toString() == to.toString()) return buildPath(traversalTree, to)

      for (child of successors(subtreeRoot, m))
      if (!visited.has(child.toString()))
      traversalTree[child] = subtreeRoot
      queue.push(child)






      console.log(bfs([0,0], [4,4]).length) // => 13








      share|improve this answer



























        0














        Since it represents an undirected unweighted graph, you can simply use BFS:






        const m =
        [ [ 'A', 'A', 'A', 'B', 'A' ],
        [ 'B', 'B', 'B', 'B', 'B' ],
        [ 'A', 'B', 'A', 'A', 'A' ],
        [ 'A', 'B', 'B', 'B', 'B' ],
        [ 'A', 'A', 'A', 'A', 'A' ] ]

        let successors = (root, m) =>
        let connectedCells = [
        [root[0] - 1, root[1]],
        [root[0], root[1] - 1],
        [root[0] + 1, root[1]],
        [root[0], root[1] + 1]
        ]

        const validCells = connectedCells.filter(
        (cell) => (
        cell[0] >= 0 && cell[0] < m.length
        && cell[1] >= 0 && cell[1] < m[0].length)
        )

        const successors = validCells.filter(
        (cell) => (m[cell[0]][cell[1]] !== m[root[0]][root[1]])
        )

        return successors


        const buildPath = (traversalTree, to) =>
        let path = [to]
        let parent = traversalTree[to]
        while (parent)
        path.push(parent)
        parent = traversalTree[parent]

        return path.reverse()


        const bfs = (from, to) =>
        let traversalTree = []
        let visited = new Set
        let queue = []
        queue.push(from)

        while (queue.length)
        let subtreeRoot = queue.shift()
        visited.add(subtreeRoot.toString())

        if (subtreeRoot.toString() == to.toString()) return buildPath(traversalTree, to)

        for (child of successors(subtreeRoot, m))
        if (!visited.has(child.toString()))
        traversalTree[child] = subtreeRoot
        queue.push(child)






        console.log(bfs([0,0], [4,4]).length) // => 13








        share|improve this answer

























          0












          0








          0







          Since it represents an undirected unweighted graph, you can simply use BFS:






          const m =
          [ [ 'A', 'A', 'A', 'B', 'A' ],
          [ 'B', 'B', 'B', 'B', 'B' ],
          [ 'A', 'B', 'A', 'A', 'A' ],
          [ 'A', 'B', 'B', 'B', 'B' ],
          [ 'A', 'A', 'A', 'A', 'A' ] ]

          let successors = (root, m) =>
          let connectedCells = [
          [root[0] - 1, root[1]],
          [root[0], root[1] - 1],
          [root[0] + 1, root[1]],
          [root[0], root[1] + 1]
          ]

          const validCells = connectedCells.filter(
          (cell) => (
          cell[0] >= 0 && cell[0] < m.length
          && cell[1] >= 0 && cell[1] < m[0].length)
          )

          const successors = validCells.filter(
          (cell) => (m[cell[0]][cell[1]] !== m[root[0]][root[1]])
          )

          return successors


          const buildPath = (traversalTree, to) =>
          let path = [to]
          let parent = traversalTree[to]
          while (parent)
          path.push(parent)
          parent = traversalTree[parent]

          return path.reverse()


          const bfs = (from, to) =>
          let traversalTree = []
          let visited = new Set
          let queue = []
          queue.push(from)

          while (queue.length)
          let subtreeRoot = queue.shift()
          visited.add(subtreeRoot.toString())

          if (subtreeRoot.toString() == to.toString()) return buildPath(traversalTree, to)

          for (child of successors(subtreeRoot, m))
          if (!visited.has(child.toString()))
          traversalTree[child] = subtreeRoot
          queue.push(child)






          console.log(bfs([0,0], [4,4]).length) // => 13








          share|improve this answer













          Since it represents an undirected unweighted graph, you can simply use BFS:






          const m =
          [ [ 'A', 'A', 'A', 'B', 'A' ],
          [ 'B', 'B', 'B', 'B', 'B' ],
          [ 'A', 'B', 'A', 'A', 'A' ],
          [ 'A', 'B', 'B', 'B', 'B' ],
          [ 'A', 'A', 'A', 'A', 'A' ] ]

          let successors = (root, m) =>
          let connectedCells = [
          [root[0] - 1, root[1]],
          [root[0], root[1] - 1],
          [root[0] + 1, root[1]],
          [root[0], root[1] + 1]
          ]

          const validCells = connectedCells.filter(
          (cell) => (
          cell[0] >= 0 && cell[0] < m.length
          && cell[1] >= 0 && cell[1] < m[0].length)
          )

          const successors = validCells.filter(
          (cell) => (m[cell[0]][cell[1]] !== m[root[0]][root[1]])
          )

          return successors


          const buildPath = (traversalTree, to) =>
          let path = [to]
          let parent = traversalTree[to]
          while (parent)
          path.push(parent)
          parent = traversalTree[parent]

          return path.reverse()


          const bfs = (from, to) =>
          let traversalTree = []
          let visited = new Set
          let queue = []
          queue.push(from)

          while (queue.length)
          let subtreeRoot = queue.shift()
          visited.add(subtreeRoot.toString())

          if (subtreeRoot.toString() == to.toString()) return buildPath(traversalTree, to)

          for (child of successors(subtreeRoot, m))
          if (!visited.has(child.toString()))
          traversalTree[child] = subtreeRoot
          queue.push(child)






          console.log(bfs([0,0], [4,4]).length) // => 13








          const m =
          [ [ 'A', 'A', 'A', 'B', 'A' ],
          [ 'B', 'B', 'B', 'B', 'B' ],
          [ 'A', 'B', 'A', 'A', 'A' ],
          [ 'A', 'B', 'B', 'B', 'B' ],
          [ 'A', 'A', 'A', 'A', 'A' ] ]

          let successors = (root, m) =>
          let connectedCells = [
          [root[0] - 1, root[1]],
          [root[0], root[1] - 1],
          [root[0] + 1, root[1]],
          [root[0], root[1] + 1]
          ]

          const validCells = connectedCells.filter(
          (cell) => (
          cell[0] >= 0 && cell[0] < m.length
          && cell[1] >= 0 && cell[1] < m[0].length)
          )

          const successors = validCells.filter(
          (cell) => (m[cell[0]][cell[1]] !== m[root[0]][root[1]])
          )

          return successors


          const buildPath = (traversalTree, to) =>
          let path = [to]
          let parent = traversalTree[to]
          while (parent)
          path.push(parent)
          parent = traversalTree[parent]

          return path.reverse()


          const bfs = (from, to) =>
          let traversalTree = []
          let visited = new Set
          let queue = []
          queue.push(from)

          while (queue.length)
          let subtreeRoot = queue.shift()
          visited.add(subtreeRoot.toString())

          if (subtreeRoot.toString() == to.toString()) return buildPath(traversalTree, to)

          for (child of successors(subtreeRoot, m))
          if (!visited.has(child.toString()))
          traversalTree[child] = subtreeRoot
          queue.push(child)






          console.log(bfs([0,0], [4,4]).length) // => 13





          const m =
          [ [ 'A', 'A', 'A', 'B', 'A' ],
          [ 'B', 'B', 'B', 'B', 'B' ],
          [ 'A', 'B', 'A', 'A', 'A' ],
          [ 'A', 'B', 'B', 'B', 'B' ],
          [ 'A', 'A', 'A', 'A', 'A' ] ]

          let successors = (root, m) =>
          let connectedCells = [
          [root[0] - 1, root[1]],
          [root[0], root[1] - 1],
          [root[0] + 1, root[1]],
          [root[0], root[1] + 1]
          ]

          const validCells = connectedCells.filter(
          (cell) => (
          cell[0] >= 0 && cell[0] < m.length
          && cell[1] >= 0 && cell[1] < m[0].length)
          )

          const successors = validCells.filter(
          (cell) => (m[cell[0]][cell[1]] !== m[root[0]][root[1]])
          )

          return successors


          const buildPath = (traversalTree, to) =>
          let path = [to]
          let parent = traversalTree[to]
          while (parent)
          path.push(parent)
          parent = traversalTree[parent]

          return path.reverse()


          const bfs = (from, to) =>
          let traversalTree = []
          let visited = new Set
          let queue = []
          queue.push(from)

          while (queue.length)
          let subtreeRoot = queue.shift()
          visited.add(subtreeRoot.toString())

          if (subtreeRoot.toString() == to.toString()) return buildPath(traversalTree, to)

          for (child of successors(subtreeRoot, m))
          if (!visited.has(child.toString()))
          traversalTree[child] = subtreeRoot
          queue.push(child)






          console.log(bfs([0,0], [4,4]).length) // => 13






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Mar 19 at 15:27









          akurtserakurtser

          523511




          523511























              2














              Well you can use grids as graphs without converting them to usual graph adjacency list representation.



              So every pair (row,column) is a node,



              You can go to next node only if: 2 nodes are neighbors and have different values,



              The purpose of adjacency list is to get neighboring nodes efficient, but with grid cells you can just always check all 4 directions and process nodes that exist.



              Sample code:






              let A = [ [ 'A', 'A', 'A', 'B', 'A' ],
              [ 'B', 'B', 'B', 'B', 'B' ],
              [ 'A', 'B', 'A', 'A', 'A' ],
              [ 'A', 'B', 'B', 'B', 'B' ],
              [ 'A', 'A', 'A', 'A', 'A' ] ];

              let visited = new Set();
              let rows = A.length;
              let columns = A[0].length;
              let distance = Array(rows).fill().map(() => Array(columns).fill(-1));
              distance[0][0]=0;
              let Q = []; //Queue
              Q.push([0,0]);
              visited.add([0,0].toString());

              let dr = [-1,1,0,0];
              let dc = [0,0,-1,1];

              while(Q.length > 0)

              let cur = Q.shift();
              let row = cur[0];
              let col = cur[1];

              for(let k=0; k<4; k++)

              let newRow = row + dr[k];
              let newCol = col + dc[k];

              if(!visited.has([newRow,newCol].toString()) && newRow>=0 && newCol >=0 && newRow < rows && newCol < columns && A[newRow][newCol] !== A[row][col])

              visited.add([newRow,newCol].toString());
              distance[newRow][newCol] = distance[row][col] + 1;
              Q.push([newRow,newCol]);




              if(distance[rows-1][columns-1] === -1)console.log("Path does not exist");
              else console.log(distance[rows-1][columns-1]);








              share|improve this answer



























                2














                Well you can use grids as graphs without converting them to usual graph adjacency list representation.



                So every pair (row,column) is a node,



                You can go to next node only if: 2 nodes are neighbors and have different values,



                The purpose of adjacency list is to get neighboring nodes efficient, but with grid cells you can just always check all 4 directions and process nodes that exist.



                Sample code:






                let A = [ [ 'A', 'A', 'A', 'B', 'A' ],
                [ 'B', 'B', 'B', 'B', 'B' ],
                [ 'A', 'B', 'A', 'A', 'A' ],
                [ 'A', 'B', 'B', 'B', 'B' ],
                [ 'A', 'A', 'A', 'A', 'A' ] ];

                let visited = new Set();
                let rows = A.length;
                let columns = A[0].length;
                let distance = Array(rows).fill().map(() => Array(columns).fill(-1));
                distance[0][0]=0;
                let Q = []; //Queue
                Q.push([0,0]);
                visited.add([0,0].toString());

                let dr = [-1,1,0,0];
                let dc = [0,0,-1,1];

                while(Q.length > 0)

                let cur = Q.shift();
                let row = cur[0];
                let col = cur[1];

                for(let k=0; k<4; k++)

                let newRow = row + dr[k];
                let newCol = col + dc[k];

                if(!visited.has([newRow,newCol].toString()) && newRow>=0 && newCol >=0 && newRow < rows && newCol < columns && A[newRow][newCol] !== A[row][col])

                visited.add([newRow,newCol].toString());
                distance[newRow][newCol] = distance[row][col] + 1;
                Q.push([newRow,newCol]);




                if(distance[rows-1][columns-1] === -1)console.log("Path does not exist");
                else console.log(distance[rows-1][columns-1]);








                share|improve this answer

























                  2












                  2








                  2







                  Well you can use grids as graphs without converting them to usual graph adjacency list representation.



                  So every pair (row,column) is a node,



                  You can go to next node only if: 2 nodes are neighbors and have different values,



                  The purpose of adjacency list is to get neighboring nodes efficient, but with grid cells you can just always check all 4 directions and process nodes that exist.



                  Sample code:






                  let A = [ [ 'A', 'A', 'A', 'B', 'A' ],
                  [ 'B', 'B', 'B', 'B', 'B' ],
                  [ 'A', 'B', 'A', 'A', 'A' ],
                  [ 'A', 'B', 'B', 'B', 'B' ],
                  [ 'A', 'A', 'A', 'A', 'A' ] ];

                  let visited = new Set();
                  let rows = A.length;
                  let columns = A[0].length;
                  let distance = Array(rows).fill().map(() => Array(columns).fill(-1));
                  distance[0][0]=0;
                  let Q = []; //Queue
                  Q.push([0,0]);
                  visited.add([0,0].toString());

                  let dr = [-1,1,0,0];
                  let dc = [0,0,-1,1];

                  while(Q.length > 0)

                  let cur = Q.shift();
                  let row = cur[0];
                  let col = cur[1];

                  for(let k=0; k<4; k++)

                  let newRow = row + dr[k];
                  let newCol = col + dc[k];

                  if(!visited.has([newRow,newCol].toString()) && newRow>=0 && newCol >=0 && newRow < rows && newCol < columns && A[newRow][newCol] !== A[row][col])

                  visited.add([newRow,newCol].toString());
                  distance[newRow][newCol] = distance[row][col] + 1;
                  Q.push([newRow,newCol]);




                  if(distance[rows-1][columns-1] === -1)console.log("Path does not exist");
                  else console.log(distance[rows-1][columns-1]);








                  share|improve this answer













                  Well you can use grids as graphs without converting them to usual graph adjacency list representation.



                  So every pair (row,column) is a node,



                  You can go to next node only if: 2 nodes are neighbors and have different values,



                  The purpose of adjacency list is to get neighboring nodes efficient, but with grid cells you can just always check all 4 directions and process nodes that exist.



                  Sample code:






                  let A = [ [ 'A', 'A', 'A', 'B', 'A' ],
                  [ 'B', 'B', 'B', 'B', 'B' ],
                  [ 'A', 'B', 'A', 'A', 'A' ],
                  [ 'A', 'B', 'B', 'B', 'B' ],
                  [ 'A', 'A', 'A', 'A', 'A' ] ];

                  let visited = new Set();
                  let rows = A.length;
                  let columns = A[0].length;
                  let distance = Array(rows).fill().map(() => Array(columns).fill(-1));
                  distance[0][0]=0;
                  let Q = []; //Queue
                  Q.push([0,0]);
                  visited.add([0,0].toString());

                  let dr = [-1,1,0,0];
                  let dc = [0,0,-1,1];

                  while(Q.length > 0)

                  let cur = Q.shift();
                  let row = cur[0];
                  let col = cur[1];

                  for(let k=0; k<4; k++)

                  let newRow = row + dr[k];
                  let newCol = col + dc[k];

                  if(!visited.has([newRow,newCol].toString()) && newRow>=0 && newCol >=0 && newRow < rows && newCol < columns && A[newRow][newCol] !== A[row][col])

                  visited.add([newRow,newCol].toString());
                  distance[newRow][newCol] = distance[row][col] + 1;
                  Q.push([newRow,newCol]);




                  if(distance[rows-1][columns-1] === -1)console.log("Path does not exist");
                  else console.log(distance[rows-1][columns-1]);








                  let A = [ [ 'A', 'A', 'A', 'B', 'A' ],
                  [ 'B', 'B', 'B', 'B', 'B' ],
                  [ 'A', 'B', 'A', 'A', 'A' ],
                  [ 'A', 'B', 'B', 'B', 'B' ],
                  [ 'A', 'A', 'A', 'A', 'A' ] ];

                  let visited = new Set();
                  let rows = A.length;
                  let columns = A[0].length;
                  let distance = Array(rows).fill().map(() => Array(columns).fill(-1));
                  distance[0][0]=0;
                  let Q = []; //Queue
                  Q.push([0,0]);
                  visited.add([0,0].toString());

                  let dr = [-1,1,0,0];
                  let dc = [0,0,-1,1];

                  while(Q.length > 0)

                  let cur = Q.shift();
                  let row = cur[0];
                  let col = cur[1];

                  for(let k=0; k<4; k++)

                  let newRow = row + dr[k];
                  let newCol = col + dc[k];

                  if(!visited.has([newRow,newCol].toString()) && newRow>=0 && newCol >=0 && newRow < rows && newCol < columns && A[newRow][newCol] !== A[row][col])

                  visited.add([newRow,newCol].toString());
                  distance[newRow][newCol] = distance[row][col] + 1;
                  Q.push([newRow,newCol]);




                  if(distance[rows-1][columns-1] === -1)console.log("Path does not exist");
                  else console.log(distance[rows-1][columns-1]);





                  let A = [ [ 'A', 'A', 'A', 'B', 'A' ],
                  [ 'B', 'B', 'B', 'B', 'B' ],
                  [ 'A', 'B', 'A', 'A', 'A' ],
                  [ 'A', 'B', 'B', 'B', 'B' ],
                  [ 'A', 'A', 'A', 'A', 'A' ] ];

                  let visited = new Set();
                  let rows = A.length;
                  let columns = A[0].length;
                  let distance = Array(rows).fill().map(() => Array(columns).fill(-1));
                  distance[0][0]=0;
                  let Q = []; //Queue
                  Q.push([0,0]);
                  visited.add([0,0].toString());

                  let dr = [-1,1,0,0];
                  let dc = [0,0,-1,1];

                  while(Q.length > 0)

                  let cur = Q.shift();
                  let row = cur[0];
                  let col = cur[1];

                  for(let k=0; k<4; k++)

                  let newRow = row + dr[k];
                  let newCol = col + dc[k];

                  if(!visited.has([newRow,newCol].toString()) && newRow>=0 && newCol >=0 && newRow < rows && newCol < columns && A[newRow][newCol] !== A[row][col])

                  visited.add([newRow,newCol].toString());
                  distance[newRow][newCol] = distance[row][col] + 1;
                  Q.push([newRow,newCol]);




                  if(distance[rows-1][columns-1] === -1)console.log("Path does not exist");
                  else console.log(distance[rows-1][columns-1]);






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Mar 19 at 14:10









                  PhotonPhoton

                  794714




                  794714





















                      2














                      One way to solve your problem is to first represent your 2D array as a graph, where each letter is a node, and there exists an edge between two nodes if the letter they represent are neighbor in the array, and these letters are different (one A and one B).

                      Then all you have to do is to use a classical shortest path algorithm, such as Dijkstra's, or A*, to find the shortest path between two nodes of your graph. This will be equivalent to finding the shortest path between two letters of your array.



                      Edit:
                      here is a pseudocode to answer the question you asked in the comment.



                      nodes = init_a_2d_array_of_graph_nodes(ARRAY_WIDTH, ARRAY_HEIGHT)
                      for i from 1 to ARRAY_WIDTH:
                      for j from 1 to ARRAY_HEIGHT:
                      if i < ARRAY_WIDTH and array[i][j] != array[i+1][j]:
                      add_edge(nodes[i][j], nodes[i+1][j])
                      if j < ARRAY_HEIGHT and array[i][j] != array[i][j+1]:
                      add_edge(nodes[i][j], nodes[i][j+1])


                      First, you need to initialize a graph structure. If you don't know how to do that, check online, there must be plenty of ways to do it, it is rather simple.



                      Then, you need to create one node for each letter in your array. It is convenient to store these node in a 2D array as well, so you can find out easily which letter of your array corresponds to which node in your graph.
                      Then, for all neighbor letters, you check if these letters are different (that is what is checked in the 2 if conditions). If it is the case, you connect the two nodes with an edge.



                      After that, you'll need to run a shortest path algorithm on your graph, between your source node and destination node. Dijkstra's algorithm is the best way to get started with shortest path algorithm, it is the most widely used, and is fast enough in most of the situations you'll encounter.



                      Finally, once you have your path, you need to retrieve the index (row and column) of the nodes of your graph, that will give you the corresponding path in your letters array.



                      Feel free to comment again if there is still something you do not understand.






                      share|improve this answer

























                      • That is exactly what I am trying to do right now. What I am having trouble with right now, is finding a way to create an adjacency list from the array.

                        – Boris Grunwald
                        Mar 19 at 13:24















                      2














                      One way to solve your problem is to first represent your 2D array as a graph, where each letter is a node, and there exists an edge between two nodes if the letter they represent are neighbor in the array, and these letters are different (one A and one B).

                      Then all you have to do is to use a classical shortest path algorithm, such as Dijkstra's, or A*, to find the shortest path between two nodes of your graph. This will be equivalent to finding the shortest path between two letters of your array.



                      Edit:
                      here is a pseudocode to answer the question you asked in the comment.



                      nodes = init_a_2d_array_of_graph_nodes(ARRAY_WIDTH, ARRAY_HEIGHT)
                      for i from 1 to ARRAY_WIDTH:
                      for j from 1 to ARRAY_HEIGHT:
                      if i < ARRAY_WIDTH and array[i][j] != array[i+1][j]:
                      add_edge(nodes[i][j], nodes[i+1][j])
                      if j < ARRAY_HEIGHT and array[i][j] != array[i][j+1]:
                      add_edge(nodes[i][j], nodes[i][j+1])


                      First, you need to initialize a graph structure. If you don't know how to do that, check online, there must be plenty of ways to do it, it is rather simple.



                      Then, you need to create one node for each letter in your array. It is convenient to store these node in a 2D array as well, so you can find out easily which letter of your array corresponds to which node in your graph.
                      Then, for all neighbor letters, you check if these letters are different (that is what is checked in the 2 if conditions). If it is the case, you connect the two nodes with an edge.



                      After that, you'll need to run a shortest path algorithm on your graph, between your source node and destination node. Dijkstra's algorithm is the best way to get started with shortest path algorithm, it is the most widely used, and is fast enough in most of the situations you'll encounter.



                      Finally, once you have your path, you need to retrieve the index (row and column) of the nodes of your graph, that will give you the corresponding path in your letters array.



                      Feel free to comment again if there is still something you do not understand.






                      share|improve this answer

























                      • That is exactly what I am trying to do right now. What I am having trouble with right now, is finding a way to create an adjacency list from the array.

                        – Boris Grunwald
                        Mar 19 at 13:24













                      2












                      2








                      2







                      One way to solve your problem is to first represent your 2D array as a graph, where each letter is a node, and there exists an edge between two nodes if the letter they represent are neighbor in the array, and these letters are different (one A and one B).

                      Then all you have to do is to use a classical shortest path algorithm, such as Dijkstra's, or A*, to find the shortest path between two nodes of your graph. This will be equivalent to finding the shortest path between two letters of your array.



                      Edit:
                      here is a pseudocode to answer the question you asked in the comment.



                      nodes = init_a_2d_array_of_graph_nodes(ARRAY_WIDTH, ARRAY_HEIGHT)
                      for i from 1 to ARRAY_WIDTH:
                      for j from 1 to ARRAY_HEIGHT:
                      if i < ARRAY_WIDTH and array[i][j] != array[i+1][j]:
                      add_edge(nodes[i][j], nodes[i+1][j])
                      if j < ARRAY_HEIGHT and array[i][j] != array[i][j+1]:
                      add_edge(nodes[i][j], nodes[i][j+1])


                      First, you need to initialize a graph structure. If you don't know how to do that, check online, there must be plenty of ways to do it, it is rather simple.



                      Then, you need to create one node for each letter in your array. It is convenient to store these node in a 2D array as well, so you can find out easily which letter of your array corresponds to which node in your graph.
                      Then, for all neighbor letters, you check if these letters are different (that is what is checked in the 2 if conditions). If it is the case, you connect the two nodes with an edge.



                      After that, you'll need to run a shortest path algorithm on your graph, between your source node and destination node. Dijkstra's algorithm is the best way to get started with shortest path algorithm, it is the most widely used, and is fast enough in most of the situations you'll encounter.



                      Finally, once you have your path, you need to retrieve the index (row and column) of the nodes of your graph, that will give you the corresponding path in your letters array.



                      Feel free to comment again if there is still something you do not understand.






                      share|improve this answer















                      One way to solve your problem is to first represent your 2D array as a graph, where each letter is a node, and there exists an edge between two nodes if the letter they represent are neighbor in the array, and these letters are different (one A and one B).

                      Then all you have to do is to use a classical shortest path algorithm, such as Dijkstra's, or A*, to find the shortest path between two nodes of your graph. This will be equivalent to finding the shortest path between two letters of your array.



                      Edit:
                      here is a pseudocode to answer the question you asked in the comment.



                      nodes = init_a_2d_array_of_graph_nodes(ARRAY_WIDTH, ARRAY_HEIGHT)
                      for i from 1 to ARRAY_WIDTH:
                      for j from 1 to ARRAY_HEIGHT:
                      if i < ARRAY_WIDTH and array[i][j] != array[i+1][j]:
                      add_edge(nodes[i][j], nodes[i+1][j])
                      if j < ARRAY_HEIGHT and array[i][j] != array[i][j+1]:
                      add_edge(nodes[i][j], nodes[i][j+1])


                      First, you need to initialize a graph structure. If you don't know how to do that, check online, there must be plenty of ways to do it, it is rather simple.



                      Then, you need to create one node for each letter in your array. It is convenient to store these node in a 2D array as well, so you can find out easily which letter of your array corresponds to which node in your graph.
                      Then, for all neighbor letters, you check if these letters are different (that is what is checked in the 2 if conditions). If it is the case, you connect the two nodes with an edge.



                      After that, you'll need to run a shortest path algorithm on your graph, between your source node and destination node. Dijkstra's algorithm is the best way to get started with shortest path algorithm, it is the most widely used, and is fast enough in most of the situations you'll encounter.



                      Finally, once you have your path, you need to retrieve the index (row and column) of the nodes of your graph, that will give you the corresponding path in your letters array.



                      Feel free to comment again if there is still something you do not understand.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Mar 19 at 15:15

























                      answered Mar 19 at 12:58









                      m.raynalm.raynal

                      1,002717




                      1,002717












                      • That is exactly what I am trying to do right now. What I am having trouble with right now, is finding a way to create an adjacency list from the array.

                        – Boris Grunwald
                        Mar 19 at 13:24

















                      • That is exactly what I am trying to do right now. What I am having trouble with right now, is finding a way to create an adjacency list from the array.

                        – Boris Grunwald
                        Mar 19 at 13:24
















                      That is exactly what I am trying to do right now. What I am having trouble with right now, is finding a way to create an adjacency list from the array.

                      – Boris Grunwald
                      Mar 19 at 13:24





                      That is exactly what I am trying to do right now. What I am having trouble with right now, is finding a way to create an adjacency list from the array.

                      – Boris Grunwald
                      Mar 19 at 13:24











                      0















                      Does anyone know of a simple Graph implementation that can help me solve this problem?




                      The Dijkstra algortihm is used to find the shortest path between two nodes. Every position in your two-dimensional array represents a node, the edges are dynamically derived from the surrounding nodes that fulfill your "alternating" rule.



                      You can further optimise it for your use case with bidirectional search and a goal metric (A*).






                      share|improve this answer























                      • IMO it would be simpler (and in any opinion - asymptotically faster) to use BFS for undirected non-weighted graphs.

                        – akurtser
                        Mar 19 at 15:34















                      0















                      Does anyone know of a simple Graph implementation that can help me solve this problem?




                      The Dijkstra algortihm is used to find the shortest path between two nodes. Every position in your two-dimensional array represents a node, the edges are dynamically derived from the surrounding nodes that fulfill your "alternating" rule.



                      You can further optimise it for your use case with bidirectional search and a goal metric (A*).






                      share|improve this answer























                      • IMO it would be simpler (and in any opinion - asymptotically faster) to use BFS for undirected non-weighted graphs.

                        – akurtser
                        Mar 19 at 15:34













                      0












                      0








                      0








                      Does anyone know of a simple Graph implementation that can help me solve this problem?




                      The Dijkstra algortihm is used to find the shortest path between two nodes. Every position in your two-dimensional array represents a node, the edges are dynamically derived from the surrounding nodes that fulfill your "alternating" rule.



                      You can further optimise it for your use case with bidirectional search and a goal metric (A*).






                      share|improve this answer














                      Does anyone know of a simple Graph implementation that can help me solve this problem?




                      The Dijkstra algortihm is used to find the shortest path between two nodes. Every position in your two-dimensional array represents a node, the edges are dynamically derived from the surrounding nodes that fulfill your "alternating" rule.



                      You can further optimise it for your use case with bidirectional search and a goal metric (A*).







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Mar 19 at 14:28









                      BergiBergi

                      383k64591922




                      383k64591922












                      • IMO it would be simpler (and in any opinion - asymptotically faster) to use BFS for undirected non-weighted graphs.

                        – akurtser
                        Mar 19 at 15:34

















                      • IMO it would be simpler (and in any opinion - asymptotically faster) to use BFS for undirected non-weighted graphs.

                        – akurtser
                        Mar 19 at 15:34
















                      IMO it would be simpler (and in any opinion - asymptotically faster) to use BFS for undirected non-weighted graphs.

                      – akurtser
                      Mar 19 at 15:34





                      IMO it would be simpler (and in any opinion - asymptotically faster) to use BFS for undirected non-weighted graphs.

                      – akurtser
                      Mar 19 at 15:34

















                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55239386%2ffinding-shortest-path-in-two-dimensional-array-javascript%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

                      SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

                      은진 송씨 목차 역사 본관 분파 인물 조선 왕실과의 인척 관계 집성촌 항렬자 인구 같이 보기 각주 둘러보기 메뉴은진 송씨세종실록 149권, 지리지 충청도 공주목 은진현