Skip to content

Commit 88e904c

Browse files
committed
Add GraphSpec
1 parent 2a034d3 commit 88e904c

File tree

6 files changed

+109
-12
lines changed

6 files changed

+109
-12
lines changed

.idea/gradle.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main/java/Main.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import algorithm.Dijkstras;
2+
import algorithm.Graph;
3+
4+
import java.util.Map;
5+
6+
public class Main {
7+
public static void main(String[] args) {
8+
System.out.println("Hello!");
9+
var algorithm = new Dijkstras<String>();
10+
11+
var graph = new Graph<>(Map.of(
12+
"A", Map.of("B", 5),
13+
"B", Map.of("A", 7)
14+
));
15+
16+
var route = algorithm.findPath(graph, "A", "A");
17+
18+
System.out.println(route);
19+
System.out.println(graph.getDistance(route));
20+
21+
route = algorithm.findPath(graph, "A", "B");
22+
System.out.println(route);
23+
System.out.println(graph.getDistance(route));
24+
25+
route = algorithm.findPath(graph, "B", "A");
26+
System.out.println(route);
27+
System.out.println(graph.getDistance(route));
28+
29+
}
30+
31+
32+
}

src/main/java/algorithm/Dijkstras.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,28 @@ public List<T> findPath(Graph<T> graph, T source, T target) {
1010
final var queue = new LinkedList<T>();
1111
final var visited = new HashSet<T>();
1212
final var distances = new HashMap<T, Double>();
13-
final var path = new HashMap<T, T>();
13+
final var previous = new HashMap<T, T>();
1414
queue.add(source);
1515

1616
while (!queue.isEmpty()) {
17-
final var previous = queue.pollFirst();
18-
final var edges = graph.get(previous);
17+
final var prev = queue.pollFirst();
18+
final var edges = graph.nodes().get(prev);
1919
edges.forEach((node, time) -> {
20-
final var distance = distances.getOrDefault(previous, .0) + time.doubleValue();
20+
final var distance = distances.getOrDefault(prev, .0) + time.doubleValue();
2121
if (!visited.contains(node)) {
2222
queue.add(node);
2323
visited.add(node);
2424
}
2525
if (distance < distances.getOrDefault(node, Double.MAX_VALUE)) {
26-
path.put(node, previous);
26+
previous.put(node, prev);
2727
distances.put(node, distance);
2828
}
2929
});
3030
}
3131

32-
final var route = new LinkedList<T>();
33-
Stream.iterate(target, Objects::nonNull, path::get).forEach(route::addFirst);
34-
return route;
32+
final var path = new LinkedList<T>();
33+
Stream.iterate(target, Objects::nonNull, previous::get).forEach(path::addFirst);
34+
return path;
3535
}
3636

3737
}

src/main/java/algorithm/Graph.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
import java.util.List;
44
import java.util.Map;
55

6-
public interface Graph<T> extends Map<T, Map<T, Number>> {
6+
public record Graph<T>(Map<T, Map<T, Number>> nodes) {
77

8-
default double getDistance(List<T> path) {
8+
public double getDistance(List<T> path) {
99
double distance = 0;
1010
for (int i = 1; i < path.size(); ++i) {
11-
final var previous = this.get(path.get(i - 1));
11+
final var previous = nodes.get(path.get(i - 1));
1212
distance += previous.get(path.get(i)).doubleValue();
1313
}
1414
return distance;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package algorithm
2+
3+
import spock.lang.Specification
4+
import spock.lang.Subject
5+
import spock.lang.Unroll
6+
7+
class DijkstrasSpec extends Specification {
8+
9+
static final SAMPLE_ONE = [
10+
A: [B: 7, C: 2],
11+
B: [A: 3, C: 5],
12+
C: [A: 1, B: 3]
13+
] as Graph<String>
14+
15+
@Subject
16+
def algorithm = new Dijkstras<String>()
17+
18+
@Unroll("from #source to #target the time is #time and the path is #expected")
19+
def 'should find a route for sample one'() {
20+
given:
21+
def graph = SAMPLE_ONE
22+
23+
when:
24+
def path = algorithm.findPath(graph, source, target)
25+
26+
then:
27+
path == expected
28+
29+
where:
30+
source | target || time | expected
31+
'A' | 'B' || 7 | ['A', 'B']
32+
}
33+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package algorithm
2+
3+
import spock.lang.Specification
4+
import spock.lang.Unroll
5+
6+
class GraphSpec extends Specification {
7+
8+
@Unroll("distance is #distance for path #path")
9+
def "should calculate distance"() {
10+
given:
11+
def graph = new Graph([
12+
A: [B: 7, C: 2],
13+
B: [A: 3, C: 5],
14+
C: [A: 1, B: 3]
15+
])
16+
17+
expect:
18+
graph.getDistance(path) == distance as double
19+
20+
where:
21+
path | distance
22+
['A'] | 0
23+
['B'] | 0
24+
['C'] | 0
25+
['A', 'B'] | 7
26+
['B', 'C'] | 5
27+
['A', 'B', 'C'] | 12
28+
['C', 'A'] | 1
29+
['A', 'B', 'C', 'A'] | 13
30+
}
31+
32+
}

0 commit comments

Comments
 (0)