Implemented no solution case of 2-coloring contract checker

Implemented a greedy 2-coloring algorithm to check whether a given
graph is 2-colorable. The algorithm is only used if the player
provides "[]" as their answer; other answers will be checked using
the previously implemented validation code.
This commit is contained in:
Undeemiss 2022-04-20 20:54:07 -05:00
parent bdfd102085
commit 951221578a

@ -1308,7 +1308,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
},
{
name: "Proper 2-Coloring of a Graph",
difficulty: 6,
difficulty: 7,
numTries: 5,
desc: (data: [number, [number, number][]]): string => {
return `test description: "${JSON.stringify(data)}"`;
@ -1355,10 +1355,54 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
return [n + m, edges];
},
solver: (data: [number, [number, number][]], ans: string): boolean => {
//No solution case
//Case where the player believes there is no solution
if (ans == "[]") {
//TODO: Check if there is no solution
return true;
//Helper function to get neighbourhood of a vertex
function neighbourhood(vertex: number): number[] {
const adjLeft = data[1].filter(([a, _]) => a == vertex).map(([_, b]) => b);
const adjRight = data[1].filter(([_, b]) => b == vertex).map(([a, _]) => a);
return adjLeft.concat(adjRight);
}
//Verify that there is no solution by attempting to create a proper 2-coloring.
const coloring: (number | undefined)[] = Array(data[0]).fill(undefined);
while (coloring.some((val) => val === undefined)) {
//Color a vertex in the graph
const initialVertex: number = coloring.findIndex((val) => val === undefined);
coloring[initialVertex] = 0;
const frontier: number[] = [initialVertex];
//Propogate the coloring throughout the component containing v greedily
while (frontier.length > 0) {
const v: number = frontier.pop() || 0;
const neighbors: number[] = neighbourhood(v);
//For each vertex u adjacent to v
for (const id in neighbors) {
const u: number = neighbors[id];
//Set the color of u to the opposite of v's color if it is new,
//then add u to the frontier to continue the algorithm.
if (coloring[u] === undefined) {
if (coloring[v] === 0) coloring[u] = 1;
else coloring[u] = 0;
frontier.push(u);
}
//Assert u,v do not have the same color
else if (coloring[u] === coloring[v]) {
//If u,v do have the same color, no proper 2-coloring exists, meaning
//the player was correct to say there is no proper 2-coloring of the graph.
return true;
}
}
}
}
//If this code is reached, there exists a proper 2-coloring of the input
//graph, and thus the player was incorrect in submitting no answer.
return false;
}
//Sanitize player input