Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

The array size is <= 16. The difference is defined as:

diff[i] = array[i+1] - array[i];

I need to find the number of permutations of the original array, which have a difference that is a permutation of the difference of the original array.

This is my code:

public class Main {
    Scanner scan = new Scanner(System.in);
    int N;
    int [] array_base;
    int [] first_diff;
    int result;

    public static void main(String[] args) {
        Main main = new Main();
        main.read();
        main.run();
    }

    void read() {
        N = scan.nextInt();
        array_base = new int [N];
        for (int i = 0; i<N; i++) {
            array_base[i] = scan.nextInt();
        }
        first_diff = first_difference();
    }

    int [] first_difference() {
        int [] temp = new int [N-1];
        for (int i=0; i < N-1; i++) {
            temp[i] = array_base[i+1] - array_base[i];
        }
        return temp;
    }

    void run() {
        permute(array_base,0);
        System.out.println(Integer.toString(result));
    }

    public void permute(int[] array, int k)
    {
        for(int i=k; i<array.length; i++)
        {
            int temp;
            temp = array[i];
            array[i] = array[k];
            array[k] = temp;
            permute(array, k+1);
            int temp2;
            temp2 = array[i];
            array[i] = array[k];
            array[k] = temp2;
        }
        if (k == array.length-1)
        {
            calculate(array);
        }
    }

    void calculate(int [] array) {
        int [] diff_values = new int [array.length-1];
        for (int i = 0; i < array.length-1; i++) {
            diff_values[i] = array[i+1] - array[i];
        }
        compare(diff_values);
    }

    void compare(int [] values) {
        boolean [] used_new = new boolean [values.length];
        boolean [] used_first = new boolean [values.length];
        for (int i = 0; i < values.length; i++) {
            used_new[i] = false;
            used_first[i] = false;
        }
        for (int i = 0; i < values.length; i++) {
            for (int j = 0; j < values.length; j++) {
                if (used_new[j]) {
                }
                else if (first_diff[i] == values[j]) {
                        used_new[j] = true;
                        used_first[i] = true;
                        break;
                }
            }
            if (used_first[i] == false) break;
        }
        if (areAllTrue(used_new) && areAllTrue(used_first)) {
            result += 1;
        }
    }

    public boolean areAllTrue(boolean[] array)
    {
        for(boolean b : array) if(!b) return false;
        return true;
    }



}

I do, however, see that this code is not fast as it could be. Could anyone give me some advice on how to speed it up?

share|improve this question
    
Can you please provide some examples of input/output ? –  Josay Mar 13 '14 at 15:38
    
Input: 9 1 4 2 5 7 6 9 8 3 Output: 8 –  Simon Mar 13 '14 at 17:48
    
I tried to have a new look at your question again and still cannot understand what you are trying to achieve. Would you mind giving more details about your examples (like giving explicitly the 8 permutations) ? –  Josay Mar 14 '14 at 23:05

1 Answer 1

You are using a class just to be able to able to mess with some kind of global values. This makes your code very hard to understand. It took me a while to unroll it all and get the following code :

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        run(read());

        run(fake_read());
    }

    static int[] fake_read() {
        int[] a = {1, 4, 2, 5, 7, 6, 9, 8, 3};
        return a;
    }

    static int[] read() {
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        int [] array = new int [N];
        for (int i = 0; i<N; i++) {
            array[i] = scan.nextInt();
        }
        return array;
    }

    static int [] first_difference(int[] array) {
        int N = array.length;
        int [] temp = new int [N-1];
        for (int i=0; i < N-1; i++) {
            temp[i] = array[i+1] - array[i];
        }
        return temp;
    }

    static void run(int[] array) {
        int [] first_diff = first_difference(array);
        int n = permute(array,0, first_diff);
        System.out.println(Integer.toString(n));
    }

    static public int permute(int[] array, int k, int [] first_diff)
    {
        int result = 0;
        for(int i=k; i<array.length; i++)
        {
            int temp = array[i];
            array[i] = array[k];
            array[k] = temp;
            result += permute(array, k+1, first_diff);
            temp  = array[i];
            array[i] = array[k];
            array[k] = temp;
        }
        if (k == array.length-1)
        {
            result += calculate(array, first_diff);
        }
        return result;
    }

    static int calculate(int [] array, int [] first_diff) {
        int [] diff_values = new int [array.length-1];
        for (int i = 0; i < array.length-1; i++) {
            diff_values[i] = array[i+1] - array[i];
        }
        return compare(diff_values, first_diff);
    }

    static int compare(int [] values, int [] first_diff) {
        int result = 0;
        boolean [] used_new = new boolean [values.length];
        boolean [] used_first = new boolean [values.length];
        for (int i = 0; i < values.length; i++) {
            used_new[i] = false;
            used_first[i] = false;
        }
        for (int i = 0; i < values.length; i++) {
            for (int j = 0; j < values.length; j++) {
                if (!used_new[j] && first_diff[i] == values[j]) {
                        used_new[j] = true;
                        used_first[i] = true;
                        break;
                }
            }
            if (!used_first[i]) break;
        }
        if (areAllTrue(used_new) && areAllTrue(used_first)) {
            result += 1;
        }
        return result;
    }

    static public boolean areAllTrue(boolean[] array)
    {
        for(boolean b : array) if(!b) return false;
        return true;
    }
}

I'll be honest with you, I was hoping that once this was done, I'd be facing something somewhat easier to understand but it is not the case (the poor documentation and the function names do not help at all). I guess one could find a simpler (and faster ?) solution but the thing is that I don't even understand what is expected. The question might need clarification.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.