Data update
This commit is contained in:
parent
72eb4943cb
commit
4d5544505c
2347 changed files with 62432 additions and 16731 deletions
149
Task/Graph-colouring/FreeBASIC/graph-colouring.basic
Normal file
149
Task/Graph-colouring/FreeBASIC/graph-colouring.basic
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
Const tests As String = "0-1 1-2 2-0 3" & Chr(10) & _
|
||||
"1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7" & Chr(10) & _
|
||||
"1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6" & Chr(10) & _
|
||||
"1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7"
|
||||
|
||||
Sub Colour(links() As Integer, nodeCount As Integer, colours() As Integer, _
|
||||
soln() As Integer, Byref best As Integer, sgte As Integer, used As Integer = 0)
|
||||
|
||||
Dim As Integer i, c = 1
|
||||
Dim As Integer tmpColours(nodeCount - 1)
|
||||
|
||||
For i = 0 To nodeCount - 1
|
||||
tmpColours(i) = colours(i)
|
||||
Next
|
||||
|
||||
While c <= best
|
||||
Dim As Boolean avail = True
|
||||
For i = 0 To nodeCount - 1
|
||||
If links(sgte, i) = 1 Andalso tmpColours(i) = c Then
|
||||
avail = False
|
||||
Exit For
|
||||
End If
|
||||
Next
|
||||
|
||||
If avail Then
|
||||
tmpColours(sgte) = c
|
||||
Dim As Integer newused = used
|
||||
If c > used Then newused = c
|
||||
|
||||
If sgte < nodeCount - 1 Then
|
||||
Colour(links(), nodeCount, tmpColours(), soln(), best, sgte + 1, newused)
|
||||
Elseif newused < best Then
|
||||
best = newused
|
||||
For i = 0 To nodeCount - 1
|
||||
soln(i) = tmpColours(i)
|
||||
Next
|
||||
End If
|
||||
End If
|
||||
c += 1
|
||||
Wend
|
||||
End Sub
|
||||
|
||||
Function GetNodeIndex(nodeMap() As String, nodeCount As Integer, nodeName As String) As Integer
|
||||
For i As Integer = 0 To nodeCount - 1
|
||||
If nodeMap(i) = nodeName Then Return i
|
||||
Next
|
||||
Return -1
|
||||
End Function
|
||||
|
||||
Sub main()
|
||||
Dim As String testLines(3)
|
||||
Dim As Integer lineCount = 0, posic = 1, nextPos
|
||||
|
||||
' Split the test chain into lines
|
||||
Do
|
||||
nextPos = Instr(posic, tests, Chr(10))
|
||||
If nextPos = 0 Then
|
||||
testLines(lineCount) = Mid(tests, posic)
|
||||
lineCount += 1
|
||||
Exit Do
|
||||
Else
|
||||
testLines(lineCount) = Mid(tests, posic, nextPos - posic)
|
||||
lineCount += 1
|
||||
posic = nextPos + 1
|
||||
End If
|
||||
Loop
|
||||
|
||||
For t As Integer = 0 To 3
|
||||
Dim As String linea = testLines(t)
|
||||
Dim As String nodeMap(20)
|
||||
Dim As Integer nodeCount = 0
|
||||
Dim As String token
|
||||
posic = 1
|
||||
|
||||
Do
|
||||
If posic > Len(linea) Then Exit Do
|
||||
|
||||
nextPos = Instr(posic, linea, " ")
|
||||
If nextPos = 0 Then nextPos = Len(linea) + 1
|
||||
|
||||
token = Mid(linea, posic, nextPos - posic)
|
||||
posic = nextPos + 1
|
||||
|
||||
Dim As Integer dashPos = Instr(token, "-")
|
||||
If dashPos > 0 Then
|
||||
Dim As String node1 = Left(token, dashPos - 1)
|
||||
Dim As String node2 = Mid(token, dashPos + 1)
|
||||
|
||||
If GetNodeIndex(nodeMap(), nodeCount, node1) = -1 Then
|
||||
nodeMap(nodeCount) = node1
|
||||
nodeCount += 1
|
||||
End If
|
||||
|
||||
If GetNodeIndex(nodeMap(), nodeCount, node2) = -1 Then
|
||||
nodeMap(nodeCount) = node2
|
||||
nodeCount += 1
|
||||
End If
|
||||
Else
|
||||
If GetNodeIndex(nodeMap(), nodeCount, token) = -1 Then
|
||||
nodeMap(nodeCount) = token
|
||||
nodeCount += 1
|
||||
End If
|
||||
End If
|
||||
Loop
|
||||
|
||||
Dim As Integer links(nodeCount - 1, nodeCount - 1)
|
||||
Dim As Integer edgeCount = 0
|
||||
|
||||
posic = 1
|
||||
Do
|
||||
If posic > Len(linea) Then Exit Do
|
||||
|
||||
nextPos = Instr(posic, linea, " ")
|
||||
If nextPos = 0 Then nextPos = Len(linea) + 1
|
||||
|
||||
token = Mid(linea, posic, nextPos - posic)
|
||||
posic = nextPos + 1
|
||||
|
||||
Dim As Integer dashPos = Instr(token, "-")
|
||||
If dashPos > 0 Then
|
||||
Dim As String node1 = Left(token, dashPos - 1)
|
||||
Dim As String node2 = Mid(token, dashPos + 1)
|
||||
|
||||
Dim As Integer idx1 = GetNodeIndex(nodeMap(), nodeCount, node1)
|
||||
Dim As Integer idx2 = GetNodeIndex(nodeMap(), nodeCount, node2)
|
||||
|
||||
links(idx1, idx2) = 1
|
||||
links(idx2, idx1) = 1
|
||||
edgeCount += 1
|
||||
End If
|
||||
Loop
|
||||
|
||||
Dim As Integer colours(nodeCount - 1), soln(nodeCount - 1)
|
||||
Dim As Integer best = nodeCount
|
||||
|
||||
Colour(links(), nodeCount, colours(), soln(), best, 0)
|
||||
|
||||
Print "test" & t + 1 & ": " & nodeCount & " nodes, " & edgeCount & " edges, " & best & " colours:";
|
||||
|
||||
For i As Integer = 0 To nodeCount - 1
|
||||
Print soln(i);
|
||||
Next
|
||||
Print
|
||||
Next
|
||||
End Sub
|
||||
|
||||
main()
|
||||
|
||||
Sleep
|
||||
222
Task/Graph-colouring/JavaScript/graph-colouring.js
Normal file
222
Task/Graph-colouring/JavaScript/graph-colouring.js
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
// Equivalent to:
|
||||
// #include <vector>
|
||||
// #include <string>
|
||||
const allColours = ["PINK", "ORANGE", "CYAN", "YELLOW", "RED", "GREEN", "BLUE"];
|
||||
|
||||
// Equivalent to:
|
||||
// class Node { ... };
|
||||
class Node {
|
||||
constructor(id, saturation, colour) {
|
||||
this.id = id; // Equivalent to int32_t id
|
||||
this.saturation = saturation; // Equivalent to int32_t saturation
|
||||
this.colour = colour; // Equivalent to std::string colour
|
||||
this.excludedFromSearch = false; // Equivalent to bool excluded_from_search
|
||||
}
|
||||
|
||||
// The default constructor Node() : id(0), ... is handled implicitly in how we create nodes in the Map.
|
||||
// If a key doesn't exist, Map.get() returns undefined, we explicitly use Map.set() to create nodes.
|
||||
}
|
||||
|
||||
// Equivalent to:
|
||||
// int main() { ... }
|
||||
function main() {
|
||||
// Equivalent to:
|
||||
// std::map<int32_t, Node, decltype([](const int32_t& a, const int32_t& b){ return a < b; })> graph;
|
||||
// In JavaScript, Map keys are ordered by insertion or can be iterated over,
|
||||
// but there's no built-in custom comparator for sorted access like std::map.
|
||||
// However, the algorithm iterates through *all* map entries to find the max saturation node,
|
||||
// so the map's internal order doesn't affect the result.
|
||||
let graph = new Map(); // Map<number, Node>
|
||||
|
||||
// Equivalent to:
|
||||
// std::map<int32_t, std::set<int32_t, decltype([](const int32_t& a, const int32_t& b) { return a < b; })>, decltype([](const int32_t& a, const int32_t& b) { return a < b; })> neighbours;
|
||||
// Similar to graph, Set doesn't guarantee element order like std::set,
|
||||
// but neighbor order isn't relevant to the coloring logic.
|
||||
let neighbours = new Map(); // Map<number, Set<number>>
|
||||
|
||||
// Equivalent to:
|
||||
// const std::vector<std::string> graph_representations = { ... };
|
||||
const graphRepresentations = [
|
||||
"0-1 1-2 2-0 3",
|
||||
"1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7",
|
||||
"1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6",
|
||||
"1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7"
|
||||
];
|
||||
|
||||
// Equivalent to:
|
||||
// for ( const std::string& graph_representation : graph_representations ) { ... }
|
||||
for (const graphRepresentation of graphRepresentations) {
|
||||
graph.clear();
|
||||
neighbours.clear();
|
||||
|
||||
// Equivalent to:
|
||||
// std::stringstream stream(graph_representation);
|
||||
// std::string element;
|
||||
// while ( stream >> element ) { ... }
|
||||
const elements = graphRepresentation.split(/\s+/); // Split string by one or more whitespace characters
|
||||
for (const element of elements) {
|
||||
if (element === "") continue; // Skip empty strings that might result from multiple spaces
|
||||
|
||||
// Equivalent to: if ( element.find("-") != std::string::npos ) { ... }
|
||||
if (element.includes("-")) {
|
||||
const parts = element.split("-");
|
||||
// Equivalent to: const int32_t id1 = element[0] - '0';
|
||||
const id1 = parseInt(parts[0], 10);
|
||||
// Equivalent to: const int32_t id2 = element[element.length() - 1] - '0';
|
||||
const id2 = parseInt(parts[parts.length - 1], 10); // Use last part, robust for potential future formats like 10-11
|
||||
|
||||
// Ensure nodes exist in the graph map.
|
||||
// Equivalent to: if ( ! graph.contains(id1) ) { graph[id1] = Node(id1, 0, "NO_COLOUR"); }
|
||||
if (!graph.has(id1)) {
|
||||
graph.set(id1, new Node(id1, 0, "NO_COLOUR"));
|
||||
}
|
||||
// C++ `Node node1 = graph[id1];` gets a *copy*. In JS, graph.get(id1) gets a *reference*.
|
||||
// We don't need to store the reference here just yet as we only needed to ensure the node exists.
|
||||
|
||||
// Equivalent to: if ( ! graph.contains(id2) ) { graph[id2] = Node(id2, 0, "NO_COLOUR"); }
|
||||
if (!graph.has(id2)) {
|
||||
graph.set(id2, new Node(id2, 0, "NO_COLOUR"));
|
||||
}
|
||||
// C++ `Node node2 = graph[id2];`
|
||||
|
||||
// Ensure neighbor sets exist and add neighbors.
|
||||
// Equivalent to: neighbours[id1].emplace(id2);
|
||||
if (!neighbours.has(id1)) {
|
||||
neighbours.set(id1, new Set()); // Equivalent to std::set<int32_t>
|
||||
}
|
||||
neighbours.get(id1).add(id2); // Equivalent to emplace
|
||||
|
||||
// Equivalent to: neighbours[id2].emplace(id1);
|
||||
if (!neighbours.has(id2)) {
|
||||
neighbours.set(id2, new Set());
|
||||
}
|
||||
neighbours.get(id2).add(id1);
|
||||
|
||||
} else { // Handle isolated nodes (e.g., "3")
|
||||
// Equivalent to: const int32_t id = element[0] - '0';
|
||||
const id = parseInt(element, 10); // Parse the whole element as an ID
|
||||
|
||||
// Equivalent to: if ( ! graph.contains(id) ) { graph[id] = Node(id, 0, "NO_COLOUR"); }
|
||||
if (!graph.has(id)) {
|
||||
graph.set(id, new Node(id, 0, "NO_COLOUR"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Graph Coloring Loop (DSatur-like heuristic)
|
||||
// Equivalent to: for ( uint64_t i = 0; i < graph.size(); ++i ) { ... }
|
||||
// This loop structure implies that each node is processed exactly once
|
||||
// because one node is marked excluded_from_search in each iteration.
|
||||
for (let i = 0; i < graph.size; ++i) {
|
||||
let maxNodeId = -1;
|
||||
let maxSaturation = -1;
|
||||
|
||||
// Find the node with the maximum saturation among those not yet colored.
|
||||
// Equivalent to: for ( const auto& [key, value] : graph ) { ... }
|
||||
for (const [key, node] of graph) {
|
||||
// Equivalent to: if ( ! value.excluded_from_search && value.saturation > max_saturation ) { ... }
|
||||
// If multiple nodes have the same max saturation, the one encountered first in the map iteration order is chosen.
|
||||
if (!node.excludedFromSearch && node.saturation > maxSaturation) {
|
||||
maxSaturation = node.saturation;
|
||||
maxNodeId = key;
|
||||
}
|
||||
}
|
||||
|
||||
// If maxNodeId is still -1, it means no unexcluded node was found.
|
||||
// This shouldn't happen until all nodes are processed due to the loop count.
|
||||
if (maxNodeId === -1) {
|
||||
// Should only happen if the graph was empty or already fully excluded,
|
||||
// which the outer loop count should prevent prematurely.
|
||||
continue; // Skip this iteration if no node found.
|
||||
}
|
||||
|
||||
// Find colours used by neighbours of the selected node.
|
||||
// Equivalent to: std::unordered_set<std::string> colours_used;
|
||||
const coloursUsed = new Set(); // Use Set for efficient `has` check
|
||||
|
||||
// Equivalent to: for ( const int32_t& neighbour : neighbours[max_node_id] ) { ... }
|
||||
// Get the set of neighbor IDs for the selected node. Handle case where node has no neighbors entry.
|
||||
const neighborIdsOfSelected = neighbours.get(maxNodeId) || new Set();
|
||||
for (const neighbourId of neighborIdsOfSelected) {
|
||||
// Get the neighbor node object from the graph map
|
||||
const neighbourNode = graph.get(neighbourId);
|
||||
// Check if the neighbor node exists in the graph and add its color to the set
|
||||
if (neighbourNode) {
|
||||
coloursUsed.add(neighbourNode.colour);
|
||||
}
|
||||
}
|
||||
|
||||
// Find the smallest available colour.
|
||||
// Equivalent to: std::string min_colour;
|
||||
let minColour = "";
|
||||
// Equivalent to: for ( const std::string& colour : all_colours ) { ... }
|
||||
for (const colour of allColours) {
|
||||
// Equivalent to: if ( ! colours_used.contains(colour) ) { ... }
|
||||
if (!coloursUsed.has(colour)) {
|
||||
minColour = colour;
|
||||
break; // Found the first available colour, stop searching.
|
||||
}
|
||||
}
|
||||
|
||||
// Assign colour to the selected node and mark it as excluded.
|
||||
// Equivalent to: graph[max_node_id].excluded_from_search = true;
|
||||
// Equivalent to: graph[max_node_id].colour = min_colour;
|
||||
const selectedNode = graph.get(maxNodeId); // Get the reference to the node object
|
||||
selectedNode.excludedFromSearch = true;
|
||||
selectedNode.colour = minColour;
|
||||
|
||||
// Update saturation of neighbours.
|
||||
// Equivalent to: for ( int32_t neighbour : neighbours[max_node_id] ) { ... }
|
||||
for (const neighbourId of neighborIdsOfSelected) {
|
||||
const neighbourNode = graph.get(neighbourId);
|
||||
// Equivalent to: if ( graph[neighbour].colour == "NO_COLOUR" ) { ... }
|
||||
// C++ logic: only update saturation if the neighbour is still uncolored.
|
||||
// Set saturation to the number of *distinct colors* used by the *selected node's* neighbors
|
||||
// *at the moment the selected node was processed*.
|
||||
if (neighbourNode && neighbourNode.colour === "NO_COLOUR") {
|
||||
neighbourNode.saturation = coloursUsed.size; // Uses the size calculated above
|
||||
}
|
||||
}
|
||||
// Note: This saturation update logic is a direct translation of the C++ code.
|
||||
// A more standard DSatur might update saturation differently (e.g., incrementing
|
||||
// the saturation of *all* uncolored neighbors if the newly assigned color is new to *their* neighborhood).
|
||||
// We adhere to the C++ code's exact implementation.
|
||||
}
|
||||
|
||||
// Output the results for the colored graph.
|
||||
// Equivalent to: std::unordered_set<std::string> graph_colours;
|
||||
const graphColours = new Set(); // Use Set to count unique colors
|
||||
|
||||
// Equivalent to: for ( const auto& [key, value] : graph ) { ... }
|
||||
// Iterate over the graph map which now contains the final colored nodes.
|
||||
for (const [key, node] of graph) {
|
||||
// Equivalent to: graph_colours.emplace(value.colour);
|
||||
graphColours.add(node.colour);
|
||||
|
||||
// Equivalent to: std::cout << "Node " << key << ": colour = " + value.colour;
|
||||
let output = `Node ${key}: colour = ${node.colour}`;
|
||||
|
||||
// Equivalent to: if ( ! neighbours[key].empty() ) { ... }
|
||||
const neighborIds = neighbours.get(key) || new Set(); // Get neighbors for the current node key
|
||||
if (neighborIds.size > 0) {
|
||||
// Equivalent to: std::cout << std::string(8 - value.colour.length(), ' ') << "neighbours = ";
|
||||
// Calculate padding for alignment based on C++ padding (8 - color length)
|
||||
const padding = ' '.repeat(Math.max(0, 8 - node.colour.length));
|
||||
output += `${padding}neighbours = `;
|
||||
|
||||
// Equivalent to: for ( const int32_t& neighbour : neighbours[key] ) { std::cout << neighbour << " "; }
|
||||
// Convert the Set of neighbor IDs to an Array and join them with spaces.
|
||||
const neighborList = Array.from(neighborIds).join(" ");
|
||||
output += neighborList;
|
||||
}
|
||||
// Equivalent to: std::cout << std::endl;
|
||||
console.log(output);
|
||||
}
|
||||
// Equivalent to: std::cout << "Number of colours used: " << graph_colours.size() << std::endl << std::endl;
|
||||
console.log(`Number of colours used: ${graphColours.size}`);
|
||||
console.log(""); // Add an extra newline as in the C++ output
|
||||
}
|
||||
}
|
||||
|
||||
// Execute the main function
|
||||
main();
|
||||
134
Task/Graph-colouring/Rust/graph-colouring.rs
Normal file
134
Task/Graph-colouring/Rust/graph-colouring.rs
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
const ALL_COLOURS: [&str; 7] = ["PINK", "ORANGE", "CYAN", "YELLOW", "RED", "GREEN", "BLUE"];
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Node {
|
||||
id: i32,
|
||||
saturation: i32,
|
||||
colour: String,
|
||||
excluded_from_search: bool,
|
||||
}
|
||||
|
||||
impl Node {
|
||||
fn new(id: i32, saturation: i32, colour: String) -> Self {
|
||||
Node {
|
||||
id,
|
||||
saturation,
|
||||
colour,
|
||||
excluded_from_search: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn default() -> Self {
|
||||
Node {
|
||||
id: 0,
|
||||
saturation: 0,
|
||||
colour: "NO_COLOUR".to_string(),
|
||||
excluded_from_search: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let graph_representations: [&str; 4] = [
|
||||
"0-1 1-2 2-0 3",
|
||||
"1-6 1-7 1-8 2-5 2-7 2-8 3-5 3-6 3-8 4-5 4-6 4-7",
|
||||
"1-4 1-6 1-8 3-2 3-6 3-8 5-2 5-4 5-8 7-2 7-4 7-6",
|
||||
"1-6 7-1 8-1 5-2 2-7 2-8 3-5 6-3 3-8 4-5 4-6 4-7",
|
||||
];
|
||||
|
||||
for graph_representation in graph_representations {
|
||||
let mut graph: HashMap<i32, Node> = HashMap::new();
|
||||
let mut neighbours: HashMap<i32, HashSet<i32>> = HashMap::new();
|
||||
|
||||
for element in graph_representation.split_whitespace() {
|
||||
if element.contains("-") {
|
||||
let parts: Vec<&str> = element.split("-").collect();
|
||||
let id1: i32 = parts[0].parse().unwrap();
|
||||
let id2: i32 = parts[1].parse().unwrap();
|
||||
|
||||
if !graph.contains_key(&id1) {
|
||||
graph.insert(id1, Node::new(id1, 0, "NO_COLOUR".to_string()));
|
||||
}
|
||||
//let node1 = graph.get(&id1).unwrap().clone(); // No need to clone
|
||||
|
||||
if !graph.contains_key(&id2) {
|
||||
graph.insert(id2, Node::new(id2, 0, "NO_COLOUR".to_string()));
|
||||
}
|
||||
//let node2 = graph.get(&id2).unwrap().clone(); // No need to clone
|
||||
|
||||
neighbours.entry(id1).or_insert(HashSet::new()).insert(id2);
|
||||
neighbours.entry(id2).or_insert(HashSet::new()).insert(id1);
|
||||
} else {
|
||||
let id: i32 = element.parse().unwrap();
|
||||
if !graph.contains_key(&id) {
|
||||
graph.insert(id, Node::new(id, 0, "NO_COLOUR".to_string()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _ in 0..graph.len() {
|
||||
let mut max_node_id: i32 = -1;
|
||||
let mut max_saturation: i32 = -1;
|
||||
|
||||
for (&key, value) in &graph {
|
||||
if !value.excluded_from_search && value.saturation > max_saturation {
|
||||
max_saturation = value.saturation;
|
||||
max_node_id = key;
|
||||
}
|
||||
}
|
||||
|
||||
let mut colours_used: HashSet<String> = HashSet::new();
|
||||
if let Some(neighbors) = neighbours.get(&max_node_id) {
|
||||
for &neighbour in neighbors {
|
||||
if let Some(neighbor_node) = graph.get(&neighbour) {
|
||||
colours_used.insert(neighbor_node.colour.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut min_colour = String::new();
|
||||
for &colour in &ALL_COLOURS {
|
||||
if !colours_used.contains(colour) {
|
||||
min_colour = colour.to_string();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(node) = graph.get_mut(&max_node_id) {
|
||||
node.excluded_from_search = true;
|
||||
node.colour = min_colour.clone();
|
||||
}
|
||||
|
||||
if let Some(neighbors) = neighbours.get(&max_node_id) {
|
||||
for &neighbour in neighbors {
|
||||
if let Some(neighbor_node) = graph.get_mut(&neighbour) {
|
||||
if neighbor_node.colour == "NO_COLOUR" {
|
||||
neighbor_node.saturation = colours_used.len() as i32;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut graph_colours: HashSet<String> = HashSet::new();
|
||||
for (&key, value) in &graph {
|
||||
graph_colours.insert(value.colour.clone());
|
||||
print!("Node {}: colour = {}", key, value.colour);
|
||||
|
||||
if let Some(neighbors) = neighbours.get(&key) {
|
||||
if !neighbors.is_empty() {
|
||||
print!("{}", " ".repeat(8 - value.colour.len()));
|
||||
print!("neighbours = ");
|
||||
for &neighbour in neighbors {
|
||||
print!("{} ", neighbour);
|
||||
}
|
||||
}
|
||||
}
|
||||
println!();
|
||||
}
|
||||
println!("Number of colours used: {}", graph_colours.len());
|
||||
println!();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue