Saturday, July 26, 2014

Problem 92 - X10

So, working on another problem. I found X10 through yet another google search, this time specifically for languages that run on the JVM, because why not. X10 is an object oriented languages developed by IBM that, yes, runs on the JVM. I ended up accidentally installing an IDE for x10 from the website (x10dt apparently means "X10 developer tools" which means "an IDE for X10"), so I used that instead of just using a command line compiler, and the IDEs copious red lines resultsd in all my errors being caught while I was writing, meaning that my pace of writing was slowed down. Overall the language wasn't too hard to pick up, having very Java-like syntax, though actually its Javaness led to my first bit of confusion...not knowing to use the new operator...but other than silly things like that, I had working code relatively quickly.

After I had working code, there were still issues. The code ran slowly, and it took me about 5 minutes to figure out how to stop execution of code in the IDE (pressing "run" again only made it run the program twice concurrently!) And in addition pressing run does not auto-save, which took a while to notice. The last big issue was an interesting one...I was accidentally allocating the "prev" array each time through the loop, which turns out to have been incredibly costly. After I moved to allocating it once instead of ten million times, my code's execution time went from about 5 minutes to do 10% of the search space to almost instant (I say almost instant because, again, IDE, so I don't have real timing data). Anyway, my X10 code is below:

(Small indents because I wrote it in the IDE which seems to have unfortunately used tabs instead of spaces).

public class e92 {

 public static def getBit(r:Rail[Long], x:Long) {
  val index    = x / 64;
  val subIndex = x % 64;
  return ((r(index) >> subIndex) & 1) == 1;
 }
 
 public static def setBit(r:Rail[Long], x:Long) {
  val index    = x / 64;
  val subIndex = x % 64;
  r(index) = r(index) | (1L << subIndex);
 }
 
 public static def nextTerm(x: Long) {
  var c:Long = x;
  var s:Long = 0;
  while (c > 0) {
   s += (c % 10) * (c % 10);
   c /= 10;
  }
  return s;
 }
    public static def main(Rail[String]) {
     // Pair of arrays for memoizing to store
     // if we have info, and if it goes to 89
        var isSet:Rail[Long] = new Rail[Long](10000000 / 64);
        isSet.fill(0);
        var is89:Rail[Long]  = new Rail[Long](10000000 / 64);
        is89.fill(0);
        setBit(isSet, 1);
        setBit(isSet, 89);
        setBit(is89, 89);
        var ans:Long = 1;
        var prev:Rail[Long] = new Rail[Long](100000);
        for (i in 1..9999999) {
         var pLength:Long = 0;
         var c:Long = i;
         while (! getBit(isSet, c)) {
          prev(pLength) = c;
          pLength      += 1;
          c = nextTerm(c);
         }
         var was89:Boolean = getBit(is89, c);
         for (j in 0..(pLength - 1)) {
          setBit(isSet, prev(j));
          if (was89) {
           setBit(is89, prev(j));
           ans += 1;
          }
         }
        }
        Console.OUT.println(ans);
    }
}

No comments:

Post a Comment