// File: /workspace/github_cpp_makefile_star2_O3/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 $0x48, %rsp
movq %r8, 0x28(%rsp)
movq %rcx, 0x10(%rsp)
movq %rdx, %r13
movq %rsi, %rbp
movabsq $0x100000000, %rcx      # imm = 0x100000000
movq 0x8(%rsi), %r15
movq 0x8(%rdx), %rbx
movq %rbx, %rax
shlq $0x20, %rax
movq %rax, 0x40(%rsp)
addq %rcx, %rax
movq %rax, %r14
sarq $0x1d, %r14
testq %rax, %rax
movq $-0x1, %r12
cmovsq %r12, %r14
movq %r14, %rdi
callq 0x5030
movq %rax, 0x20(%rsp)
testl %ebx, %ebx
movq %rbx, 0x18(%rsp)
movq %r15, 0x8(%rsp)
js 0x13b9d
movq %r14, 0x38(%rsp)
shlq $0x20, %r15
movabsq $0x100000000, %rax      # imm = 0x100000000
addq %rax, %r15
movq %r15, %rax
sarq $0x1e, %rax
movq %r15, 0x30(%rsp)
testq %r15, %r15
cmovnsq %rax, %r12
incl %ebx
xorl %r14d, %r14d
movq 0x20(%rsp), %r15
movq %r12, %rdi
callq 0x5030
movq %rax, (%r15,%r14,8)
incq %r14
cmpq %r14, %rbx
jne 0x13b46
movq 0x38(%rsp), %rdi
callq 0x5030
movq %rax, %r14
movq 0x18(%rsp), %r12
testl %r12d, %r12d
js 0x13bab
movq 0x30(%rsp), %r15
sarq $0x20, %r15
leal 0x1(%r12), %ebx
xorl %r12d, %r12d
movq %r15, %rdi
callq 0x5030
movq %rax, (%r14,%r12,8)
incq %r12
cmpq %r12, %rbx
jne 0x13b82
movq 0x18(%rsp), %r12
jmp 0x13bab
movq %r14, %rdi
callq 0x5030
movq %rax, %r14
movq %rbx, %r12
movq 0x10(%rsp), %rdi
movq 0x8(%rdi), %rdx
leaq 0x1da37(%rip), %r15     # 0x315f2
xorl %ebx, %ebx
xorl %esi, %esi
movq %r15, %rcx
xorl %r8d, %r8d
callq 0x54b0
movq 0x28(%rsp), %rdi
movq 0x8(%rdi), %rdx
xorl %esi, %esi
movq %r15, %rcx
xorl %r8d, %r8d
callq 0x54b0
cmpl $0x0, 0x8(%rsp)
movq 0x20(%rsp), %r15
js 0x13c0c
movq 0x8(%rsp), %rax
incl %eax
movq (%r15), %rcx
movq (%r14), %rdx
xorl %esi, %esi
movl %ebx, (%rcx,%rsi,4)
movb $0x2d, (%rdx,%rsi)
incq %rsi
decl %ebx
cmpq %rsi, %rax
jne 0x13bfb
testl %r12d, %r12d
js 0x13ce1
leal 0x1(%r12), %eax
xorl %ecx, %ecx
xorl %edx, %edx
movq (%r15,%rdx,8), %rsi
movl %ecx, (%rsi)
movq (%r14,%rdx,8), %rsi
movb $0x7c, (%rsi)
incq %rdx
decl %ecx
cmpq %rdx, %rax
jne 0x13c1e
movq (%r14), %rax
movb $0x2a, (%rax)
testl %r12d, %r12d
je 0x13ce7
movq 0x8(%rsp), %rax
incl %eax
leal 0x1(%r12), %ecx
decq %rax
movl $0x1, %edx
cmpl $0x0, 0x8(%rsp)
jle 0x13cd3
movq -0x8(%r15,%rdx,8), %rsi
movq (%r15,%rdx,8), %rdi
xorl %r8d, %r8d
movq (%rbp), %r9
movb (%r9,%r8), %r9b
movq (%r13), %r10
xorl %ebx, %ebx
cmpb -0x1(%r10,%rdx), %r9b
setne %bl
movl (%rsi,%r8,4), %r11d
subl %ebx, %r11d
movl 0x4(%rsi,%r8,4), %r9d
movl (%rdi,%r8,4), %r10d
cmpl %r10d, %r11d
jl 0x13ca5
cmpl %r9d, %r11d
jl 0x13ca5
movl %r11d, 0x4(%rdi,%r8,4)
movb $0x2a, %r9b
jmp 0x13cc2
cmpl %r9d, %r10d
jge 0x13cb7
decl %r9d
movl %r9d, 0x4(%rdi,%r8,4)
movb $0x7c, %r9b
jmp 0x13cc2
decl %r10d
movl %r10d, 0x4(%rdi,%r8,4)
movb $0x2d, %r9b
movq (%r14,%rdx,8), %r10
movb %r9b, 0x1(%r10,%r8)
incq %r8
cmpq %r8, %rax
jne 0x13c6b
incq %rdx
cmpq %rcx, %rdx
jne 0x13c58
jmp 0x13ce7
movq (%r14), %rax
movb $0x2a, (%rax)
testl %r12d, %r12d
setg %al
cmpl $0x0, 0x8(%rsp)
setg %cl
orb %al, %cl
cmpb $0x1, %cl
jne 0x13dad
movq 0x8(%rsp), %rax
movl %eax, %ecx
movq 0x18(%rsp), %rax
movl %eax, %r15d
movslq %r15d, %r12
movq (%r14,%r12,8), %rax
movslq %ecx, %rbx
movzbl (%rax,%rbx), %eax
cmpl $0x7c, %eax
je 0x13d6d
cmpl $0x2d, %eax
je 0x13d53
cmpl $0x2a, %eax
jne 0x13d9c
movq (%rbp), %rax
movsbl -0x1(%rax,%rbx), %esi
decq %rbx
movq 0x10(%rsp), %rdi
callq 0x52d0
movq (%r13), %rax
movb -0x1(%rax,%r12), %al
decq %r12
movl %r12d, %r15d
jmp 0x13d6b
movq (%rbp), %rax
movsbl -0x1(%rax,%rbx), %esi
decq %rbx
movq 0x10(%rsp), %rdi
callq 0x52d0
movb $0x2d, %al
jmp 0x13d8d
movl %ecx, %ebx
movq 0x10(%rsp), %rdi
movl $0x2d, %esi
callq 0x52d0
movq (%r13), %rax
movb -0x1(%rax,%r12), %al
decq %r12
movl %r12d, %r15d
movsbl %al, %esi
movq 0x28(%rsp), %rdi
callq 0x52d0
movl %ebx, %ecx
testl %r15d, %r15d
jg 0x13d0f
testl %ecx, %ecx
jg 0x13d0f
movq 0x10(%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 0x13df3
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 0x13dd8
movq 0x28(%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 0x18(%rsp), %r15
jne 0x13e3e
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 0x13e23
movq 0x40(%rsp), %rax
sarq $0x1d, %rax
movq 0x20(%rsp), %r12
movq (%r12,%rax), %rax
movslq 0x8(%rsp), %rcx
movl (%rax,%rcx,4), %ebp
testl %r15d, %r15d
js 0x13e86
incl %r15d
xorl %ebx, %ebx
movq (%r12,%rbx,8), %rdi
movl $0x4, %esi
callq 0x5340
movq (%r14,%rbx,8), %rdi
movl $0x1, %esi
callq 0x5340
incq %rbx
cmpq %rbx, %r15
jne 0x13e62
movl $0x8, %esi
movq %r12, %rdi
callq 0x5340
movl $0x8, %esi
movq %r14, %rdi
callq 0x5340
movl %ebp, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop