Last active
August 29, 2015 14:00
-
-
Save scottchiang/11361665 to your computer and use it in GitHub Desktop.
Find smallest cube for which exactly five permutations of its digits are cube
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.collection.mutable | |
import scala.collection.mutable.MutableList | |
import scala.collection.immutable.IntMap | |
import scala.collection.JavaConversions.mapAsScalaMap | |
import scala.util.control.Breaks._ | |
// The run time for my code is roughly 120ms. I'm pretty sure I'm not understanding something about scala because when | |
// I implement this in ruby, it runs in around 20ms. I think I can improve performance by changing how I'm | |
// storing and updating values using HashMap. | |
object Cube { | |
def main(args: Array[String]) { | |
val start_time = System.nanoTime | |
val cubes = find_cube_perm | |
val time = (System.nanoTime - start_time) / 1e6 | |
println(time + "ms") | |
test_keys_for_permutation(cubes) | |
} | |
def find_cube_perm: MutableList[Long] = { | |
var start = 346 | |
// I'm storing the number of permutations in a HashMap. The key is determined using the get_hash_key function | |
// below. The value is a count which will be updated everytime a different permutation of a number appears. | |
// I'm using java HashMap instead of scala's mutable map because it performed ~20% better | |
var perms_count: mutable.Map[Long, Int] = new java.util.HashMap[Long, Int] | |
// I'm also storing the actual cubes in another HashMap so I can test the results. | |
var perm_identities: mutable.Map[Long, MutableList[Long]] = new java.util.HashMap[Long, MutableList[Long]] | |
var key = 0L | |
breakable { | |
while (true) { | |
var cube = math.pow(start, 3).toLong | |
key = get_hash_key(cube) | |
var count_at_key = perms_count getOrElse (key, 0) | |
count_at_key += 1 | |
perms_count(key) = count_at_key | |
var list_at_key = perm_identities getOrElse (key, MutableList()) | |
list_at_key += cube | |
perm_identities(key) = list_at_key | |
if(count_at_key == 5){ | |
break | |
} | |
start += 1 | |
} | |
} | |
println("Matching permutations are " + perm_identities(key)) | |
println("Smallest cube is " + perm_identities(key)(0)) | |
println("Smallest cube root is " + math.cbrt(perm_identities(key)(0).toLong).toInt) | |
perm_identities(key) | |
} | |
// this function will take a cube number and turn it into a hash key. I set up a list of 10 numbers to be combined | |
// to make a unique hash key for each set of permutation. I originally wanted to use a binary sequence but that would | |
// not produce unique values for me. I need an array of values differing by an order of magnitude to get unique hash | |
// keys. The hash key will be the sum of the keys list at the indices provided by the digits in the cube number. | |
// I started by using an IntMap but determined that a list has better performance. | |
def get_hash_key(n: Long) = { | |
// val keys = IntMap(0 -> 1, 1 -> 10, 2 -> 100, 3 -> 1000, 4 -> 10000, 5 -> 100000, 6 -> 1000000, 7 -> 10000000, 8 -> 100000000, 9 -> 1000000000) | |
val keys = List(1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000) | |
var key = 0 | |
var num = n | |
while (num > 0) { | |
var x = num % 10 | |
key += keys(x.toInt) | |
num /= 10 | |
} | |
key | |
} | |
// this is my test for 5 permutations which all have cube roots. | |
def test_keys_for_permutation(list: MutableList[Long]) = { | |
if(list.length == 5) { | |
println("there are 5 permutations") | |
} else { | |
println("the number of permutations is incorrect") | |
} | |
if((get_hash_key(list(0)) == get_hash_key(list(1))) && (get_hash_key(list(1)) == get_hash_key(list(2))) && (get_hash_key(list(2)) == get_hash_key(list(3))) && (get_hash_key(list(3)) == get_hash_key(list(4)))){ | |
println("all values are permutations of each other") | |
} else { | |
println("fail") | |
} | |
} | |
} | |
// Response | |
// Matching permutations are MutableList(127035954683, 352045367981, 373559126408, 569310543872, 589323567104) | |
// Smallest cube is 127035954683 | |
// Smallest cube root is 5027 | |
// 120.625ms | |
// there are 5 permutations | |
// all values are permutations of each other |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment