diff --git a/Backtracking/MColoringProblem.js b/Backtracking/MColoringProblem.js new file mode 100644 index 0000000000..c89f30e043 --- /dev/null +++ b/Backtracking/MColoringProblem.js @@ -0,0 +1,49 @@ +/** + * Colors a graph using up to m colors such that no two adjacent vertices share the same color. + * @param {number[][]} graph - Adjacency matrix of the graph, using 0 for no edge. + * @param {number} m - The number of colors to use. + * @returns {?Array.} A valid M-coloring of the graph using colors 1 to m, or null if none exists. + * @see https://en.wikipedia.org/wiki/Graph_coloring + */ +function mColoring(graph, m) { + const colors = new Array(graph.length).fill(0); + + // Check if it's safe to color a vertex with a given color. + function isSafe(vertex, color) { + for (let i = 0; i < graph.length; i++) { + if (graph[vertex][i] && colors[i] === color) { + return false; + } + } + return true; + } + + // Use backtracking to try and color the graph. + function solveColoring(vertex = 0) { + if (vertex === graph.length) { + return true; + } + + for (let color = 1; color <= m; color++) { + if (isSafe(vertex, color)) { + colors[vertex] = color; + + if (solveColoring(vertex + 1)) { + return true; + } + + // If no solution, backtrack. + colors[vertex] = 0; + } + } + return false; + } + + // If coloring is possible, return the colors. + if (solveColoring()) { + return colors; + } + return null; +} + +export { mColoring }; diff --git a/Backtracking/tests/MColoringProblem.test.js b/Backtracking/tests/MColoringProblem.test.js new file mode 100644 index 0000000000..d98134b62a --- /dev/null +++ b/Backtracking/tests/MColoringProblem.test.js @@ -0,0 +1,23 @@ +import { mColoring } from '../MColoringProblem'; + +describe('MColoringProblem', () => { + it('should color a triangle with 3 colors', () => { + const graph = [ + [0, 1, 1], + [1, 0, 1], + [1, 1, 0] + ]; + const solution = mColoring(graph, 3); + expect(solution).not.toBeNull(); + }); + + it('should not color a triangle with 2 colors', () => { + const graph = [ + [0, 1, 1], + [1, 0, 1], + [1, 1, 0] + ]; + const solution = mColoring(graph, 2); + expect(solution).toBeNull(); + }); +}); diff --git a/DIRECTORY.md b/DIRECTORY.md index aea7b1548f..61fa501119 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -3,6 +3,7 @@ * [generateParentheses](Backtracking/generateParentheses.js) * [GeneratePermutations](Backtracking/GeneratePermutations.js) * [KnightTour](Backtracking/KnightTour.js) + * [MColoringProblem](Backtracking/MColoringProblem.js) * [NQueens](Backtracking/NQueens.js) * [RatInAMaze](Backtracking/RatInAMaze.js) * [Sudoku](Backtracking/Sudoku.js) @@ -166,6 +167,7 @@ * [Area](Maths/Area.js) * [ArithmeticGeometricMean](Maths/ArithmeticGeometricMean.js) * [ArmstrongNumber](Maths/ArmstrongNumber.js) + * [AutomorphicNumber](Maths/AutomorphicNumber.js) * [AverageMean](Maths/AverageMean.js) * [AverageMedian](Maths/AverageMedian.js) * [BinaryConvert](Maths/BinaryConvert.js)