0

I've been hitting my head against the wall for a while now...

The problem asks me to formulate this differentiation rule, applied to a byte array (the source should be overwritten), recursively, starting at the end of the array (derive.length - 1) and moving towards i=0. No second array should be used and the input-array should be overwritten. Below is the iterative version.

public static void derivative(byte[] derive) {
        
        for (int i = derive.length - 1; i > 0; i--) {
            
            if (i == 0 && derive[0] == 0) {
                derive[0] = 0;
            }
            
            if (i > 0 && derive[i] == derive[i-1]) {
                derive[i] = 0;
            }
            
            else {
                derive[i] = 1;
            }   
}

The algorithm in question applies the following ruleset to an array of binary numbers such as [1,0,1,1]: a[i] (the output version) should be equal to:

  • 0 if i=0 and a[i]=0
  • 0 if i>0 and a[i]=a[i-1]
  • 1 else

For example: {1,0,1,0,0} becomes: {1,1,1,1,0} and {0,1,1,0} becomes: {0,1,0,1}

How can I express this recursively?

  • Why would you want to express this recursively? _"moving towards i=1"_ -- do you mean `i==0`? Otherwise `0 if i=0 and a[i]=0` would never be true. Does the array modification happen in the original array or in a separate array (i.e. is `a[i]==a[i-1]` is aware of possible immediatlely prior modification of `a[i-1]`)? Your description implies no (output is in `b`) but the code overwrites the source. Lots of clarification needed. – Jim Garrison Jan 11 '21 at 21:34
  • It's an exercise I need to do :) doesn't make much sense to do it recursively... – Estamel Tharchon Jan 11 '21 at 21:36
  • Yes from the right to the left so a[i] to a[0] basically. The modification should happen in the original array. I wrote b as output because of the mathematical definition. Sorry for not being clear! The output should be the modified input array. – Estamel Tharchon Jan 11 '21 at 21:37
  • You should [edit] your question and put all the clarifications there. – Jim Garrison Jan 11 '21 at 21:39
  • It hath been done most expediently. Thank you for your help :) – Estamel Tharchon Jan 11 '21 at 21:40

2 Answers2

0
public static byte derivative(byte[] derive, int index) {
    byte curr = derive[index];
    
    if (index == 0) {
        derive[index] = 0;
        return curr;
    } elif (derive[index] == derivative(derive, index - 1)) {
        derive[index] = 0;
        return curr;
    }

    derive[index] = 1;
    return curr;
}

Edit: Modify return type

Caleb
  • 56
  • 5
  • Thank you for your help. Hmm this created a new array. It's a void method that doesn't return a value but just overwrites the input array. The problem is the derivative doesn't really depend on the value of the derivative to the left but rather on the value of the input array. This creates the problem of how to introduce a recursion given that the method can't call itself if it doesn't depend on it's own output... – Estamel Tharchon Jan 11 '21 at 21:53
  • Whoops, missed the return type in the function declaration. The return value is not the derivative of the left but rather the value that's currently in the array before modification. The function saves the current value in the input array and gets the previous value of the input array recursively, then changes the input value to 0 or 1. As far as overwriting the input array I'm not to sure about java and how it handles array passing as I believe it is just a reference so it should be similar to passing arrays in C/C++ allowing you to modify the contents in a function call like this. – Caleb Jan 11 '21 at 22:06
0

Your code actually does this:

public static void derivative(byte[] derive) {       
    for (int i = derive.length - 1; i > 0; i--) {
         derive[i] = derive[i] == derive[i-1] ? 0 : 1;
    }   
}

I would ask you to check this.

Which is more interesting, as it is so simple.

A better way would be to use bits, 8 bits per byte, or a long.

public static void derivative(byte[] derive) {
    long num = toBits(derive);
    num = (num >>> 1)^num;
    fromBits(bits, derive);
}

private static long bits(byte[] derive) {  
    long bits = 0;
    for (byte b : derive) {
        bits = (bits << 1) | (b == 0 ? 0 : 1);
    }
    return bits;
}

Using the following algorithm

{1,0,1,0,0} becomes:
{1,1,1,1,0}

10100

10100
 1010 shift right
----- xor
11110

The recursion of the simplified function at the top is trivial.

public static void derivative(byte[] derive) {       
    derivativeRecursively(derive, derive.length - 1);
}

private static void derivativeRecursively(byte[] derive, int i) {       
    ...   
}
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138