4

I came across this awesome problem and tried to solve it in scala in order to learn the language. The short explanation of the problem is in the title and here's a longer explanation http://www.mathblog.dk/project-euler-62-cube-five-permutations/.

I solved it in Javascript and tried to transfer the logic to scala but it doesn't quite work. It works for finding 3 permutations but not 4, 5 and probably upwards.

Here's the code:

import collection.mutable.Map
import collection.mutable.{Map => MMap}

val mutMap3 = MMap.empty[String, MMap[String, Int]]
def pow(n:Int) : Int =  { 
  val cubed = (n * n * n).toString
  val digits = 0 to 9
  var str = ""
  for (a <- digits) {
    val b = cubed.count(_.toString==a.toString)
    str += b
  }
  if (mutMap3 contains str) {
    mutMap3(str)("len") += 1
    if(mutMap3(str)("len") == 5) {
      return mutMap3(str)("first")
    }
  } else {
    mutMap3(str) = MMap("len" -> 1, "first" -> n)
  }
  return pow(n+1)
}

My idea was that since a permutation is just a rearrangement of the order, (i.e. 4233 is a permutation of 3234), then you can just count the number of times each number occurs and that will represent all possible permutations. In the permutation of 4233, "0" occurs 0 times, "1" occurs 0 times, "2" occurs 2 times, "4" occurs 1 time, "5" occurs 0 times...etc all the way up to 9, which can be put in a string as "0012100000" as the number of occurrences of integers "0123456789" (both 4233 and 3234, and all other combinations of "2","3", and "4" can be represented as "0012100000"). So in plain English, take a number, cube it, turn it into a string of occurrences of particular integers, store that and count how many times we see it as we keep calling the function with number + 1 until a specific permutation occurs 5 times, then return the number from the first time we got that permutation.

I'd like to see alternative approaches but I'd really like to know why mine doesn't work and whether or not it is a good approach. Have fun!

natecraft1
  • 2,737
  • 9
  • 36
  • 56
  • 2
    There is method `permutations` in scala collections: `323.toString.permutations.map{ _.toLong }.toSet - 323` => `Set(332, 233)` – senia Feb 12 '14 at 07:58
  • do I have to import something to get that method? im just trying stuff on simplyscala.com and it says that method doesnt exist. – natecraft1 Feb 12 '14 at 18:11

1 Answers1

1

Not particularly efficient but concise:

scala> val cubes=(0 to 5030).map(c=>c.toLong*c*c).toSet

cubes: scala.collection.immutable.Set[Long] = Set(2628072, ...

scala> cubes.par.filter(_.toString.permutations.map(_.toLong).filter(cubes.contains(_)).length==5)

res6: scala.collection.parallel.immutable.ParSet[Long] = ParSet(38614472000, 10648000000, 10403062487, 91125000000, 65939264000, 54439939000, 95443993000, 122763473000, 116500279104, 114791256000, 40920960536, 103823000000)
Mark Lister
  • 1,103
  • 6
  • 16