fixed #17 by using caching, thus reducing O(n^3) to O(1) :)