Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you replace Java nested for loops in Clojure?

Tags:

clojure

I have created a very simple nested loop example and am struggling to write the equivalent Clojure code. I've been trying to do it by list comprehensions but cannot get the same answer. Any help appreciated.

public class Toy {

    public static void main(String[] args) {
        int maxMod = 0;
        for (int i=0;i<1000;i++) {
            for (int j=i;j<1000;j++) {
                if ((i * j) % 13 == 0 && i % 7 == 0) maxMod = i * j;
            }
        }
        System.out.println(maxMod);
    }
}
like image 516
deltanovember Avatar asked Feb 04 '12 01:02

deltanovember


People also ask

Can you do nested for loops in Java?

In fact, there can be any type of loop nested inside any type and to any level. Syntax: do{ while(condition) { for ( initialization; condition; increment ) { // statement of inside for loop } // statement of inside while loop } // statement of outer do-while loop }while(condition);

Are nested for loops necessary?

Nested loops are extraordinarily useful when you have two different arrays that need to be looped through the same function, looping different arrays into properties of various objects, when you need a “2D” array (x and y-axis), and the list goes on.


2 Answers

Here's a list comprehension solution:

(last 
  (for [i (range 1000) 
        j (range 1000)
        :let [n (* i j)] 
        :when (and (= (mod n 13) 0) 
                   (= (mod i 7) 0))] 
    n))
like image 118
dnolen Avatar answered Sep 23 '22 10:09

dnolen


In general, you want to use some sort of sequence operation (like dnolen's answer). However, if you need to do something that is not expressible in some combination of sequence functions, using the loop macro works as well. For this precise problem, dnolen's answer is better than anything using loop, but for illustrative purposes, here is how you would write it with loop.

(loop [i 0
       max-mod 0]
  (if (>= i 1000)
    (println max-mod)
    (recur (inc i)
           (loop [j 0
                  max-mod max-mod]
             (if (>= j 1000)
               max-mod
               (recur (inc j)
                      (if (and (= (mod (* i j) 13) 0)
                               (= (mod 1 7) 0))
                        (* i j)
                        max-mod)))))))

This is pretty much an exact translation of your given code. That said, this is obviously ugly, which is why a solution using for (or other similar functions) is preferred whenever possible.

like image 34
Retief Avatar answered Sep 21 '22 10:09

Retief