// File: kevintownsend[P]bwt/example.cpp
// Function: main
int main(int argc, char* argv[]){
    vector<char> original;
    if(argc == 3){
        if(string(argv[1]) == "-f"){
            original.clear();
            ifstream file(argv[2]);
            while(!file.eof()){
                char c = file.get();
                if(c == '\n') break;
                original.push_back(c);
            }
            file.close();
        }else{
            cerr << "usage: " << argv[0] << " gataca" << endl;
            return 1;
        }
    }else if(argc == 2){
        original.insert(original.begin(),argv[1], argv[1] + strlen(argv[1]));
    }else if(argc == 1){
        char c;
        while((c = getchar()) != -1)
            original.push_back(c);
    }else{
        cerr << "usage: " << argv[0] << " gataca" << endl;
        return 1;
    }
    size_t key;
    std::tie(original, key) = bwt::bwt(original.begin(), original.end());
    if(original.size() <= 1000){
        for(auto it = original.begin(); it != original.end(); it++){
            if(it == (original.begin() + key))
                cout << "$";
            cout << *it;
        }
        cout << endl;
    }
    bool success;
    std::tie(original, success) = bwt::iBwt(original.begin(), original.end(), key);
    if(original.size() <= 1000){
        for(auto it = original.begin(); it != original.end(); it++){
            cout << *it;
        }
        cout << endl;
    }
    return 0;
}

// Assembly:
subq $0x3d8, %rsp            # imm = 0x3D8
movl $0x0, 0x3d4(%rsp)
movl %edi, 0x3d0(%rsp)
movq %rsi, 0x3c8(%rsp)
leaq 0x3b0(%rsp), %rdi
callq 0x2ab0
cmpl $0x3, 0x3d0(%rsp)
jne 0x263d
movq 0x3c8(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x68(%rsp)
leaq 0x38f(%rsp), %rdi
movq %rdi, 0x70(%rsp)
callq 0x2240
movq 0x68(%rsp), %rsi
movq 0x70(%rsp), %rdx
leaq 0x390(%rsp), %rdi
callq 0x21b0
jmp 0x2428
leaq 0x5bd5(%rip), %rsi      # 0x8004
leaq 0x390(%rsp), %rdi
callq 0x2ac0
movb %al, 0x67(%rsp)
jmp 0x2442
leaq 0x390(%rsp), %rdi
callq 0x20f0
leaq 0x38f(%rsp), %rdi
callq 0x2180
movb 0x67(%rsp), %al
testb $0x1, %al
jne 0x2469
jmp 0x25bc
leaq 0x3b0(%rsp), %rdi
callq 0x2af0
movq 0x3c8(%rsp), %rax
movq 0x10(%rax), %rsi
leaq 0x170(%rsp), %rdi
movl $0x8, %edx
callq 0x2250
jmp 0x2496
jmp 0x2498
movq 0x170(%rsp), %rax
movq -0x18(%rax), %rax
leaq 0x170(%rsp,%rax), %rdi
callq 0x2260
movb %al, 0x66(%rsp)
jmp 0x24b7
movb 0x66(%rsp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x24c6
jmp 0x259e
leaq 0x170(%rsp), %rdi
callq 0x21a0
movl %eax, 0x60(%rsp)
jmp 0x24d9
movl 0x60(%rsp), %eax
movb %al, 0x16f(%rsp)
movsbl 0x16f(%rsp), %eax
cmpl $0xa, %eax
jne 0x2582
jmp 0x259e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x380(%rsp)
movl %eax, 0x37c(%rsp)
jmp 0x2531
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x380(%rsp)
movl %eax, 0x37c(%rsp)
leaq 0x390(%rsp), %rdi
callq 0x20f0
leaq 0x38f(%rsp), %rdi
callq 0x2180
jmp 0x2a96
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x380(%rsp)
movl %eax, 0x37c(%rsp)
jmp 0x2a96
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x380(%rsp)
movl %eax, 0x37c(%rsp)
leaq 0x170(%rsp), %rdi
callq 0x2060
jmp 0x2a96
leaq 0x3b0(%rsp), %rdi
leaq 0x16f(%rsp), %rsi
callq 0x2b10
jmp 0x2599
jmp 0x2498
leaq 0x170(%rsp), %rdi
callq 0x2050
jmp 0x25ad
leaq 0x170(%rsp), %rdi
callq 0x2060
jmp 0x2638
movq 0x9a2d(%rip), %rdi      # 0xbff0
leaq 0x5a3d(%rip), %rsi      # 0x8007
callq 0x2140
movq %rax, 0x58(%rsp)
jmp 0x25d6
movq 0x58(%rsp), %rdi
movq 0x3c8(%rsp), %rax
movq (%rax), %rsi
callq 0x2140
movq %rax, 0x50(%rsp)
jmp 0x25f2
movq 0x50(%rsp), %rdi
leaq 0x5a11(%rip), %rsi      # 0x800f
callq 0x2140
movq %rax, 0x48(%rsp)
jmp 0x260a
movq 0x48(%rsp), %rdi
movq 0x99aa(%rip), %rsi      # 0xbfc0
callq 0x2170
jmp 0x261d
movl $0x1, 0x3d4(%rsp)
movl $0x1, 0x168(%rsp)
jmp 0x2a7a
jmp 0x2787
cmpl $0x2, 0x3d0(%rsp)
jne 0x26c2
leaq 0x3b0(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x2c30
movq %rax, 0x158(%rsp)
leaq 0x160(%rsp), %rdi
leaq 0x158(%rsp), %rsi
callq 0x2c60
movq 0x3c8(%rsp), %rax
movq 0x8(%rax), %rdi
movq %rdi, 0x38(%rsp)
callq 0x20b0
movq 0x30(%rsp), %rdi
movq 0x38(%rsp), %rdx
movq %rdx, %rcx
addq %rax, %rcx
movq 0x160(%rsp), %rsi
callq 0x2b80
movq %rax, 0x40(%rsp)
jmp 0x26b0
movq 0x40(%rsp), %rax
movq %rax, 0x150(%rsp)
jmp 0x2785
cmpl $0x1, 0x3d0(%rsp)
jne 0x2707
jmp 0x26ce
callq 0x21c0
movl %eax, 0x2c(%rsp)
jmp 0x26d9
movl 0x2c(%rsp), %eax
movb %al, 0x14f(%rsp)
movsbl %al, %eax
cmpl $-0x1, %eax
je 0x2705
leaq 0x3b0(%rsp), %rdi
leaq 0x14f(%rsp), %rsi
callq 0x2b10
jmp 0x2703
jmp 0x26ce
jmp 0x2783
movq 0x98e2(%rip), %rdi      # 0xbff0
leaq 0x58f2(%rip), %rsi      # 0x8007
callq 0x2140
movq %rax, 0x20(%rsp)
jmp 0x2721
movq 0x20(%rsp), %rdi
movq 0x3c8(%rsp), %rax
movq (%rax), %rsi
callq 0x2140
movq %rax, 0x18(%rsp)
jmp 0x273d
movq 0x18(%rsp), %rdi
leaq 0x58c6(%rip), %rsi      # 0x800f
callq 0x2140
movq %rax, 0x10(%rsp)
jmp 0x2755
movq 0x10(%rsp), %rdi
movq 0x985f(%rip), %rsi      # 0xbfc0
callq 0x2170
jmp 0x2768
movl $0x1, 0x3d4(%rsp)
movl $0x1, 0x168(%rsp)
jmp 0x2a7a
jmp 0x2785
jmp 0x2787
leaq 0x3b0(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x2c30
movq 0x8(%rsp), %rdi
movq %rax, 0x118(%rsp)
callq 0x3230
movq %rax, 0x110(%rsp)
movq 0x118(%rsp), %rsi
movq 0x110(%rsp), %rdx
leaq 0x120(%rsp), %rdi
callq 0x2ca0
jmp 0x27d2
leaq 0x100(%rsp), %rdi
leaq 0x3b0(%rsp), %rsi
leaq 0x140(%rsp), %rdx
callq 0x3260
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x32a0
leaq 0x120(%rsp), %rdi
callq 0x3310
leaq 0x3b0(%rsp), %rdi
callq 0x3320
cmpq $0x3e8, %rax            # imm = 0x3E8
ja 0x2929
leaq 0x3b0(%rsp), %rdi
callq 0x2c30
movq %rax, 0xf8(%rsp)
leaq 0x3b0(%rsp), %rdi
callq 0x3230
movq %rax, 0xf0(%rsp)
leaq 0xf8(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x3340
testb $0x1, %al
jne 0x2872
jmp 0x2912
leaq 0x3b0(%rsp), %rdi
callq 0x2c30
movq %rax, 0xe0(%rsp)
movq 0x140(%rsp), %rsi
leaq 0xe0(%rsp), %rdi
callq 0x33c0
movq %rax, 0xe8(%rsp)
leaq 0xf8(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x3380
testb $0x1, %al
jne 0x28bf
jmp 0x28d6
movq 0x970a(%rip), %rdi      # 0xbfd0
leaq 0x574a(%rip), %rsi      # 0x8017
callq 0x2140
jmp 0x28d4
jmp 0x28d6
leaq 0xf8(%rsp), %rdi
callq 0x3400
movsbl (%rax), %esi
movq 0x96e3(%rip), %rdi      # 0xbfd0
callq 0x2190
jmp 0x28f4
jmp 0x28f6
leaq 0xf8(%rsp), %rdi
xorl %esi, %esi
callq 0x3410
movq %rax, 0xd8(%rsp)
jmp 0x283f
movq 0x96b7(%rip), %rdi      # 0xbfd0
movq 0x96a0(%rip), %rsi      # 0xbfc0
callq 0x2170
jmp 0x2927
jmp 0x2929
leaq 0x3b0(%rsp), %rdi
movq %rdi, (%rsp)
callq 0x2c30
movq (%rsp), %rdi
movq %rax, 0xa8(%rsp)
callq 0x3230
movq %rax, 0xa0(%rsp)
movq 0x140(%rsp), %rcx
movq 0xa8(%rsp), %rsi
movq 0xa0(%rsp), %rdx
leaq 0xb0(%rsp), %rdi
callq 0x3450
jmp 0x297a
leaq 0x90(%rsp), %rdi
leaq 0x3b0(%rsp), %rsi
leaq 0xd7(%rsp), %rdx
callq 0x38d0
leaq 0x90(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x3910
leaq 0xb0(%rsp), %rdi
callq 0x3980
leaq 0x3b0(%rsp), %rdi
callq 0x3320
cmpq $0x3e8, %rax            # imm = 0x3E8
ja 0x2a64
leaq 0x3b0(%rsp), %rdi
callq 0x2c30
movq %rax, 0x88(%rsp)
leaq 0x3b0(%rsp), %rdi
callq 0x3230
movq %rax, 0x80(%rsp)
leaq 0x88(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x3340
testb $0x1, %al
jne 0x2a17
jmp 0x2a4d
leaq 0x88(%rsp), %rdi
callq 0x3400
movsbl (%rax), %esi
movq 0x95a2(%rip), %rdi      # 0xbfd0
callq 0x2190
jmp 0x2a35
jmp 0x2a37
leaq 0x88(%rsp), %rdi
xorl %esi, %esi
callq 0x3410
movq %rax, 0x78(%rsp)
jmp 0x29e7
movq 0x957c(%rip), %rdi      # 0xbfd0
movq 0x9565(%rip), %rsi      # 0xbfc0
callq 0x2170
jmp 0x2a62
jmp 0x2a64
movl $0x0, 0x3d4(%rsp)
movl $0x1, 0x168(%rsp)
leaq 0x3b0(%rsp), %rdi
callq 0x3990
movl 0x3d4(%rsp), %eax
addq $0x3d8, %rsp            # imm = 0x3D8
retq
leaq 0x3b0(%rsp), %rdi
callq 0x3990
movq 0x380(%rsp), %rdi
callq 0x2230