Restricted memory optimization The edit (or Levenshtein) distance between two strings is the minimal number of single character insertions, deletions and substitutions needed to transform one string into the other. If the two strings have length n each, it is well known that this can be done in O(n^2) time by dynamic programming. The following Python code performs this calculation for two strings s1 and s2.

def edit_distance(s1, s2):
    l1 = len(s1)
    l2 = len(s2)

    matrix = [range(l1 + 1)] * (l2 + 1)
    for zz in range(l2 + 1):
      matrix[zz] = range(zz,zz + l1 + 1)
    for zz in range(0,l2):
      for sz in range(0,l1):
        if s1[sz] == s2[zz]:
          matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz])
        else:
          matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz] + 1)
    return matrix[l2][l1]


In this task you have to get as close are you can to computing the edit distance but with a severe memory restriction. Your code is allowed to define one array containing 1000 32-bit integers and this is to be the only temporary storage you use in your computation.  All variables and data structures are to be contained in this array. In particular, you would not be able to implement the algorithm above as for strings of length 1000 as it would require you to store at least 1,000,000 numbers. Where your language doesn't naturally have 32 bit integers (for example Python) you simply need to make sure you never store a number larger than 2^32-1 in the array.  

You may read in the data using any standard library of your choice without worrying about the memory restrictions in that part. In order to make the competition fair for the main part of your code, you may only use operations that are functionally equivalent to those in the C programming language and cannot use any external libraries.

To be extra clear, the memory to store the input data or used by your language's interpreter, JVM etc. does not count towards your limit and you may not write anything to disk.  You must assume the input data is read-only when in memory so you can't reuse that to gain more working space.

What do I have to implement?

Your code should read in a file in the following format. It will have three lines. The first line is the true edit distance. The second is string 1 and the third is string 2.   I will test it with the sample data at https://bpaste.net/show/6905001d52e8 where the strings have length 10,000 but it shouldn't be specialised for this data. It should output the smallest edit distance it can find between the two strings.

You will also need to prove your edit distance actually comes from a valid set of edits. Your code should have a switch which turns it into a mode that may use more memory (as much as you like) and outputs the edit operations that give your edit distance.

Score 

Your score will be the (optimal edit distance/divided by the edit distance you find) * 100.  To start things off, notice that you can get a score by just counting the number of mismatches between the two strings.

You can use any language you like which is freely available and easy to install in Linux.

Tie break

In the case of a tie-break, I will run your code on my Linux machine and the fastest code wins.
C++   75.0
The program is designed to work with arbitrary text strings. They can be of any different lengths as long as neither exceeds 13824 characters. It uses 1,897 16-bit integers, which is equivalent to 949 32-bit integers. At first I was writing it in C, but then realized there was no function for reading a line.
The first command-line argument should be a filename. If a second argument exists, a summary of the edits is printed. The first line in the file is ignored while the second and third are the strings.
The algorithm is a doubly blocked version of the usual algorithm. It performs basically the same number of operations, but is of course much less accurate, since if a common subsequence gets split over the edge of a block, much of the potential savings are lost.
#include &lt;cstring&gt;
#include &lt;inttypes.h&gt;
#include &lt;iostream&gt;
#include &lt;fstream&gt;

#define M 24
#define MAXLEN (M*M*M)
#define SETMIN(V, X) if( (X) &lt; (V) ) { (V) = (X); }
#define MIN(X, Y) ( (X) &lt; (Y) ? (X) : (Y) )

char A[MAXLEN+1], B[MAXLEN+1];
uint16_t d0[M+1][M+1], d1[M+1][M+1], d2[M+1][M+1];

int main(int argc, char**argv)
{

    if(argc &lt; 2)
        return 1;

    std::ifstream fi(argv[1]);

    std::string Astr, Bstr;
    for(int i = 3; i--;)
        getline(fi, i?Bstr:Astr);
    if(!fi.good()) {
        printf(&quot;Error reading file&quot;);
        return 5;
    }
    if(Astr.length() &gt; MAXLEN || Bstr.length() &gt; MAXLEN) {
        printf(&quot;String too long&quot;);
        return 7;
    }

    strcpy(A, Astr.c_str());
    strcpy(B, Bstr.c_str());

    uint16_t lA = Astr.length(), lB = Bstr.length();
    if(!lA || !lB) {
        printf(&quot;%d\n&quot;, lA|lB);
        return 0;
    }
    uint16_t nbA2, nbB2, bA2, bB2, nbA1, nbB1, bA1, bB1, nbA0, nbB0, bA0, bB0; //block, number of blocks
    uint16_t iA2, iB2, iA1, iB1, jA2, jB2, jA1, jB1; //start, end indices of block

    nbA2 = MIN(M, lA);
    nbB2 = MIN(M, lB);
    for(bA2 = 0; bA2 &lt;= nbA2; bA2++) {
        iA2 = lA * (bA2-1)/nbA2,  jA2 = lA * bA2/nbA2;
        for(bB2 = 0; bB2 &lt;= nbB2; bB2++) {
            if(!(bA2|bB2)) {
                d2[0][0] = 0;
                continue;
            }
            iB2 = lB * (bB2-1)/nbB2,  jB2 = lB * bB2/nbB2;
            d2[bA2][bB2] = ~0;
            if(bB2)
                SETMIN(d2[bA2][bB2], d2[bA2][bB2-1] + (jB2-iB2));
            if(bA2)
                SETMIN(d2[bA2][bB2], d2[bA2-1][bB2] + (jA2-iA2));

            if(bA2 &amp;&amp; bB2) {
                nbA1 = MIN(M, jA2-iA2);
                nbB1 = MIN(M, jB2-iB2);
                for(bA1 = 0; bA1 &lt;= nbA1; bA1++) {
                    iA1 = iA2 + (jA2-iA2) * (bA1-1)/nbA1, jA1 = iA2 + (jA2-iA2) * bA1/nbA1;
                    for(bB1 = 0; bB1 &lt;= nbB1; bB1++) {
                        if(!(bA1|bB1)) {
                            d1[0][0] = 0;
                            continue;
                        }
                        iB1 = iB2 + (jB2-iB2) * (bB1-1)/nbB1, jB1 = iB2 + (jB2-iB2) * bB1/nbB1;
                        d1[bA1][bB1] = ~0;
                        if(bB1)
                            SETMIN(d1[bA1][bB1], d1[bA1][bB1-1] + (jB1-iB1));
                        if(bA1)
                            SETMIN(d1[bA1][bB1], d1[bA1-1][bB1] + (jA1-iA1));

                        if(bA1 &amp;&amp; bB1) {
                            nbA0 = jA1-iA1;
                            nbB0 = jB1-iB1;
                            for(bA0 = 0; bA0 &lt;= nbA0; bA0++) {
                                for(bB0 = 0; bB0 &lt;= nbB0; bB0++) {
                                    if(!(bA0|bB0)) {
                                        d0[0][0] = 0;
                                        continue;
                                    }
                                    d0[bA0][bB0] = ~0;
                                    if(bB0)
                                        SETMIN(d0[bA0][bB0], d0[bA0][bB0-1] + 1);
                                    if(bA0)
                                        SETMIN(d0[bA0][bB0], d0[bA0-1][bB0] + 1);
                                    if(bA0 &amp;&amp; bB0)
                                        SETMIN(d0[bA0][bB0], d0[bA0-1][bB0-1] + (A[iA1 + nbA0 - 1] != B[iB1 + nbB0 - 1]));
                                }
                            }
                            SETMIN(d1[bA1][bB1], d1[bA1-1][bB1-1] + d0[nbA0][nbB0]);
                        }
                    }
                }

                SETMIN(d2[bA2][bB2], d2[bA2-1][bB2-1] + d1[nbA1][nbB1]);
            }
        }
    }
    printf(&quot;%d\n&quot;, d2[nbA2][nbB2]);

    if(argc == 2)
        return 0;

    int changecost, total = 0;
    for(bA2 = nbA2, bB2 = nbB2; bA2||bB2; ) {
        iA2 = lA * (bA2-1)/nbA2,  jA2 = lA * bA2/nbA2;
        iB2 = lB * (bB2-1)/nbB2,  jB2 = lB * bB2/nbB2;
        if(bB2 &amp;&amp; d2[bA2][bB2-1] + (jB2-iB2) == d2[bA2][bB2]) {
            total += changecost = (jB2-iB2);
            char tmp = B[jB2];
            B[jB2] = 0;
            printf(&quot;%d %d deleted {%s}\n&quot;, changecost, total, B + iB2);
            B[jB2] = tmp;
            --bB2;
        } else if(bA2 &amp;&amp; d2[bA2-1][bB2] + (jA2-iA2) == d2[bA2][bB2]) {
            total += changecost = (jA2-iA2);
            char tmp = B[jA2];
            A[jA2] = 0;
            printf(&quot;%d %d inserted {%s}\n&quot;, changecost, total, A + iA2);
            A[jA2] = tmp;
            --bA2;
        } else {
            total += changecost = d2[bA2][bB2] - d2[bA2-1][bB2-1];
            char tmpa = A[jA2], tmpb = B[jB2];
            B[jB2] = A[jA2] = 0;
            printf(&quot;%d %d changed {%s} to {%s}\n&quot;, changecost, total, B + iB2, A + iA2);
            A[jA2] = tmpa, B[jB2] = tmpb;
            --bA2, --bB2;
        }
    }


    return 0;
}