Skip to content

Commit 5f25754

Browse files
authored
Add dot-dsl exercise (#2834)
Add dot-dsl exercise Closes #1809
1 parent ba71783 commit 5f25754

File tree

17 files changed

+832
-11
lines changed

17 files changed

+832
-11
lines changed

config.json

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,17 @@
437437
],
438438
"difficulty": 2
439439
},
440+
{
441+
"slug": "dot-dsl",
442+
"name": "DOT DSL",
443+
"uuid": "03e1070d-a3ed-4664-9559-283e535c6bc4",
444+
"practices": [],
445+
"prerequisites": [
446+
"classes",
447+
"lists"
448+
],
449+
"difficulty": 2
450+
},
440451
{
441452
"slug": "grains",
442453
"name": "Grains",
@@ -916,6 +927,17 @@
916927
],
917928
"difficulty": 5
918929
},
930+
{
931+
"slug": "game-of-life",
932+
"name": "Conway's Game of Life",
933+
"uuid": "749de7fc-3dcb-4231-9b4f-115d153af74f",
934+
"practices": [],
935+
"prerequisites": [
936+
"arrays",
937+
"if-statements"
938+
],
939+
"difficulty": 5
940+
},
919941
{
920942
"slug": "grep",
921943
"name": "Grep",
@@ -1791,17 +1813,6 @@
17911813
"lists"
17921814
],
17931815
"difficulty": 10
1794-
},
1795-
{
1796-
"slug": "game-of-life",
1797-
"name": "Conway's Game of Life",
1798-
"uuid": "749de7fc-3dcb-4231-9b4f-115d153af74f",
1799-
"practices": [],
1800-
"prerequisites": [
1801-
"arrays",
1802-
"if-statements"
1803-
],
1804-
"difficulty": 5
18051816
}
18061817
],
18071818
"foregone": [
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Instructions append
2+
3+
The graph is represented in the DSL by the `Graph` class.
4+
The implementation for the nodes and edges (represented by the `Node` and `Edge` classes respectively) are provided.
5+
6+
For more details on the DSL's expected design, take a look at the test cases in `GraphTest.java`.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Instructions
2+
3+
A [Domain Specific Language (DSL)][dsl] is a small language optimized for a specific domain.
4+
Since a DSL is targeted, it can greatly impact productivity/understanding by allowing the writer to declare _what_ they want rather than _how_.
5+
6+
One problem area where they are applied are complex customizations/configurations.
7+
8+
For example the [DOT language][dot-language] allows you to write a textual description of a graph which is then transformed into a picture by one of the [Graphviz][graphviz] tools (such as `dot`).
9+
A simple graph looks like this:
10+
11+
graph {
12+
graph [bgcolor="yellow"]
13+
a [color="red"]
14+
b [color="blue"]
15+
a -- b [color="green"]
16+
}
17+
18+
Putting this in a file `example.dot` and running `dot example.dot -T png -o example.png` creates an image `example.png` with red and blue circle connected by a green line on a yellow background.
19+
20+
Write a Domain Specific Language similar to the Graphviz dot language.
21+
22+
Our DSL is similar to the Graphviz dot language in that our DSL will be used to create graph data structures.
23+
However, unlike the DOT Language, our DSL will be an internal DSL for use only in our language.
24+
25+
More information about the difference between internal and external DSLs can be found [here][fowler-dsl].
26+
27+
[dsl]: https://en.wikipedia.org/wiki/Domain-specific_language
28+
[dot-language]: https://en.wikipedia.org/wiki/DOT_(graph_description_language)
29+
[graphviz]: https://graphviz.org/
30+
[fowler-dsl]: https://martinfowler.com/bliki/DomainSpecificLanguage.html
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"authors": [
3+
"kahgoh",
4+
"manumafe98"
5+
],
6+
"files": {
7+
"solution": [
8+
"src/main/java/Graph.java"
9+
],
10+
"test": [
11+
"src/test/java/GraphTest.java"
12+
],
13+
"example": [
14+
".meta/src/reference/java/Graph.java"
15+
],
16+
"editor": [
17+
"src/main/java/Node.java",
18+
"src/main/java/Edge.java"
19+
]
20+
},
21+
"blurb": "Write a Domain Specific Language similar to the Graphviz dot language.",
22+
"source": "Wikipedia",
23+
"source_url": "https://en.wikipedia.org/wiki/DOT_(graph_description_language)"
24+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import java.util.Collections;
2+
import java.util.Map;
3+
import java.util.Objects;
4+
5+
/**
6+
* Represents an edge on the graph.
7+
*
8+
* NOTE: There is no need to change this file and is treated as read only by the Exercism test runners.
9+
*/
10+
public final class Edge {
11+
private final String start;
12+
13+
private final String end;
14+
15+
private final Map<String, String> attributes;
16+
17+
public Edge(String start, String end) {
18+
this.start = start;
19+
this.end = end;
20+
this.attributes = Collections.emptyMap();
21+
}
22+
23+
public Edge(String start, String end, Map<String, String> attributes) {
24+
this.start = start;
25+
this.end = end;
26+
this.attributes = Map.copyOf(attributes);
27+
}
28+
29+
@Override
30+
public int hashCode() {
31+
return Objects.hash(start, end, attributes);
32+
}
33+
34+
@Override
35+
public boolean equals(Object obj) {
36+
if (obj instanceof Edge other) {
37+
return Objects.equals(other.start, start)
38+
&& Objects.equals(other.end, end)
39+
&& Objects.equals(other.attributes, attributes);
40+
}
41+
return false;
42+
}
43+
44+
@Override
45+
public String toString() {
46+
return "Edge [start=" + start + ", end=" + end + ", attributes=" + attributes + "]";
47+
}
48+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import java.util.ArrayList;
2+
import java.util.Collection;
3+
import java.util.Collections;
4+
import java.util.List;
5+
import java.util.Map;
6+
7+
public class Graph {
8+
9+
private final List<Node> nodes = new ArrayList<>();
10+
11+
private final List<Edge> edges = new ArrayList<>();
12+
13+
private final Map<String, String> attributes;
14+
15+
public Graph() {
16+
this.attributes = Collections.emptyMap();
17+
}
18+
19+
public Graph(Map<String, String> attributes) {
20+
this.attributes = Map.copyOf(attributes);
21+
}
22+
23+
public Collection<Node> getNodes() {
24+
return Collections.unmodifiableList(nodes);
25+
}
26+
27+
public Collection<Edge> getEdges() {
28+
return Collections.unmodifiableList(edges);
29+
}
30+
31+
public Graph node(String name) {
32+
nodes.add(new Node(name));
33+
return this;
34+
}
35+
36+
public Graph node(String name, Map<String, String> attributes) {
37+
nodes.add(new Node(name, attributes));
38+
return this;
39+
}
40+
41+
public Graph edge(String start, String end) {
42+
edges.add(new Edge(start, end));
43+
return this;
44+
}
45+
46+
public Graph edge(String start, String end, Map<String, String> attributes) {
47+
edges.add(new Edge(start, end, attributes));
48+
return this;
49+
}
50+
51+
public Map<String, String> getAttributes() {
52+
return attributes;
53+
}
54+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import java.util.Collections;
2+
import java.util.Map;
3+
import java.util.Objects;
4+
5+
/**
6+
* Represents a node on the graph.
7+
*
8+
* NOTE: There is no need to change this file and is treated as read only by the Exercism test runners.
9+
*/
10+
public final class Node {
11+
12+
private final String name;
13+
14+
private final Map<String, String> attributes;
15+
16+
public Node(String name) {
17+
this.name = name;
18+
this.attributes = Collections.emptyMap();
19+
}
20+
21+
public Node(String name, Map<String, String> attributes) {
22+
this.name = name;
23+
this.attributes = Map.copyOf(attributes);
24+
}
25+
26+
@Override
27+
public int hashCode() {
28+
return Objects.hash(name, attributes);
29+
}
30+
31+
@Override
32+
public boolean equals(Object obj) {
33+
if (obj instanceof Node other) {
34+
return Objects.equals(other.name, name) && Objects.equals(other.attributes, attributes);
35+
}
36+
return false;
37+
}
38+
39+
@Override
40+
public String toString() {
41+
return "Node [name=" + name + ", attributes=" + attributes + "]";
42+
}
43+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
plugins {
2+
id "java"
3+
}
4+
5+
repositories {
6+
mavenCentral()
7+
}
8+
9+
dependencies {
10+
testImplementation platform("org.junit:junit-bom:5.10.0")
11+
testImplementation "org.junit.jupiter:junit-jupiter"
12+
testImplementation "org.assertj:assertj-core:3.25.1"
13+
}
14+
15+
test {
16+
useJUnitPlatform()
17+
18+
testLogging {
19+
exceptionFormat = "full"
20+
showStandardStreams = true
21+
events = ["passed", "failed", "skipped"]
22+
}
23+
}
Binary file not shown.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
distributionBase=GRADLE_USER_HOME
2+
distributionPath=wrapper/dists
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
4+
validateDistributionUrl=true
5+
zipStoreBase=GRADLE_USER_HOME
6+
zipStorePath=wrapper/dists

0 commit comments

Comments
 (0)