// File: ikatanic[P]lcskpp/main_fasta.cpp
// Function: main
int main(int argc, char** argv) {
  if (argc != 4) {
    printf(
      "Compute LCSk++ of two sequences given in FASTA format.\n\n"
      "Usage: ./main k input output\n\n"
      "Example: ./main 4 input.fa out\n"
      "finds LCS4++ of first two sequences given in `input.fa` and\n"
      "and writes it to `out`\n"
    );
    return 0;
  };

  int k = stoi(argv[1]);
  ifstream infile(argv[2]);

  vector<string> sequences;
  string line;
  string current_seq;
  bool first = true;
  while (getline(infile, line)) {
    if (!line.size()) continue;

    if (line[0] == '>') {
      if (!first) {
        sequences.push_back(current_seq);
      }
      current_seq = "";
      first = false;
    } else if (line[0] == ',') {
      continue;
    } else {
      current_seq += line;
    }
  }
  sequences.push_back(current_seq);

  printf("Read %d sequences.\n", (int)sequences.size());
  if (sequences.size() < 2) {
    printf("Not enough sequences. Aborting.\n");
    return 0;
  }

  string& A = sequences[0];
  string& B = sequences[1];

  printf("Computing LCSk++ of first two sequences..\n");
  printf("Sequence 1 length: %d\n", (int)A.size());
  printf("Sequence 2 length: %d\n", (int)B.size());

  vector<pair<int, int>> recon;
  int length = lcskpp(sequences[0], sequences[1], k, &recon);
  printf("LCSk++ length: %d\n", length);

  auto r = freopen(argv[3], "w", stdout);
  for (auto& p: recon) {
    putchar(A[p.first]);
  }
  return 0;
}

// Assembly:
subq $0x388, %rsp            # imm = 0x388
movl $0x0, 0x384(%rsp)
movl %edi, 0x380(%rsp)
movq %rsi, 0x378(%rsp)
cmpl $0x4, 0x380(%rsp)
je 0xae49
leaq 0x234c(%rip), %rdi      # 0xd17e
movb $0x0, %al
callq 0x2040
movl $0x0, 0x384(%rsp)
jmp 0xb385
movq 0x378(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x68(%rsp)
leaq 0x34f(%rsp), %rdi
movq %rdi, 0x70(%rsp)
callq 0x2270
movq 0x68(%rsp), %rsi
movq 0x70(%rsp), %rdx
leaq 0x350(%rsp), %rdi
callq 0x21d0
jmp 0xae85
xorl %eax, %eax
movl %eax, %esi
leaq 0x350(%rsp), %rdi
movl $0xa, %edx
callq 0xb3b0
movl %eax, 0x64(%rsp)
jmp 0xaea1
leaq 0x350(%rsp), %rdi
callq 0x2100
leaq 0x34f(%rsp), %rdi
callq 0x2180
movl 0x64(%rsp), %eax
movl %eax, 0x374(%rsp)
movq 0x378(%rsp), %rax
movq 0x10(%rax), %rsi
leaq 0x130(%rsp), %rdi
movl $0x8, %edx
callq 0x2280
leaq 0x118(%rsp), %rdi
callq 0xb400
leaq 0xf8(%rsp), %rdi
callq 0x21e0
leaq 0xd8(%rsp), %rdi
callq 0x21e0
movb $0x1, 0xd7(%rsp)
leaq 0x130(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0x2050
movq %rax, 0x58(%rsp)
jmp 0xaf2f
movq 0x58(%rsp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x21a0
movb %al, 0x57(%rsp)
jmp 0xaf49
movb 0x57(%rsp), %al
testb $0x1, %al
jne 0xaf56
jmp 0xb07f
leaq 0xf8(%rsp), %rdi
callq 0x2120
cmpq $0x0, %rax
jne 0xafcd
jmp 0xaf13
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x340(%rsp)
movl %eax, 0x33c(%rsp)
jmp 0xafa2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x340(%rsp)
movl %eax, 0x33c(%rsp)
leaq 0x350(%rsp), %rdi
callq 0x2100
leaq 0x34f(%rsp), %rdi
callq 0x2180
jmp 0xb394
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x340(%rsp)
movl %eax, 0x33c(%rsp)
jmp 0xb34f
xorl %eax, %eax
movl %eax, %esi
leaq 0xf8(%rsp), %rdi
callq 0x2290
movq %rax, 0x48(%rsp)
jmp 0xafe5
movq 0x48(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x3e, %eax
jne 0xb035
testb $0x1, 0xd7(%rsp)
jne 0xb015
leaq 0x118(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0xb410
jmp 0xb013
jmp 0xb015
leaq 0x228a(%rip), %rsi      # 0xd2a6
leaq 0xd8(%rsp), %rdi
callq 0x21c0
jmp 0xb02b
movb $0x0, 0xd7(%rsp)
jmp 0xb07a
xorl %eax, %eax
movl %eax, %esi
leaq 0xf8(%rsp), %rdi
callq 0x2290
movq %rax, 0x40(%rsp)
jmp 0xb04d
movq 0x40(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x2c, %eax
jne 0xb05f
jmp 0xaf13
leaq 0xd8(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0x21b0
jmp 0xb076
jmp 0xb078
jmp 0xb07a
jmp 0xaf13
leaq 0x118(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0xb410
jmp 0xb096
leaq 0x118(%rsp), %rdi
callq 0xb480
movl %eax, %esi
leaq 0x219b(%rip), %rdi      # 0xd247
xorl %eax, %eax
callq 0x2040
jmp 0xb0b5
leaq 0x118(%rsp), %rdi
callq 0xb480
cmpq $0x2, %rax
jae 0xb0f3
leaq 0x218c(%rip), %rdi      # 0xd25b
xorl %eax, %eax
callq 0x2040
jmp 0xb0d8
movl $0x0, 0x384(%rsp)
movl $0x1, 0xd0(%rsp)
jmp 0xb319
xorl %eax, %eax
movl %eax, 0x3c(%rsp)
movl %eax, %esi
leaq 0x118(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0xb4a0
movq 0x30(%rsp), %rdi
movq %rax, 0xc8(%rsp)
movl $0x1, %esi
callq 0xb4a0
movq %rax, %rcx
movl 0x3c(%rsp), %eax
movq %rcx, 0xc0(%rsp)
leaq 0x2142(%rip), %rdi      # 0xd27c
callq 0x2040
jmp 0xb141
movq 0xc8(%rsp), %rdi
callq 0x2120
movl %eax, %esi
leaq 0x2150(%rip), %rdi      # 0xd2a7
xorl %eax, %eax
callq 0x2040
jmp 0xb160
movq 0xc0(%rsp), %rdi
callq 0x2120
movl %eax, %esi
leaq 0x2148(%rip), %rdi      # 0xd2be
xorl %eax, %eax
callq 0x2040
jmp 0xb17f
leaq 0xa8(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x6260
xorl %eax, %eax
movl %eax, %esi
leaq 0x118(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0xb4a0
movq 0x10(%rsp), %rdi
movq %rax, 0x18(%rsp)
movl $0x1, %esi
callq 0xb4a0
movq 0x18(%rsp), %rdi
movq 0x20(%rsp), %rcx
movq %rax, %rsi
movl 0x374(%rsp), %edx
callq 0x4520
movl %eax, 0x2c(%rsp)
jmp 0xb1da
movl 0x2c(%rsp), %eax
movl %eax, 0xa4(%rsp)
movl 0xa4(%rsp), %esi
leaq 0x20e2(%rip), %rdi      # 0xd2d5
xorl %eax, %eax
callq 0x2040
jmp 0xb1fc
movq 0x378(%rsp), %rax
movq 0x18(%rax), %rdi
movq 0x6da9(%rip), %rax      # 0x11fb8
movq (%rax), %rdx
leaq 0x20cf(%rip), %rsi      # 0xd2e8
callq 0x2170
movq %rax, 0x8(%rsp)
jmp 0xb225
movq 0x8(%rsp), %rax
movq %rax, 0x98(%rsp)
leaq 0xa8(%rsp), %rax
movq %rax, 0x90(%rsp)
movq 0x90(%rsp), %rdi
callq 0x5ba0
movq %rax, 0x88(%rsp)
movq 0x90(%rsp), %rdi
callq 0x5c10
movq %rax, 0x80(%rsp)
leaq 0x88(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x60e0
testb $0x1, %al
jne 0xb287
jmp 0xb2f6
leaq 0x88(%rsp), %rdi
callq 0x6120
movq %rax, 0x78(%rsp)
movq 0xc8(%rsp), %rdi
movq 0x78(%rsp), %rax
movslq (%rax), %rsi
callq 0x2290
movq %rax, (%rsp)
jmp 0xb2b4
movq (%rsp), %rax
movsbl (%rax), %edi
callq 0x21f0
jmp 0xb2c2
jmp 0xb2c4
leaq 0x88(%rsp), %rdi
callq 0x6130
jmp 0xb26c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x340(%rsp)
movl %eax, 0x33c(%rsp)
leaq 0xa8(%rsp), %rdi
callq 0x6200
jmp 0xb34f
movl $0x0, 0x384(%rsp)
movl $0x1, 0xd0(%rsp)
leaq 0xa8(%rsp), %rdi
callq 0x6200
leaq 0xd8(%rsp), %rdi
callq 0x2100
leaq 0xf8(%rsp), %rdi
callq 0x2100
leaq 0x118(%rsp), %rdi
callq 0xb4c0
leaq 0x130(%rsp), %rdi
callq 0x2060
jmp 0xb385
leaq 0xd8(%rsp), %rdi
callq 0x2100
leaq 0xf8(%rsp), %rdi
callq 0x2100
leaq 0x118(%rsp), %rdi
callq 0xb4c0
leaq 0x130(%rsp), %rdi
callq 0x2060
jmp 0xb394
movl 0x384(%rsp), %eax
addq $0x388, %rsp            # imm = 0x388
retq
movq 0x340(%rsp), %rdi
callq 0x2260
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)