From 73ea5e258719a47e6263c3429807d2271f0dea53 Mon Sep 17 00:00:00 2001 From: Sam De Backer Date: Wed, 3 Dec 2014 12:28:09 +0100 Subject: [PATCH] Solutions for #13 --- .../projecteuler/problems/Problem004.scala | 83 ++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/src/test/scala/org/bescala/projecteuler/problems/Problem004.scala b/src/test/scala/org/bescala/projecteuler/problems/Problem004.scala index 06ce8a1..53ea5c5 100644 --- a/src/test/scala/org/bescala/projecteuler/problems/Problem004.scala +++ b/src/test/scala/org/bescala/projecteuler/problems/Problem004.scala @@ -4,6 +4,8 @@ package org.bescala.projecteuler.problems import org.bescala.projecteuler.EulerSuite import org.bescala.projecteuler.ProjectEuler._ +import scala.annotation.tailrec + class Problem004 extends EulerSuite { /** @@ -24,7 +26,84 @@ class Problem004 extends EulerSuite { *find a good strategy. The 'fast' solution doesn't require tons of math... * */ - euler(problem(4)) { - TODO + + def isPalindromic(n: BigInt) = { + val s = n.toString + @tailrec def isPalindromicImpl(leftIndex: Int, rightIndex: Int): Boolean = { + if (leftIndex >= rightIndex) true + else (s.charAt(leftIndex) == s.charAt(rightIndex)) && isPalindromicImpl(leftIndex + 1, rightIndex - 1) + } + isPalindromicImpl(0, s.length - 1) + } + + val start = 999L + + euler(problem(4), "nested loops") { + var max = BigInt(1) + def find(start: BigInt): Long = { + for (i <- start to 1 by -1) { + for (j <- start to i by -1) { + val n = i * j + if (n > max && isPalindromic(n)) { + //println(s"$i x $j = $n") + max = n + } + } + } + max.toLong + } + find(start) + } + + euler(problem(4), "flatMap that shit") { + def find(start: BigInt): Long = { + var max = BigInt(1) + (start to 1 by -1).flatMap { i => + (start to i by -1).map { j => + val n = i * j + if (n > max && isPalindromic(n)) { + //println(s"$i x $j = $n") + max = n + n + } + } + } + max.toLong + } + find(start) + } + + euler(problem(4), "for-comprehension (with a trick)") { + def find(start: BigInt): Long = { + var max = BigInt(1) + (for { + i <- (start to 1 by -1) + j <- (start to i by -1) + n = i * j + if n > max && isPalindromic(n) && { max = n; true } // a trick to set the var max in the closure only if the tests succeed + //max = n // Will not work since the max here is local in the inner map, and not the var max in the closure! + } yield max.toLong).last + } + find(start) + } + + euler(problem(4), "from largest to smallest fastest solution") { + def find(start: BigInt): Long = { + for (n <- start to 1 by -1) { + for (k <- 0 to 1) { + var j = n - k + for (i <- n to start) { + val p = i * j + if (isPalindromic(p)) { + //println(s"$i x $j = $p") + return p.toLong + } + j -= 1 + } + } + } + 1L + } + find(start) } }