Skip to content

Instantly share code, notes, and snippets.

@mkulak
Created June 12, 2012 06:45
Show Gist options
  • Save mkulak/2915660 to your computer and use it in GitHub Desktop.
Save mkulak/2915660 to your computer and use it in GitHub Desktop.
Darkus June FP contest solution
import io.Source
object Stars {
type Point = Array[Int]
type Tree = Array[Array[Array[List[Point]]]]
def main(args:Array[String]) {
val start:Long = System.nanoTime()
val coords = Source.fromFile("stars.dat").getLines().map(s => s.split("\\s+").map(_.toInt)).toArray
var minDistance = Long.MaxValue
var s1:Point = Array(-1, -1, -1)
var s2:Point = Array(-1, -1, -1)
var maxC = 0
for (c <- coords) {
for (p <- c) {
maxC = p max maxC
}
}
val part: Int = 100
val div = maxC / part
val tree:Tree = Array.fill(part + 1, part + 1, part + 1)({List.empty[Point]})
val neighbours = for (x <- Array(-1, 0, 1); y <- Array(-1, 0, 1); z <-Array(-1, 0, 1)) yield (x, y, z)
for (c <- coords) {
val i = c(0) / div
val j = c(1) / div
val k = c(2) / div
for (t <- neighbours) {
val x = t._1 + i
val y = t._2 + j
val z = t._3 + k
if (x >= 0 && x < tree.length && y >= 0 && y < tree.length && z >= 0 && z < tree.length) {
tree(x)(y)(z) = c :: tree(x)(y)(z)
}
}
}
for (i <- 0 until tree.length; j <- 0 until tree(i).length; k <- 0 until tree(i)(j).length) {
val group = tree(i)(j)(k).toArray
val (localMin, localS1, localS2) = solve(group)
if (localMin < minDistance) {
minDistance = localMin
s1 = localS1
s2 = localS2
}
}
val total = System.nanoTime() - start
println("distance " + math.sqrt(minDistance))
println("A(" + s1.mkString(", ") + ")")
println("B(" + s2.mkString(", ") + ")")
println("time elapsed: " + total / 1000000 + " ms")
}
def solve(points: Array[Point]):Tuple3[Long, Point, Point] = {
var min = Long.MaxValue
var s1:Point = null
var s2:Point = null
for (i <- 0 until points.length; j <- (i + 1) until points.length) {
val d = distance(points(i), points(j))
if (d < min) {
min = d
s1 = points(i)
s2 = points(j)
}
}
(min, s1, s2)
}
def distance(a:Point, b:Point):Long = {
val dx:Long = a(0) - b(0)
val dy:Long = a(1) - b(1)
val dz:Long = a(2) - b(2)
dx * dx + dy * dy + dz* dz
}
}
//distance 85.98255637046388
//A(637999, 813818, 458335)
//B(637957, 813791, 458265)
//time elapsed: 78541 ms
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment