Advertisement

Anyone heard of codility? (Automated Programming Assessment)

Started by February 20, 2010 04:13 PM
35 comments, last by janta 14 years, 8 months ago
Quote: Original post by nullsquared
Just something I found funny:


Funny how Java is sometimes tied or faster than C. Obviously, the 0.22 time is JVM startup.

Large pyramid is 0.268-0.220 = 0.48 vs. 0.56

And that is even without native compiler kicking in (1000/10000 calls of method).
Here was my solution (it is obvious I went for a more "fun" and less utilitarian approach to pad out some of the extra time I was given):

*EDIT: Solved the overflow thing. It got me the first time and I ended up with a 94. Seems I wasn't the only one. Kind of a kludge... Whatever.

#include <list>#include <algorithm>struct IsEquilibrium{   IsEquilibrium(long int tot, int &ind):total(tot),index(&ind){*index = -1;}   bool operator()(pair<long int, long int> element){      (*index)++;      return (element.first == (total - element.first - element.second));   }   long int total;   int *index;};struct Amounts{   Amounts():total(0),error(false){}   void operator()(const int &amount){      amounts.push_back(pair<long int, long int>(total, amount));      if((total + amount < total && amount > 0) || (total + amount > total && amount < 0)){         error = true;      }      total+=amount;   }   int getEquilibrium(){      if(error){return -1;}      int index;      if(find_if(amounts.begin(), amounts.end(), IsEquilibrium(total, index)) == amounts.end()){         index = -1;      }      return index;   }   list<pair<long int, long int> > amounts;   long int total;   bool error;};int equi ( const vector<int> &A ) {   Amounts totals;   return for_each(A.begin(), A.end(), totals).getEquilibrium();}


[Edited by - M2tM on February 21, 2010 7:01:34 AM]
_______________________"You're using a screwdriver to nail some glue to a ming vase. " -ToohrVyk
Advertisement
Python for me too :)
def equi(A):    lhs, rhs = 0, sum(A)    for i, e in enumerate(A):        rhs -= e        if lhs == rhs:            return i        lhs += e    return -1
How about PHP?

function equi ( $A ) {    $total = array_sum($A);    foreach($A as $key => $value){        if(($accumulated) == ($total - $accumulated - $value)){            return $key;        }        $accumulated += $value;    }    return -1;}


And &#106avascript (for this one I just implemented the solution presented by SiCrane in &#106avascript) (this keeps putting in [] around literal 0's when I use lang="&#106avascript"...)<br><br><!--STARTSCRIPT--><!--source lang="cpp"--><div class="source"><pre><br>function sum( A ) {<br> var result = <span class="cpp-number">0</span>;<br> <span class="cpp-keyword">for</span>(var i = <span class="cpp-number">0</span>;i &lt; A.length;i++) {<br> result += A<span style="font-weight:bold;"><br> }<br> <span class="cpp-keyword">return</span> result<br>}<br><br>function equi ( A ) {<br> var right = sum(A);<br> var left = <span class="cpp-number">0</span>;<br> <span class="cpp-keyword">for</span>(var i = <span class="cpp-number">0</span>;i &lt; A.length;i++){<br> right-=A<span style="font-weight:bold;">;<br> <span class="cpp-keyword">if</span>(left==right){<br> <span class="cpp-keyword">return</span> i;<br> }<br> left+=A<span style="font-weight:bold;">;<br> }<br> <span class="cpp-keyword">return</span> -<span class="cpp-number">1</span>;<br>}<br><br><br><br><br></pre></div><!--ENDSCRIPT-->
_______________________"You're using a screwdriver to nail some glue to a ming vase. " -ToohrVyk
Quote: Original post by Antheus
Funny how Java is sometimes tied or faster than C.

Logically, that doesn't make sense. The JVM is written in C++, therefore something written in Java can only be as fast or slower than the exact equivalent in C/C++.
Quote: Obviously, the 0.22 time is JVM startup.

That's not a bad point, though I'm willing to say that their timing method is not quite up to par.

Quote:
Large pyramid is 0.268-0.220 = 0.48 vs. 0.56

See above.

Quote: Original post by SiCrane
This was my Python attempt. It looks pretty similar to Sneftel's except that it doesn't special case the last iteration.
def equi ( A ):  a = 0  b = sum(A)  for i in range(len(A)):    b -= A    if a == b:      return i    a += A  return -1


If you look above, that was pretty much my exact first attempt, except that I special cased empty and size=1 arrays [smile] (which wasn't necessary, but it got my mind going [grin])
Quote: Original post by nullsquared
Logically, that doesn't make sense. The JVM is written in C++, therefore something written in Java can only be as fast or slower than the exact equivalent in C/C++.
That's not how Java VMs have worked for years. Google "just-in-time compilation".
Advertisement
In fact, notice how most of the measurements for the C version were 0s. The last one in C was either a fluke, or their Java measurements were inaccurate.

@ Sneftel: Not the point - the same code in Java won't JIT compile to something as efficient or more efficient than the same code in C. Though it'd be interesting to see proof that shows otherwise [smile].
Quote: Original post by nullsquared
In fact, notice how most of the measurements for the C version were 0s. The last one in C was either a fluke, or their Java measurements were inaccurate.


So you reject the reality and substitute your own? Your statement means that both Java and C version fluked on same test, and they were both pair-wise correct on every other test.

Quote: @ Sneftel: Not the point - the same code in Java won't JIT compile to something as efficient or more efficient than the same code in C. Though it'd be interesting to see proof that shows otherwise [smile].


Why not?

Since this is a trivial case, depending on how C code gets compiled, the Java version might put variables closer together, reducing number of cache misses. Just one or two cases as such and you've saved several hundred, perhaps even thousands of cycles.

Code hasn't been a bottleneck in a while now, memory is. And while it cannot be controlled, unless specifically managed in C, JVM might just result in slightly more optimal version, considering we're dealing with arrays, which Java can allocate in place, compared to List<> which requires instances of objects.

Quote: The JVM is written in C++, therefore something written in Java can only be as fast or slower than the exact equivalent in C/C++.

So C or C++ application can never be faster than something written in assembly?

Some assembly code can be faster than compiled C/C++ code.

BTW, do not underestimate JVM's design. When it comes to large application (1MLOC+), JVM will offer considerably better run-time characteristics than equivalent-effort C++ application precisely due to memory management. I mean this seriously, the micro overhead starts mattering surprisingly little above certain size, without even mentioning the difference in development time.

The biggest problem with Java is its legacy-ridden standard library and abysmal quality of third-party libraries. JVM however is fine, as demonstrated by JRuby, Clojure, Scala, etc... They are a whole different beast.
Quote: Original post by nullsquared
@ Sneftel: Not the point - the same code in Java won't JIT compile to something as efficient or more efficient than the same code in C.
JIT-compiled code can potentially run faster than optimized precompiled C, due to the ability of the compiler to dynamically recompile portions of the code in response to dynamic analysis as well as the specific processor it's running on.
Heh, that was fun.

This was my solution (C#):

int equi ( int[] A ) {         double totalSum = 0;         for (int i=0;i<A.Length;i++){        totalSum += A;    }         double currentSum = 0;         for (int i=0;i<A.Length;i++){             int current = A;        totalSum -= current;                 if (totalSum == currentSum) {            return i;        }        currentSum += current;    }         return -1;}


Time used: 12 minutes
Score: 100/100

This topic is closed to new replies.

Advertisement