// File: /workspace/github_cpp_makefile_star2_O1/medvedevgroup[P]varmatch/src/wholegenome.cpp
// Function: WholeGenome::needleman_wunsch(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&)
int WholeGenome::needleman_wunsch(string S1, string S2, string &R1, string &R2)
{
    int M = S1.length();
    int N = S2.length();
    /*
    0MMMMMMMMMMMMMMMM
    N
    N
    N
    N
    N
    N
    so the matrix is N*M
    */
    int **score = new int *[N+1];
    for (int i = 0; i <= N; i++)
    {
        score[i] = new int [M+1];
    }

    char **trackBack = new char *[N+1];
    // * for match, - for ->, | for moving downward
    for (int i = 0; i <= N; i++)
    {
        trackBack[i] = new char [M+1];
    }
    R1 = "";
    R2 = "";
    initialize_score_matrix(score, trackBack, M, N);

    for (int i = 1; i <=N; i++)
    {
        for (int k = 1; k <= M; k++)
        {
            char S1_k = S1[k-1];
            char S2_i = S2[i-1];
            int matchingCost = score[i-1][k-1];
            if(S1_k != S2_i) matchingCost--;
            int rightCost = score[i][k-1] - 1;
            int downCost = score[i-1][k] - 1;
            if (matchingCost > rightCost && matchingCost > downCost)
            {
                score[i][k] = matchingCost;
                trackBack[i][k] = '*';
            }else if(rightCost >= downCost)
            {
                score[i][k] = rightCost;
                trackBack[i][k] = '-';
            }else
            {
                score[i][k] = downCost;
                trackBack[i][k] = '|';
            }
        }
    }

    //trackBack
    int n = N;
    int m = M;
    while(n > 0 || m > 0)
    {
        if (trackBack[n][m] == '*')
        {
            R1 += S1[m-1];
            R2 += S2[n-1];
            n--;
            m--;
        }else if(trackBack[n][m] == '-')
        {
            R1 += S1[m-1];
            R2 += '-';
            m--;
        }else if(trackBack[n][m] == '|')
        {
            R1 += '-';
            R2 += S2[n-1];
            n--;
        }
    }
    reverse(R1.begin(), R1.end());
    reverse(R2.begin(), R2.end());

    int result = score[N][M];

    for (int i = 0; i <= N; i++)
    {
        delete score[i];
        delete trackBack[i];
    }

    delete score;
    delete trackBack;

    return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %r8, 0x20(%rsp)
movq %rcx, 0x18(%rsp)
movq %rdx, %r13
movq %rsi, %rbp
movabsq $0x100000000, %rcx      # imm = 0x100000000
movq 0x8(%rsi), %rax
movq %rax, 0x10(%rsp)
movq 0x8(%rdx), %r14
movq %r14, %rax
shlq $0x20, %rax
movq %rax, 0x30(%rsp)
addq %rcx, %rax
movq %rax, %rdi
sarq $0x1d, %rdi
testq %rax, %rax
movq $-0x1, %r15
cmovsq %r15, %rdi
movq %rdi, 0x28(%rsp)
callq 0x5030
movq %rax, %rbx
movq %r14, 0x8(%rsp)
testl %r14d, %r14d
js 0x13c0a
movq 0x10(%rsp), %rax
shlq $0x20, %rax
movabsq $0x100000000, %rcx      # imm = 0x100000000
addq %rcx, %rax
movq %rax, %rcx
sarq $0x1e, %rcx
testq %rax, %rax
cmovnsq %rcx, %r15
movq 0x8(%rsp), %rax
leal 0x1(%rax), %r12d
xorl %r14d, %r14d
movq %r15, %rdi
callq 0x5030
movq %rax, (%rbx,%r14,8)
incq %r14
cmpq %r14, %r12
jne 0x13bf6
movq 0x28(%rsp), %rdi
callq 0x5030
movq %rax, %r14
cmpl $0x0, 0x8(%rsp)
js 0x13c5d
movq 0x10(%rsp), %r15
shlq $0x20, %r15
movabsq $0x100000000, %rax      # imm = 0x100000000
addq %rax, %r15
sarq $0x20, %r15
movq 0x8(%rsp), %rax
incl %eax
movq %rax, 0x28(%rsp)
xorl %r12d, %r12d
movq %r15, %rdi
callq 0x5030
movq %rax, (%r14,%r12,8)
incq %r12
cmpq %r12, 0x28(%rsp)
jne 0x13c47
movq 0x18(%rsp), %rdi
movq 0x8(%rdi), %rdx
leaq 0x1d955(%rip), %r15     # 0x315c2
xorl %r12d, %r12d
xorl %esi, %esi
movq %r15, %rcx
xorl %r8d, %r8d
callq 0x54b0
movq 0x20(%rsp), %rdi
movq 0x8(%rdi), %rdx
xorl %esi, %esi
movq %r15, %rcx
xorl %r8d, %r8d
callq 0x54b0
movq 0x10(%rsp), %r15
testl %r15d, %r15d
js 0x13cbc
leal 0x1(%r15), %eax
xorl %ecx, %ecx
movq (%rbx), %rdx
movl %r12d, (%rdx,%rcx,4)
movq (%r14), %rdx
movb $0x2d, (%rdx,%rcx)
incq %rcx
decl %r12d
cmpq %rcx, %rax
jne 0x13ca3
movq 0x8(%rsp), %r11
testl %r11d, %r11d
js 0x13ce5
leal 0x1(%r11), %eax
xorl %ecx, %ecx
xorl %edx, %edx
movq (%rbx,%rdx,8), %rsi
movl %ecx, (%rsi)
movq (%r14,%rdx,8), %rsi
movb $0x7c, (%rsi)
incq %rdx
decl %ecx
cmpq %rdx, %rax
jne 0x13cce
movq (%r14), %rax
movb $0x2a, (%rax)
testl %r11d, %r11d
jle 0x13d8a
leal 0x1(%r15), %eax
leal 0x1(%r11), %ecx
decq %rax
movl $0x1, %edx
testl %r15d, %r15d
jle 0x13d7e
xorl %esi, %esi
movq (%rbp), %rdi
movb (%rdi,%rsi), %dil
movq (%r13), %r8
xorl %r9d, %r9d
cmpb -0x1(%r8,%rdx), %dil
setne %r9b
movq -0x8(%rbx,%rdx,8), %r8
movq (%rbx,%rdx,8), %rdi
movl (%r8,%rsi,4), %r10d
subl %r9d, %r10d
movl 0x4(%r8,%rsi,4), %r8d
movl (%rdi,%rsi,4), %r9d
cmpl %r9d, %r10d
jl 0x13d50
cmpl %r8d, %r10d
jl 0x13d50
movl %r10d, 0x4(%rdi,%rsi,4)
movb $0x2a, %dil
jmp 0x13d6d
cmpl %r8d, %r9d
jge 0x13d62
decl %r8d
movl %r8d, 0x4(%rdi,%rsi,4)
movb $0x7c, %dil
jmp 0x13d6d
decl %r9d
movl %r9d, 0x4(%rdi,%rsi,4)
movb $0x2d, %dil
movq (%r14,%rdx,8), %r8
movb %dil, 0x1(%r8,%rsi)
incq %rsi
cmpq %rsi, %rax
jne 0x13d0b
incq %rdx
cmpq %rcx, %rdx
jne 0x13d04
testl %r11d, %r11d
setg %al
testl %r15d, %r15d
setg %cl
orb %al, %cl
cmpb $0x1, %cl
jne 0x13e51
movq 0x10(%rsp), %rax
movl %eax, %edx
movq 0x8(%rsp), %rax
movl %eax, %ecx
movslq %ecx, %r15
movq (%r14,%r15,8), %rax
movslq %edx, %r12
movzbl (%rax,%r12), %eax
cmpl $0x7c, %eax
je 0x13e10
cmpl $0x2d, %eax
je 0x13df2
cmpl $0x2a, %eax
jne 0x13e41
movq (%rbp), %rax
movsbl -0x1(%rax,%r12), %esi
decq %r12
movq 0x18(%rsp), %rdi
callq 0x52d0
movq (%r13), %rax
movb -0x1(%rax,%r15), %al
decq %r15
jmp 0x13e0e
movl %ecx, %r15d
movq (%rbp), %rax
movsbl -0x1(%rax,%r12), %esi
decq %r12
movq 0x18(%rsp), %rdi
callq 0x52d0
movb $0x2d, %al
jmp 0x13e2e
movl %edx, %r12d
movq 0x18(%rsp), %rdi
movl $0x2d, %esi
callq 0x52d0
movq (%r13), %rax
movb -0x1(%rax,%r15), %al
decq %r15
movsbl %al, %esi
movq 0x20(%rsp), %rdi
callq 0x52d0
movl %r15d, %ecx
movl %r12d, %edx
testl %ecx, %ecx
jg 0x13daf
testl %edx, %edx
jg 0x13daf
movq 0x18(%rsp), %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rcx
testq %rcx, %rcx
setne %dl
addq %rax, %rcx
decq %rcx
cmpq %rax, %rcx
seta %sil
andb %dl, %sil
cmpb $0x1, %sil
jne 0x13e97
incq %rax
movb -0x1(%rax), %dl
movb (%rcx), %sil
movb %sil, -0x1(%rax)
movb %dl, (%rcx)
decq %rcx
leaq 0x1(%rax), %rdx
cmpq %rcx, %rax
movq %rdx, %rax
jb 0x13e7c
movq 0x20(%rsp), %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rcx
testq %rcx, %rcx
setne %dl
addq %rax, %rcx
decq %rcx
cmpq %rax, %rcx
seta %sil
andb %dl, %sil
cmpb $0x1, %sil
movq 0x8(%rsp), %r12
movq 0x10(%rsp), %rdi
jne 0x13ee7
incq %rax
movb -0x1(%rax), %dl
movb (%rcx), %sil
movb %sil, -0x1(%rax)
movb %dl, (%rcx)
decq %rcx
leaq 0x1(%rax), %rdx
cmpq %rcx, %rax
movq %rdx, %rax
jb 0x13ecc
movq 0x30(%rsp), %rax
sarq $0x1d, %rax
movq (%rbx,%rax), %rax
movslq %edi, %rcx
movl (%rax,%rcx,4), %ebp
testl %r12d, %r12d
js 0x13f33
incl %r12d
xorl %r15d, %r15d
movq (%rbx,%r15,8), %rdi
testq %rdi, %rdi
je 0x13f18
movl $0x4, %esi
callq 0x5340
movq (%r14,%r15,8), %rdi
testq %rdi, %rdi
je 0x13f2b
movl $0x1, %esi
callq 0x5340
incq %r15
cmpq %r15, %r12
jne 0x13f05
movl $0x8, %esi
movq %rbx, %rdi
callq 0x5340
movl $0x8, %esi
movq %r14, %rdi
callq 0x5340
movl %ebp, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq