Skip to content

Commit 977ea25

Browse files
author
Abhijit Sarkar
committed
Simplify graph tests by implicitly converting tuples to edges
1 parent 3f9311c commit 977ea25

File tree

5 files changed

+59
-38
lines changed

5 files changed

+59
-38
lines changed

graph/test/src/P83Spec.scala

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import org.scalatest.funspec.AnyFunSpec
44
import org.scalatest.matchers.should.Matchers.*
55
import P83.spanningTrees
66
import org.scalactic.Equality
7+
import graph.Util.given
8+
import scala.language.implicitConversions
79

810
class P83Spec extends AnyFunSpec:
911
it("construct all spanning trees"):
10-
val data = List(
12+
val data: List[(List[Char], List[Edge[Char, Nothing]])] = List(
1113
(
1214
List('a', 'b', 'c'),
1315
List(('a', 'b'), ('b', 'c'), ('a', 'c'))
@@ -30,16 +32,16 @@ class P83Spec extends AnyFunSpec:
3032
)
3133
)
3234

33-
val edgeEq = new Equality[(Char, Char)]:
34-
def areEqual(a: (Char, Char), b: Any): Boolean =
35+
val edgeEq = new Equality[Edge[Char, Nothing]]:
36+
def areEqual(a: Edge[Char, Nothing], b: Any): Boolean =
3537
if b.isInstanceOf[List[?]] then
3638
b.asInstanceOf[List[Char]] match
37-
case u :: v :: Nil => (u, v) == a || (v, u) == a
39+
case u :: v :: Nil => (u, v) == (a.u, a.v) || (v, u) == (a.u, a.v)
3840
case _ => false
3941
else false
4042

4143
data.foreach { (vertices, edges) =>
42-
val g = Graph.buildUG(vertices, edges.map((u, v) => Edge(u, v, None)))
44+
val g = Graph.buildUG(vertices, edges)
4345
val st = g.spanningTrees
4446
val n = g.vertices.size
4547
st.foreach { t =>

graph/test/src/P84Spec.scala

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import org.scalatest.funspec.AnyFunSpec
44
import org.scalatest.matchers.should.Matchers.*
55
import P84.minimalSpanningTree
66
import org.scalactic.Equality
7+
import graph.Util.given
8+
import scala.language.implicitConversions
79

810
class P84Spec extends AnyFunSpec:
911
it("construct the minimal spanning tree"):
10-
val data = List(
12+
val data: List[(List[Char], List[Edge[Char, Int]], Int)] = List(
1113
(
1214
List('a', 'b', 'c'),
1315
List(('a', 'b', 1), ('b', 'c', 2), ('a', 'c', 3)),
@@ -32,15 +34,15 @@ class P84Spec extends AnyFunSpec:
3234
)
3335
)
3436

35-
val edgeEq = new Equality[(Char, Char, Int)]:
36-
def areEqual(a: (Char, Char, Int), b: Any): Boolean =
37+
val edgeEq = new Equality[Edge[Char, Int]]:
38+
def areEqual(a: Edge[Char, Int], b: Any): Boolean =
3739
if b.isInstanceOf[Edge[?, ?]] then
38-
val e = b.asInstanceOf[Edge[Char, Int]]
39-
(a._1, a._2) == (e.u, e.v) || (a._1, a._2) == (e.v, e.u)
40+
b.asInstanceOf[Edge[Char, Int]] match
41+
case Edge(u, v, _) => (u, v) == (a.u, a.v) || (v, u) == (a.u, a.v)
4042
else false
4143

4244
data.foreach { (vertices, edges, cost) =>
43-
val g = Graph.buildUG(vertices, edges.map((u, v, d) => Edge(u, v, Some(d))))
45+
val g = Graph.buildUG(vertices, edges)
4446
val mst = g.minimalSpanningTree
4547
mst.foreach(e => (edges should contain(e))(edgeEq))
4648
mst.foldLeft(0)((s, e) => s + e.data.getOrElse(0)) shouldBe cost

graph/test/src/P85Spec.scala

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,68 +3,76 @@ package graph
33
import org.scalatest.funspec.AnyFunSpec
44
import org.scalatest.matchers.should.Matchers.shouldBe
55
import P85.isIsomorphicTo
6+
import graph.Util.given
7+
import scala.language.implicitConversions
68

79
class P85Spec extends AnyFunSpec:
810
it("graph isomorphism"):
911

10-
val v1 = List('a', 'b')
11-
val e1 = List(('a', 'b'))
12-
val v2 = List(5, 7)
13-
val e2 = List((5, 7))
14-
val g1 = Graph.buildUG(v1, e1.map((u, v) => Edge(u, v, None)))
15-
val g2 = Graph.buildUG(v2, e2.map((u, v) => Edge(u, v, None)))
12+
val v1 = List('a', 'b')
13+
val e1: List[Edge[Char, Nothing]] = List(('a', 'b'))
14+
val v2 = List(5, 7)
15+
val e2: List[Edge[Int, Nothing]] = List((5, 7))
16+
val g1 = Graph.buildUG(v1, e1)
17+
val g2 = Graph.buildUG(v2, e2)
1618
g1.isIsomorphicTo(g2) shouldBe true
1719

1820
// format: off
1921
val v3 = (1 to 8).toList
20-
val e3 =
22+
val e3: List[Edge[Int, Nothing]] =
2123
List(
2224
(1, 5), (1, 6), (1, 7), (2, 5),
2325
(2, 6), (2, 8), (3, 5), (3, 7),
2426
(3, 8), (4, 6), (4, 7), (4, 8)
2527
)
26-
val e4 =
28+
val e4: List[Edge[Int, Nothing]] =
2729
List(
2830
(1, 2), (1, 4), (1, 5), (6, 2),
2931
(6, 5), (6, 7), (8, 4), (8, 5),
3032
(8, 7), (3, 2), (3, 4), (3, 7)
3133
)
3234
// format: on
3335

34-
val g3 = Graph.buildUG(v3, e3.map((u, v) => Edge(u, v, None)))
35-
val g4 = Graph.buildUG(v3, e4.map((u, v) => Edge(u, v, None)))
36+
val g3 = Graph.buildUG(v3, e3)
37+
val g4 = Graph.buildUG(v3, e4)
3638
g3.isIsomorphicTo(g4) shouldBe true
3739

3840
val v5 = ('a' to 'e').toList
39-
val e5 = List(('a', 'b'), ('a', 'c'), ('a', 'e'), ('b', 'c'), ('c', 'd'), ('d', 'e'))
41+
val e5: List[Edge[Char, Nothing]] =
42+
List(('a', 'b'), ('a', 'c'), ('a', 'e'), ('b', 'c'), ('c', 'd'), ('d', 'e'))
4043
val v6 = ('A' to 'E').toList
41-
val e6 = List(('A', 'D'), ('A', 'E'), ('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'D'))
44+
val e6: List[Edge[Char, Nothing]] =
45+
List(('A', 'D'), ('A', 'E'), ('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'D'))
4246

43-
val g5 = Graph.buildUG(v5, e5.map((u, v) => Edge(u, v, None)))
44-
val g6 = Graph.buildUG(v6, e6.map((u, v) => Edge(u, v, None)))
47+
val g5 = Graph.buildUG(v5, e5)
48+
val g6 = Graph.buildUG(v6, e6)
4549
g5.isIsomorphicTo(g6) shouldBe true
4650

4751
val v7 = List('α', 'β', 'γ', 'δ', 'ε')
48-
val e7 = List(('α', 'β'), ('α', 'γ'), ('α', 'ε'), ('β', 'δ'), ('γ', 'δ'), ('δ', 'ε'))
49-
val g7 = Graph.buildUG(v7, e7.map((u, v) => Edge(u, v, None)))
52+
val e7: List[Edge[Char, Nothing]] =
53+
List(('α', 'β'), ('α', 'γ'), ('α', 'ε'), ('β', 'δ'), ('γ', 'δ'), ('δ', 'ε'))
54+
val g7 = Graph.buildUG(v7, e7)
5055
g5.isIsomorphicTo(g7) shouldBe false
5156
g6.isIsomorphicTo(g7) shouldBe false
5257

5358
val v8 = ('a' to 'f').toList
54-
val e8 = List(('a', 'b'), ('a', 'd'), ('b', 'c'), ('c', 'f'), ('d', 'e'), ('e', 'f'))
55-
val e9 = List(('a', 'd'), ('a', 'e'), ('b', 'd'), ('b', 'f'), ('c', 'e'), ('c', 'f'))
56-
val g8 = Graph.buildUG(v8, e8.map((u, v) => Edge(u, v, None)))
57-
val g9 = Graph.buildUG(v8, e9.map((u, v) => Edge(u, v, None)))
59+
val e8: List[Edge[Char, Nothing]] =
60+
List(('a', 'b'), ('a', 'd'), ('b', 'c'), ('c', 'f'), ('d', 'e'), ('e', 'f'))
61+
val e9: List[Edge[Char, Nothing]] =
62+
List(('a', 'd'), ('a', 'e'), ('b', 'd'), ('b', 'f'), ('c', 'e'), ('c', 'f'))
63+
val g8 = Graph.buildUG(v8, e8)
64+
val g9 = Graph.buildUG(v8, e9)
5865
g8.isIsomorphicTo(g9) shouldBe true
5966

6067
// G(v8 e8) and G(va ea) are not isomorphic but the algorithm can't determine that.
6168
// val va = [1..6]
6269
// val ea = [(1, 3), (1, 5), (2, 4), (2, 6), (3, 5), (4, 6)]
6370

6471
val v10 = ('A' to 'D').toList
65-
val e10 = List(('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D'))
66-
val v11 = (1 to 4).toList
67-
val e11 = List((1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4))
68-
val g10 = Graph.buildUG(v10, e10.map((u, v) => Edge(u, v, None)))
69-
val g11 = Graph.buildUG(v11, e11.map((u, v) => Edge(u, v, None)))
72+
val e10: List[Edge[Char, Nothing]] =
73+
List(('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D'))
74+
val v11 = (1 to 4).toList
75+
val e11: List[Edge[Int, Nothing]] = List((1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4))
76+
val g10 = Graph.buildUG(v10, e10)
77+
val g11 = Graph.buildUG(v11, e11)
7078
g10.isIsomorphicTo(g11) shouldBe true

graph/test/src/P86Spec.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ package graph
33
import org.scalatest.funspec.AnyFunSpec
44
import org.scalatest.matchers.should.Matchers.*
55
import P86.colorNodes
6+
import graph.Util.given
7+
import scala.language.implicitConversions
68

79
class P86Spec extends AnyFunSpec:
810
it("graph coloration"):
9-
val data = List(
11+
val data: List[(List[Char], List[Edge[Char, Nothing]])] = List(
1012
(
1113
('a' to 'j').toList,
1214
List(
@@ -50,7 +52,7 @@ class P86Spec extends AnyFunSpec:
5052
)
5153

5254
data.foreach { (vertices, edges) =>
53-
val g = Graph.buildUG(vertices, edges.map((u, v) => Edge(u, v, None)))
55+
val g = Graph.buildUG(vertices, edges)
5456
val clrMap = g.colorNodes.toMap
5557
vertices.foreach { u =>
5658
g.neighbors(u).map(v => clrMap(v._1)) should not contain (clrMap(u))

graph/test/src/Util.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package graph
2+
3+
object Util:
4+
given [A, B] => Conversion[Tuple, Edge[A, B]] =
5+
case (u, v) => Edge(u.asInstanceOf[A], v.asInstanceOf[A], None)
6+
case (u, v, d) => Edge(u.asInstanceOf[A], v.asInstanceOf[A], Some(d.asInstanceOf[B]))
7+
case _ => throw IllegalArgumentException(s"unsupported tuple")

0 commit comments

Comments
 (0)