From 9b2e1cd5ddb7e448c6564f30d3fb56cef8ddabd8 Mon Sep 17 00:00:00 2001 From: "M.Pac" Date: Wed, 3 May 2023 11:38:52 +0200 Subject: [PATCH 1/5] feat: added dijkstra in c --- dijkstra.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 dijkstra.c diff --git a/dijkstra.c b/dijkstra.c new file mode 100644 index 0000000..7f8d835 --- /dev/null +++ b/dijkstra.c @@ -0,0 +1,86 @@ +#include +#include +#include + +#define MAX_NODES 1000 + +struct Edge { + int to; + int cost; +}; + +struct Node { + int id; + int dist; +}; + +int cmp(const void *a, const void *b) { + const struct Node *node_a = (const struct Node *)a; + const struct Node *node_b = (const struct Node *)b; + return node_b->dist - node_a->dist; +} + +void dijkstra(struct Edge **nodes, int num_nodes, int start, int *dist) { + int i, j; + struct Node pq[MAX_NODES]; + int pq_size = 0; + + for (i = 0; i < num_nodes; i++) { + dist[i] = INT_MAX; + } + dist[start] = 0; + + pq[pq_size++] = (struct Node){ start, 0 }; + qsort(pq, pq_size, sizeof(struct Node), cmp); + + while (pq_size > 0) { + struct Node node = pq[--pq_size]; + + for (j = 0; j < num_nodes; j++) { + if (nodes[node.id][j].to < 0) break; + + int new_dist = dist[node.id] + nodes[node.id][j].cost; + if (new_dist < dist[nodes[node.id][j].to]) { + dist[nodes[node.id][j].to] = new_dist; + pq[pq_size++] = (struct Node){ nodes[node.id][j].to, new_dist }; + qsort(pq, pq_size, sizeof(struct Node), cmp); + } + } + } +} + +int main() { + int num_nodes = 4; + struct Edge **nodes = (struct Edge **)malloc(num_nodes * sizeof(struct Edge *)); + int i, j; + + for (i = 0; i < num_nodes; i++) { + nodes[i] = (struct Edge *)malloc(num_nodes * sizeof(struct Edge)); + for (j = 0; j < num_nodes; j++) { + nodes[i][j].to = -1; + nodes[i][j].cost = -1; + } + } + + nodes[0][0].to = 1; nodes[0][0].cost = 4; + nodes[0][1].to = 2; nodes[0][1].cost = 2; + nodes[1][0].to = 3; nodes[1][0].cost = 1; + nodes[2][0].to = 1; nodes[2][0].cost = 1; + nodes[2][1].to = 3; nodes[2][1].cost = 5; + + int *dist = (int *)malloc(num_nodes * sizeof(int)); + dijkstra(nodes, num_nodes, 0, dist); + + for (i = 0; i < num_nodes; i++) { + printf("%d ", dist[i]); + } + printf("\n"); + + for (i = 0; i < num_nodes; i++) { + free(nodes[i]); + } + free(nodes); + free(dist); + + return 0; +} \ No newline at end of file From 818eec1f891065266aeb2a33dea9e3183b40da21 Mon Sep 17 00:00:00 2001 From: "M.Pac" Date: Wed, 3 May 2023 11:39:01 +0200 Subject: [PATCH 2/5] feat: added dijkstra in Go --- dijkstra.go | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 dijkstra.go diff --git a/dijkstra.go b/dijkstra.go new file mode 100644 index 0000000..0501734 --- /dev/null +++ b/dijkstra.go @@ -0,0 +1,78 @@ +type edge struct { + to int + cost int +} + +type node struct { + id int + dist int + edges []edge +} + +func dijkstra(nodes []node, start int) []int { + const inf = 1<<31 - 1 + dist := make([]int, len(nodes)) + for i := range dist { + dist[i] = inf + } + dist[start] = 0 + pq := priorityQueue{{start, 0}} + for len(pq) > 0 { + curr := pq.pop() + if dist[curr.id] < curr.dist { + continue + } + for _, e := range nodes[curr.id].edges { + if newDist := dist[curr.id] + e.cost; newDist < dist[e.to] { + dist[e.to] = newDist + pq.push(node{e.to, newDist}) + } + } + } + return dist +} + +type priorityQueue []node + +func (pq *priorityQueue) push(n node) { + heap.Push(pq, n) +} + +func (pq *priorityQueue) pop() node { + return heap.Pop(pq).(node) +} + +func (pq priorityQueue) Len() int { + return len(pq) +} + +func (pq priorityQueue) Less(i, j int) bool { + return pq[i].dist < pq[j].dist +} + +func (pq priorityQueue) Swap(i, j int) { + pq[i], pq[j] = pq[j], pq[i] +} + +func (pq *priorityQueue) Push(x interface{}) { + *pq = append(*pq, x.(node)) +} + +func (pq *priorityQueue) Pop() interface{} { + old := *pq + n := len(old) + item := old[n-1] + *pq = old[0 : n-1] + return item +} + +func main() { + nodes := []node{ + {0, 0, []edge{{1, 4}, {2, 2}}}, + {1, math.MaxInt32, []edge{{3, 1}}}, + {2, math.MaxInt32, []edge{{1, 1}, {3, 5}}}, + {3, math.MaxInt32, []edge{}}, + } + dist := dijkstra(nodes, 0) + fmt.Println(dist) +} \ No newline at end of file From 1a40ee53d1221067ea672757198529ad421c6e94 Mon Sep 17 00:00:00 2001 From: "M.Pac" Date: Wed, 3 May 2023 11:39:13 +0200 Subject: [PATCH 3/5] feat: added dijkstra in Rust --- dijkstra.r | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 dijkstra.r diff --git a/dijkstra.r b/dijkstra.r new file mode 100644 index 0000000..79a9892 --- /dev/null +++ b/dijkstra.r @@ -0,0 +1,59 @@ +use std::cmp::Ordering; +use std::collections::BinaryHeap; + +#[derive(Clone, Copy, Eq, PartialEq)] +struct Node { + id: usize, + dist: i32, +} + +impl Ord for Node { + fn cmp(&self, other: &Node) -> Ordering { + other.dist.cmp(&self.dist) + } +} + +impl PartialOrd for Node { + fn partial_cmp(&self, other: &Node) -> Option { + Some(self.cmp(other)) + } +} + +struct Edge { + to: usize, + cost: i32, +} + +fn dijkstra(nodes: &Vec>, start: usize) -> Vec { + let mut dist = vec![i32::MAX; nodes.len()]; + let mut pq = BinaryHeap::new(); + + dist[start] = 0; + pq.push(Node { id: start, dist: 0 }); + + while let Some(Node { id, dist: _ }) = pq.pop() { + for edge in &nodes[id] { + let new_dist = dist[id] + edge.cost; + if new_dist < dist[edge.to] { + dist[edge.to] = new_dist; + pq.push(Node { + id: edge.to, + dist: new_dist, + }); + } + } + } + + dist +} + +fn main() { + let nodes = vec![ + vec![Edge { to: 1, cost: 4 }, Edge { to: 2, cost: 2 }], + vec![Edge { to: 3, cost: 1 }], + vec![Edge { to: 1, cost: 1 }, Edge { to: 3, cost: 5 }], + vec![], + ]; + let dist = dijkstra(&nodes, 0); + println!("{:?}", dist); +} \ No newline at end of file From dfba9c0a5a4a62a6b0358872a65877875e8dfebc Mon Sep 17 00:00:00 2001 From: "M.Pac" Date: Wed, 3 May 2023 11:39:53 +0200 Subject: [PATCH 4/5] update: updated supported languages --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d462106..300fe1c 100644 --- a/README.md +++ b/README.md @@ -13,5 +13,5 @@ Each example should feature this graph and should print the path A->B->F->H in s ex. `py dijkstras.py` >>> \['H', 'F', 'B'\] ## Current Supported Languages: -C++, C#, Java, Javascript, Typescript, Coffeescript, PHP, **Python**, **Ruby**, Scala +C++, C#, Java, Javascript, Typescript, Coffeescript, PHP, **Python**, **Ruby**, Scala, C, Go, Rust *(Bolded languages have associated test-suites)* From 1b2cf012853cd27343f073ab0c5d730952287bdf Mon Sep 17 00:00:00 2001 From: "M.Pac" Date: Wed, 3 May 2023 11:40:10 +0200 Subject: [PATCH 5/5] chore: linting code --- Dijkstras.java | 2 +- dijkstras.coffee | 2 +- dijkstras.cpp | 2 +- dijkstras.cs | 2 +- dijkstras.js | 2 +- dijkstras.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Dijkstras.java b/Dijkstras.java index 66e2121..71f2176 100644 --- a/Dijkstras.java +++ b/Dijkstras.java @@ -163,4 +163,4 @@ public List getShortestPath(Character start, Character finish) { return new ArrayList(distances.keySet()); } -} +} \ No newline at end of file diff --git a/dijkstras.coffee b/dijkstras.coffee index 5f782e4..71cfbb2 100644 --- a/dijkstras.coffee +++ b/dijkstras.coffee @@ -89,4 +89,4 @@ g.addVertex 'H', E: 1 F: 3 -console.log g.shortestPath('A', 'H').concat(['A']).reverse() +console.log g.shortestPath('A', 'H').concat(['A']).reverse() \ No newline at end of file diff --git a/dijkstras.cpp b/dijkstras.cpp index 87d66a1..a0e6b35 100644 --- a/dijkstras.cpp +++ b/dijkstras.cpp @@ -96,4 +96,4 @@ int main() } return 0; -} +} \ No newline at end of file diff --git a/dijkstras.cs b/dijkstras.cs index b3996b0..74d17a1 100644 --- a/dijkstras.cs +++ b/dijkstras.cs @@ -90,4 +90,4 @@ public static void Main(string[] args) g.shortest_path('A', 'H').ForEach( x => Console.WriteLine(x) ); } } -} +} \ No newline at end of file diff --git a/dijkstras.js b/dijkstras.js index 666ec52..ef24d98 100644 --- a/dijkstras.js +++ b/dijkstras.js @@ -100,4 +100,4 @@ g.addVertex('G', {C: 4, F: 9}); g.addVertex('H', {E: 1, F: 3}); // Log test, with the addition of reversing the path and prepending the first node so it's more readable -console.log(g.shortestPath('A', 'H').concat(['A']).reverse()); +console.log(g.shortestPath('A', 'H').concat(['A']).reverse()); \ No newline at end of file diff --git a/dijkstras.php b/dijkstras.php index 79eb8be..9740cee 100644 --- a/dijkstras.php +++ b/dijkstras.php @@ -99,4 +99,4 @@ public function __toString() $graph->add_vertex( 'F', array( 'B' => 2, 'C' => 6, 'D' => 8, 'G' => 9, 'H' => 3 ) ); $graph->add_vertex( 'G', array( 'C' => 4, 'F' => 9 ) ); $graph->add_vertex( 'H', array( 'E' => 1, 'F' => 3 ) ); -print_r($graph->shortest_path('A', 'H')); +print_r($graph->shortest_path('A', 'H')); \ No newline at end of file