Skip to content

Instantly share code, notes, and snippets.

@oantolin
Created Mar 28, 2014
Embed
What would you like to do?
Help me make this Clojure code about as fast as Java, please!
(defn f [x y z n]
(+ (* 2 (+ (* x y) (+ (* y z) (* x z))))
(* 4 (+ x y z n -2) (- n 1))))
(defmacro from [[var ini cnd] & body]
`(loop [~var ~ini]
(when ~cnd
~@body
(recur (inc ~var)))))
(defn g [n]
(let [c (long-array (inc n))]
(from [x 1 (<= (f x x x 1) n)]
(from [y x (<= (f x y y 1) n)]
(from [z y (<= (f x y z 1) n)]
(from [k 1 (<= (f x y z k) n)]
(let [l (f x y z k)]
(aset c l (inc (aget c l))))))))
c))
(defn h [x]
(loop [n 1000]
(let [^longs c (g n)]
(if-let [k (some #(when (= x (aget c %)) %)
(range 1 (inc n)))]
k
(recur (* 2 n))))))
(time (println (h 1000)))
public class T {
static int f(int x, int y, int z, int n) {
return 2*(x*y+y*z+x*z) + 4*(x+y+z+n-2)*(n-1);
}
static int[] g(int n) {
int[] count = new int[n+1];
for (int x=1; f(x,x,x,1)<=n; x++)
for (int y=x; f(x,y,y,1)<=n; y++)
for (int z=y; f(x,y,z,1)<=n; z++)
for (int k=1; f(x,y,z,k)<=n; k++)
count[f(x,y,z,k)]++;
return count;
}
static int h(int x) {
for (int n=1000; true; n*=2) {
int[] v = g(n);
for (int i=1; i<=n; i++)
if (v[i]==x)
return i;
}
}
public static void main(String args[]) {
long t0 = System.currentTimeMillis();
System.out.println(h(1000));
long t1 = System.currentTimeMillis();
System.out.println(t1-t0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment