Skip to content

Commit

Permalink
Add dot-dsl exercise (#2834)
Browse files Browse the repository at this point in the history
Add dot-dsl exercise

Closes #1809
  • Loading branch information
kahgoh authored Sep 9, 2024
1 parent ba71783 commit 5f25754
Show file tree
Hide file tree
Showing 17 changed files with 832 additions and 11 deletions.
33 changes: 22 additions & 11 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,17 @@
],
"difficulty": 2
},
{
"slug": "dot-dsl",
"name": "DOT DSL",
"uuid": "03e1070d-a3ed-4664-9559-283e535c6bc4",
"practices": [],
"prerequisites": [
"classes",
"lists"
],
"difficulty": 2
},
{
"slug": "grains",
"name": "Grains",
Expand Down Expand Up @@ -916,6 +927,17 @@
],
"difficulty": 5
},
{
"slug": "game-of-life",
"name": "Conway's Game of Life",
"uuid": "749de7fc-3dcb-4231-9b4f-115d153af74f",
"practices": [],
"prerequisites": [
"arrays",
"if-statements"
],
"difficulty": 5
},
{
"slug": "grep",
"name": "Grep",
Expand Down Expand Up @@ -1791,17 +1813,6 @@
"lists"
],
"difficulty": 10
},
{
"slug": "game-of-life",
"name": "Conway's Game of Life",
"uuid": "749de7fc-3dcb-4231-9b4f-115d153af74f",
"practices": [],
"prerequisites": [
"arrays",
"if-statements"
],
"difficulty": 5
}
],
"foregone": [
Expand Down
6 changes: 6 additions & 0 deletions exercises/practice/dot-dsl/.docs/instructions.append.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Instructions append

The graph is represented in the DSL by the `Graph` class.
The implementation for the nodes and edges (represented by the `Node` and `Edge` classes respectively) are provided.

For more details on the DSL's expected design, take a look at the test cases in `GraphTest.java`.
30 changes: 30 additions & 0 deletions exercises/practice/dot-dsl/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Instructions

A [Domain Specific Language (DSL)][dsl] is a small language optimized for a specific domain.
Since a DSL is targeted, it can greatly impact productivity/understanding by allowing the writer to declare _what_ they want rather than _how_.

One problem area where they are applied are complex customizations/configurations.

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`).
A simple graph looks like this:

graph {
graph [bgcolor="yellow"]
a [color="red"]
b [color="blue"]
a -- b [color="green"]
}

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.

Write a Domain Specific Language similar to the Graphviz dot language.

Our DSL is similar to the Graphviz dot language in that our DSL will be used to create graph data structures.
However, unlike the DOT Language, our DSL will be an internal DSL for use only in our language.

More information about the difference between internal and external DSLs can be found [here][fowler-dsl].

[dsl]: https://en.wikipedia.org/wiki/Domain-specific_language
[dot-language]: https://en.wikipedia.org/wiki/DOT_(graph_description_language)
[graphviz]: https://graphviz.org/
[fowler-dsl]: https://martinfowler.com/bliki/DomainSpecificLanguage.html
24 changes: 24 additions & 0 deletions exercises/practice/dot-dsl/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"authors": [
"kahgoh",
"manumafe98"
],
"files": {
"solution": [
"src/main/java/Graph.java"
],
"test": [
"src/test/java/GraphTest.java"
],
"example": [
".meta/src/reference/java/Graph.java"
],
"editor": [
"src/main/java/Node.java",
"src/main/java/Edge.java"
]
},
"blurb": "Write a Domain Specific Language similar to the Graphviz dot language.",
"source": "Wikipedia",
"source_url": "https://en.wikipedia.org/wiki/DOT_(graph_description_language)"
}
48 changes: 48 additions & 0 deletions exercises/practice/dot-dsl/.meta/src/reference/java/Edge.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import java.util.Collections;
import java.util.Map;
import java.util.Objects;

/**
* Represents an edge on the graph.
*
* NOTE: There is no need to change this file and is treated as read only by the Exercism test runners.
*/
public final class Edge {
private final String start;

private final String end;

private final Map<String, String> attributes;

public Edge(String start, String end) {
this.start = start;
this.end = end;
this.attributes = Collections.emptyMap();
}

public Edge(String start, String end, Map<String, String> attributes) {
this.start = start;
this.end = end;
this.attributes = Map.copyOf(attributes);
}

@Override
public int hashCode() {
return Objects.hash(start, end, attributes);
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Edge other) {
return Objects.equals(other.start, start)
&& Objects.equals(other.end, end)
&& Objects.equals(other.attributes, attributes);
}
return false;
}

@Override
public String toString() {
return "Edge [start=" + start + ", end=" + end + ", attributes=" + attributes + "]";
}
}
54 changes: 54 additions & 0 deletions exercises/practice/dot-dsl/.meta/src/reference/java/Graph.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class Graph {

private final List<Node> nodes = new ArrayList<>();

private final List<Edge> edges = new ArrayList<>();

private final Map<String, String> attributes;

public Graph() {
this.attributes = Collections.emptyMap();
}

public Graph(Map<String, String> attributes) {
this.attributes = Map.copyOf(attributes);
}

public Collection<Node> getNodes() {
return Collections.unmodifiableList(nodes);
}

public Collection<Edge> getEdges() {
return Collections.unmodifiableList(edges);
}

public Graph node(String name) {
nodes.add(new Node(name));
return this;
}

public Graph node(String name, Map<String, String> attributes) {
nodes.add(new Node(name, attributes));
return this;
}

public Graph edge(String start, String end) {
edges.add(new Edge(start, end));
return this;
}

public Graph edge(String start, String end, Map<String, String> attributes) {
edges.add(new Edge(start, end, attributes));
return this;
}

public Map<String, String> getAttributes() {
return attributes;
}
}
43 changes: 43 additions & 0 deletions exercises/practice/dot-dsl/.meta/src/reference/java/Node.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import java.util.Collections;
import java.util.Map;
import java.util.Objects;

/**
* Represents a node on the graph.
*
* NOTE: There is no need to change this file and is treated as read only by the Exercism test runners.
*/
public final class Node {

private final String name;

private final Map<String, String> attributes;

public Node(String name) {
this.name = name;
this.attributes = Collections.emptyMap();
}

public Node(String name, Map<String, String> attributes) {
this.name = name;
this.attributes = Map.copyOf(attributes);
}

@Override
public int hashCode() {
return Objects.hash(name, attributes);
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Node other) {
return Objects.equals(other.name, name) && Objects.equals(other.attributes, attributes);
}
return false;
}

@Override
public String toString() {
return "Node [name=" + name + ", attributes=" + attributes + "]";
}
}
23 changes: 23 additions & 0 deletions exercises/practice/dot-dsl/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
plugins {
id "java"
}

repositories {
mavenCentral()
}

dependencies {
testImplementation platform("org.junit:junit-bom:5.10.0")
testImplementation "org.junit.jupiter:junit-jupiter"
testImplementation "org.assertj:assertj-core:3.25.1"
}

test {
useJUnitPlatform()

testLogging {
exceptionFormat = "full"
showStandardStreams = true
events = ["passed", "failed", "skipped"]
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit 5f25754

Please sign in to comment.