Permalink
Browse files

Solve problem 028

With Spiral class needed to be done.
  • Loading branch information...
xieweiking committed Oct 20, 2012
1 parent 9cecdd3 commit 85a65a5d4508107deea4f190006996aad156696a
Showing with 109 additions and 18 deletions.
  1. +6 −18 src/problem_028/Answer1.scala
  2. +25 −0 src/problem_028/Answer2.scala
  3. +19 −0 src/problem_028/Answer3.scala
  4. +59 −0 src/problem_028/Spiral.scala
@@ -1,28 +1,16 @@
package problem_028
-import common.Answer
+import common._
object Answer1 extends Answer {
- def answer = {
- val scale = 5
- val half = scale / 2
- val diagonalRange = -half to half
- val spiral = new Spiral(scale)
- var sum = 0
- for (i <- diagonalRange)
- sum += spiral(i, i)
- for (i <- diagonalRange if i != 0)
- sum += spiral(i, -i)
- sum
- }
-
- class Spiral(scale: Int) {
+ override def title = "Position to spiral number."
- def apply(x: Int, y: Int) = {
- 1
+ def answer = {
+ val spiral = Spiral(1001)
+ (0 /: spiral.diagonalPositions) { (sum, pos) =>
+ sum + spiral(pos._1, pos._2)
}
-
}
}
@@ -0,0 +1,25 @@
+package problem_028
+
+import common._
+
+object Answer2 extends Answer {
+
+ override def title = "Sum the sum of arithmetic sequense of every level with nthEven(leve) delta."
+
+ def answer = {
+ var prevMax = 1L // (0, 0)
+ var sum = prevMax
+ for (n <- 1 to seqCount(1001)) {
+ val (max, edge) = Spiral.maxAndEdgeOfLevel(n)
+ sum += sumOfArithmeticSeq(prevMax + edge, edge, max)
+ prevMax = max
+ }
+ sum
+ }
+
+ def seqCount(max: Int) = {
+ require(isOdd(max) && max >= 1)
+ (max - 1) / 2
+ }
+
+}
@@ -0,0 +1,19 @@
+package problem_028
+
+import common._
+
+object Answer3 extends Answer {
+
+ override def title = "Using formula."
+
+ def answer = (1 /: (3 to 1001 by 2)) { (sum, scale) =>
+ // top-right corner: scale^2 -> scale * scale
+ // top-left corner: scale^2 - (scale - 1) -> scale * scale - scale + 1
+ // bottom-left corner: scale^2 - 2(scale - 1) -> scale * scale - 2 * scale + 2
+ // bottom-right corner: scale^2 - 3(scale - 1) -> scale * scale - 3 * scale + 3
+ // sum of them: 4 * scale * scale - 6 * scale + 6
+ // -> ((scale * (2 * scale - 3) + 3) << 1)
+ sum + ((scale * (2 * scale - 3) + 3) << 1)
+ }
+
+}
@@ -0,0 +1,59 @@
+package problem_028
+
+import common._
+
+class Spiral(scale: Int) {
+
+ require(isOdd(scale) && scale > 0)
+
+ private lazy val half = scale / 2
+
+ def diagonalPositions = generator {
+ yield_return(0, 0)
+ var s = 1
+ while (s <= this.half) {
+ yield_return( s, -s)
+ yield_return(-s, -s)
+ yield_return(-s, s)
+ yield_return( s, s)
+ s += 1
+ }
+ }
+
+ def apply(x: Int, y: Int) = {
+ val (absX, absY) = (x.abs, y.abs)
+ require(absX <= this.half && absY <= this.half)
+ val (max, edge) = Spiral.maxAndEdgeOfLevel(absX max absY)
+ if (x == y) {
+ if (x >= 0) max
+ else max - 2 * edge // math.pow(even(absY), 2)
+ }
+ else if (absX == absY) {
+ if (x < 0) max - edge
+ else max - 3 * edge
+ }
+ else {
+ // TODO
+ 0
+ }
+ }
+
+ def apply(index: Int) = {
+ require(index >= 1)
+ // TODO
+ (0, 0)
+ }
+
+}
+
+object Spiral {
+
+ def apply(scale: Int) = new Spiral(scale)
+
+ def maxAndEdgeOfLevel(n: Int) = {
+ require(n >= 0)
+ val o = nthOdd(n)
+ (o * o, o - 1)
+ }
+
+}

0 comments on commit 85a65a5

Please sign in to comment.