-
Notifications
You must be signed in to change notification settings - Fork 46
/
Copy pathscala.scala
70 lines (53 loc) · 1.84 KB
/
scala.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
object LPath extends App {
def readPlaces:Array[Node] = {
val lines = scala.io.Source.fromFile("agraph").getLines().drop(1)
val linesOfInts = lines.map(_.split(" ").map(_.toInt))
val linesById = linesOfInts.toSeq.groupBy(_.apply(0))
linesById.map { lines =>
val (nodeId, nodeLines) = lines
val neighbors = nodeLines.map { neighborLine =>
neighborLine(1) -> neighborLine(2)
}.toMap
Node(nodeId, neighbors)
}.toArray.sortBy(_.id)
}
val nodes = readPlaces
case class Neighbor(id:Int, neighbor:Node, cost:Int)
case class Node(id:Int, neighborIds:Map[Int,Int]) {
lazy val neighbors = neighborIds.map(n => Neighbor(n._1, nodes(n._1),n._2)).toArray
}
@inline def max(a:Int,b:Int) = if (a >= b) a else b
def longestPath(nextNode:Node, visited:Array[Boolean], dist:Int):Int = {
val nnid = nextNode.id
val ns = nextNode.neighbors
var m = 0
var i = 0
val icount = ns.length
visited(nnid) = true
while(i < icount) {
val n = ns(i)
if(!visited(n.id)) {
m = max(m,n.cost + longestPath(n.neighbor, visited, dist))
}
i = i + 1
}
visited(nnid) = false
m
}
def longestPath_functional(nextNode:Node, visited:scala.collection.immutable.BitSet, dist:Int):Int = {
nextNode.neighbors.foldLeft(0) {
case (lastMax, Neighbor(id,node,_)) if visited.contains(node.id) =>
max(lastMax,dist)
case (lastMax, Neighbor(id,node,cost)) =>
max(lastMax,longestPath_functional(node,visited + node.id,dist + cost))
}
}
//warm up
for(i <- 1 to 10) {
longestPath(nodes(0), new Array[Boolean](nodes.size), 0)
}
val start = System.nanoTime()
val len = longestPath(nodes(0), new Array[Boolean](nodes.size), 0)
val duration = (System.nanoTime() - start) / 1000000
println(s"$len LANGUAGE Scala $duration")
}