// File: ParkerLab[P]cta/src/cta.cpp
// Function: levenshtein_distance(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, long long)
long long int levenshtein_distance(const std::string& s1, const std::string& s2, long long int maximum = 0) {
    // shortcuts
    if (s1 == s2) return 0;

    long long int s1_length = s1.size();
    long long int s2_length = s2.size();

    if (s1_length == 0) {
        return s2_length;
    }

    if (s2_length == 0) {
        return s1_length;
    }

    if (maximum) {
        long long int minimum_distance = llabs(s1_length - s2_length);
        if (maximum < minimum_distance) {
            return minimum_distance;
        }
    }

    // ok, not getting out of the work that easily
    std::vector<long long int> v1(s2_length + 1);
    std::vector<long long int> v2(s2_length + 1);

    for (long long int i = 0; i < s2_length; i++) {
        v1[i] = i;
    }

    long long int v1_size = v1.size();
    for (long long int i = 0; i < s1_length; i++) {
        v2[0] = i + 1;

        for (long long int j = 0; j < s2_length; j++) {
            int cost = s1[i] == s2[j] ? 0 : 1;
            v2[j + 1] = std::min(v2[j] + 1, std::min(v1[j + 1] + 1, v1[j] + cost));
        }

        long long int minimum = maximum + 1;
        for (long long int j = 0; j < v1_size; j++) {
            if (v2[j] < minimum) {
                minimum = v2[j];
            }
            v1[j] = v2[j];
        }
        if (minimum > maximum) {
            // abort early
            return maximum + 1;
        }
    }

    return v2[s2_length];
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x12dc0
testb $0x1, %al
jne 0xf63a
jmp 0xf647
movq $0x0, -0x8(%rbp)
jmp 0xfab1
movq -0x10(%rbp), %rdi
callq 0xe480
movq %rax, -0x28(%rbp)
movq -0x18(%rbp), %rdi
callq 0xe480
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0xf675
movq -0x30(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xfab1
cmpq $0x0, -0x30(%rbp)
jne 0xf689
movq -0x28(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xfab1
cmpq $0x0, -0x20(%rbp)
je 0xf6bf
movq -0x28(%rbp), %rax
subq -0x30(%rbp), %rax
movq %rax, %rcx
negq %rcx
cmovnsq %rcx, %rax
movq %rax, -0x38(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x38(%rbp), %rax
jge 0xf6bd
movq -0x38(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xfab1
jmp 0xf6bf
movq -0x30(%rbp), %rax
incq %rax
movq %rax, -0xf0(%rbp)
leaq -0x51(%rbp), %rdi
movq %rdi, -0xe8(%rbp)
callq 0x12e50
movq -0xf0(%rbp), %rsi
movq -0xe8(%rbp), %rdx
leaq -0x50(%rbp), %rdi
callq 0x12e70
jmp 0xf6f6
leaq -0x51(%rbp), %rdi
callq 0x12ee0
movq -0x30(%rbp), %rax
incq %rax
movq %rax, -0x100(%rbp)
leaq -0x81(%rbp), %rdi
movq %rdi, -0xf8(%rbp)
callq 0x12e50
movq -0x100(%rbp), %rsi
movq -0xf8(%rbp), %rdx
leaq -0x80(%rbp), %rdi
callq 0x12e70
jmp 0xf739
leaq -0x81(%rbp), %rdi
callq 0x12ee0
movq $0x0, -0x90(%rbp)
movq -0x90(%rbp), %rax
cmpq -0x30(%rbp), %rax
jge 0xf7d0
movq -0x90(%rbp), %rax
movq %rax, -0x108(%rbp)
movq -0x90(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0x12f00
movq -0x108(%rbp), %rcx
movq %rcx, (%rax)
movq -0x90(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x90(%rbp)
jmp 0xf750
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x51(%rbp), %rdi
callq 0x12ee0
jmp 0xfabe
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x81(%rbp), %rdi
callq 0x12ee0
jmp 0xfaa6
leaq -0x50(%rbp), %rdi
callq 0x12f20
movq %rax, -0x98(%rbp)
movq $0x0, -0xa0(%rbp)
movq -0xa0(%rbp), %rax
cmpq -0x28(%rbp), %rax
jge 0xfa74
movq -0xa0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x110(%rbp)
leaq -0x80(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x12f00
movq -0x110(%rbp), %rcx
movq %rcx, (%rax)
movq $0x0, -0xa8(%rbp)
movq -0xa8(%rbp), %rax
cmpq -0x30(%rbp), %rax
jge 0xf987
movq -0x10(%rbp), %rdi
movq -0xa0(%rbp), %rsi
callq 0xe6d0
movsbl (%rax), %eax
movl %eax, -0x124(%rbp)
movq -0x18(%rbp), %rdi
movq -0xa8(%rbp), %rsi
callq 0xe6d0
movq %rax, %rcx
movl -0x124(%rbp), %eax
movsbl (%rcx), %ecx
subl %ecx, %eax
setne %al
movzbl %al, %eax
movl %eax, -0xac(%rbp)
movq -0xa8(%rbp), %rsi
leaq -0x80(%rbp), %rdi
callq 0x12f00
movq (%rax), %rax
incq %rax
movq %rax, -0xb8(%rbp)
movq -0xa8(%rbp), %rsi
incq %rsi
leaq -0x50(%rbp), %rdi
movq %rdi, -0x120(%rbp)
callq 0x12f00
movq -0x120(%rbp), %rdi
movq (%rax), %rax
incq %rax
movq %rax, -0xc0(%rbp)
movq -0xa8(%rbp), %rsi
callq 0x12f00
movq (%rax), %rax
movslq -0xac(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0xc8(%rbp)
leaq -0xc0(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0x12f40
movq %rax, -0x118(%rbp)
jmp 0xf90b
movq -0x118(%rbp), %rsi
leaq -0xb8(%rbp), %rdi
callq 0x12f40
movq %rax, -0x130(%rbp)
jmp 0xf927
movq -0x130(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x138(%rbp)
movq -0xa8(%rbp), %rsi
addq $0x1, %rsi
leaq -0x80(%rbp), %rdi
callq 0x12f00
movq -0x138(%rbp), %rcx
movq %rcx, (%rax)
movq -0xa8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa8(%rbp)
jmp 0xf830
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x12f80
jmp 0xfaa6
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xd0(%rbp)
movq $0x0, -0xd8(%rbp)
movq -0xd8(%rbp), %rax
cmpq -0x98(%rbp), %rax
jge 0xfa36
movq -0xd8(%rbp), %rsi
leaq -0x80(%rbp), %rdi
callq 0x12f00
movq (%rax), %rax
cmpq -0xd0(%rbp), %rax
jge 0xf9eb
movq -0xd8(%rbp), %rsi
leaq -0x80(%rbp), %rdi
callq 0x12f00
movq (%rax), %rax
movq %rax, -0xd0(%rbp)
movq -0xd8(%rbp), %rsi
leaq -0x80(%rbp), %rdi
callq 0x12f00
movq (%rax), %rax
movq %rax, -0x140(%rbp)
movq -0xd8(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0x12f00
movq -0x140(%rbp), %rcx
movq %rcx, (%rax)
movq -0xd8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xd8(%rbp)
jmp 0xf9a1
movq -0xd0(%rbp), %rax
cmpq -0x20(%rbp), %rax
jle 0xfa5b
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0xdc(%rbp)
jmp 0xfa92
jmp 0xfa5d
movq -0xa0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa0(%rbp)
jmp 0xf7eb
movq -0x30(%rbp), %rsi
leaq -0x80(%rbp), %rdi
callq 0x12f00
movq (%rax), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0xdc(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x12f80
leaq -0x50(%rbp), %rdi
callq 0x12f80
jmp 0xfab1
leaq -0x50(%rbp), %rdi
callq 0x12f80
jmp 0xfabe
movq -0x8(%rbp), %rax
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
movq -0x60(%rbp), %rdi
callq 0xeb80
nopw (%rax,%rax)