// File: /workspace/github_cpp_makefile_star2_O3/stoianmihail[P]XY-sorting/algorithm.cpp
// Function: chooseAlgorithm(unsigned int)
std::vector<cdf_coord> chooseAlgorithm(uint32_t option)
// Benchmark the different algorithms, by returning the CDF of the sorting.
{
    // Final result - the CDF of the sorting
    std::vector<cdf_coord> ret;
    
    // Create the input
    std::vector<uint64_t> xs = generator(MAX_VALUE_X);
    std::vector<uint64_t> ys = generator(MAX_VALUE_Y);
    
    auto printVector = [&](std::string msg, const std::vector<uint64_t>& arr) {
        std::cout << msg << std::endl;
        for (auto v : arr)
            std::cout << v << " ";
        std::cout << std::endl;
    };

#if 0
    printVector("X", xs);
    printVector("Y", ys);
#endif
    
    std::unordered_map<uint64_t, hash_coord> count_ = computeFreqHashTable(xs, ys);
    
    // Analyze options
    switch (option) {
        // Sort with a comparison-based sorting algorithm (N^2 log N)
        // Sort with radix sort (N ^ 2)
        case RADIX : {
            assert(("Radix not yet supported", 0));
#if 0
            cdf = solveWithRadix(xs, ys);
#endif
            break;
        }
        case TEST : {
            std::cerr << "Testing" << std::endl;
        }
        case SORTING : {
#if 1
            auto start = high_resolution_clock::now();
            ret = preprocessing_sorting(count_, xs, ys);
            solveWithSorting(ret);
            applyFrequencies(count_, ret);
            auto stop = high_resolution_clock::now();
            std::cout << "Sorting (preprocessing + solve) took: " << duration_cast<milliseconds>(stop - start).count() << " ms" << std::endl;
#endif
            if (option != TEST)
                break;
        }
        // Sort with the CDF approximation (N ^ 2)
        case CDF : {
            auto start = high_resolution_clock::now();
            ret = preprocessing_cdf(count_, xs, ys);
            solveWithCdf(ret);
            applyFrequencies(count_, ret);
            auto stop = high_resolution_clock::now();
            std::cout << "CDF approximation (preprocessing + solve) took: " << duration_cast<milliseconds>(stop - start).count() << " ms" << std::endl;
            break;
        }
        default : {
            std::cerr << "Option " << option << " not (yet) available" << std::endl;
        }
    }
#if 0
    util::printComputedCdf("Choose algorithm", cdf);
#endif
    std::cerr << "Is cdf? " << util::is_cdf(xs, ys, ret) << std::endl;
    return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movl %esi, %ebp
movq %rdi, %rbx
xorps %xmm0, %xmm0
movups %xmm0, (%rdi)
movq $0x0, 0x10(%rdi)
movq 0x6196(%rip), %rsi      # 0xa1e8
leaq 0x48(%rsp), %rdi
callq 0x45a7
movq 0x618d(%rip), %rsi      # 0xa1f0
leaq 0x30(%rsp), %rdi
callq 0x45a7
leaq 0x60(%rsp), %rdi
leaq 0x48(%rsp), %rsi
leaq 0x30(%rsp), %rdx
callq 0x352f
movq %rbx, 0x8(%rsp)
movl %ebp, %r14d
cmpl $0x3, %ebp
ja 0x40a9
leaq 0x2ffb(%rip), %rax      # 0x7090
movslq (%rax,%r14,4), %rcx
addq %rax, %rcx
jmpq *%rcx
xorl %r13d, %r13d
xorl %r14d, %r14d
jmp 0x4284
xorl %r12d, %r12d
movq 0x5f35(%rip), %rdi      # 0x9fe8
leaq 0x321e(%rip), %rsi      # 0x72d8
movl $0x7, %edx
xorl %r15d, %r15d
callq 0x31e0
xorl %r12d, %r12d
movq 0x5f17(%rip), %rdi      # 0x9fe8
xorl %r15d, %r15d
movq %r14, %rsi
callq 0x3100
movq %rax, %r14
xorl %r12d, %r12d
leaq 0x31f7(%rip), %rsi      # 0x72e0
movl $0x14, %edx
xorl %r15d, %r15d
movq %rax, %rdi
callq 0x31e0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
xorl %r12d, %r12d
xorl %r15d, %r15d
movl $0xa, %esi
callq 0x31b0
xorl %r12d, %r12d
movsbl %al, %esi
xorl %r15d, %r15d
movq %r14, %rdi
callq 0x3030
xorl %r12d, %r12d
xorl %r15d, %r15d
movq %rax, %rdi
callq 0x3110
xorl %ebx, %ebx
jmp 0x43ac
xorl %r12d, %r12d
movq 0x5ea5(%rip), %r14      # 0x9fe8
leaq 0x312e(%rip), %rsi      # 0x7278
movl $0x7, %edx
xorl %r15d, %r15d
movq %r14, %rdi
callq 0x31e0
movq (%r14), %rax
addq -0x18(%rax), %r14
xorl %r12d, %r12d
xorl %r15d, %r15d
movq %r14, %rdi
movl $0xa, %esi
callq 0x31b0
xorl %r12d, %r12d
movsbl %al, %esi
movq 0x5e67(%rip), %rdi      # 0x9fe8
xorl %r15d, %r15d
callq 0x3030
xorl %r12d, %r12d
xorl %r15d, %r15d
movq %rax, %rdi
callq 0x3110
callq 0x3040
movq %rax, %r12
leaq 0x10(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x3637
movq 0x10(%rsp), %r15
movq 0x8(%rsp), %r14
movq %r15, (%r14)
movq 0x18(%rsp), %rbx
movq %rbx, 0x8(%r14)
movq 0x20(%rsp), %rcx
movq %rcx, (%rsp)
movq %rcx, 0x10(%r14)
movq %r14, %rdi
callq 0x3689
leaq 0x60(%rsp), %rdi
movq %r14, %rsi
callq 0x34dc
callq 0x3040
movq %rax, %r14
movq 0x5dc3(%rip), %rdi      # 0x9fb8
leaq 0x3084(%rip), %rsi      # 0x7280
movl $0x26, %edx
callq 0x31e0
subq %r12, %r14
movq %r14, %rax
movabsq $0x431bde82d7b634db, %rcx # imm = 0x431BDE82D7B634DB
imulq %rcx
movq %rdx, %rsi
shrq $0x3f, %rsi
sarq $0x12, %rdx
addq %rdx, %rsi
movq 0x5d8a(%rip), %rdi      # 0x9fb8
callq 0x3190
movq %rax, %r14
leaq 0x2f1c(%rip), %rsi      # 0x7159
movl $0x3, %edx
movq %rax, %rdi
callq 0x31e0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3110
movq (%rsp), %r12
movq %r12, %r13
movq %r15, %r14
cmpl $0x3, %ebp
jne 0x43ac
callq 0x3040
movq %rax, %r12
leaq 0x10(%rsp), %rdi
leaq 0x60(%rsp), %rsi
leaq 0x48(%rsp), %rdx
leaq 0x30(%rsp), %rcx
callq 0x3897
movq 0x10(%rsp), %r15
movq 0x8(%rsp), %rax
movq %r15, (%rax)
movq 0x18(%rsp), %rbx
movq %rbx, 0x8(%rax)
movq 0x20(%rsp), %rdx
movq %rdx, (%rsp)
movq %rdx, 0x10(%rax)
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
movq $0x0, 0x20(%rsp)
testq %r14, %r14
je 0x4303
subq %r14, %r13
movq %r14, %rdi
movq %r13, %rsi
callq 0x31d0
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x4303
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x31d0
movq 0x8(%rsp), %r14
movq %r14, %rdi
callq 0x3f04
leaq 0x60(%rsp), %rdi
movq %r14, %rsi
callq 0x34dc
callq 0x3040
movq %rax, %r14
movq 0x5c8c(%rip), %rdi      # 0x9fb8
leaq 0x2f74(%rip), %rsi      # 0x72a7
movl $0x30, %edx
callq 0x31e0
subq %r12, %r14
movq %r14, %rax
movabsq $0x431bde82d7b634db, %rcx # imm = 0x431BDE82D7B634DB
imulq %rcx
movq %rdx, %rsi
shrq $0x3f, %rsi
sarq $0x12, %rdx
addq %rdx, %rsi
movq 0x5c53(%rip), %rdi      # 0x9fb8
callq 0x3190
movq %rax, %r14
leaq 0x2de5(%rip), %rsi      # 0x7159
movl $0x3, %edx
movq %rax, %rdi
callq 0x31e0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3110
movq (%rsp), %r12
movq 0x5c35(%rip), %rdi      # 0x9fe8
leaq 0x2f3b(%rip), %rsi      # 0x72f5
movl $0x8, %edx
callq 0x31e0
cmpq %rbx, %r15
je 0x44c6
movq 0x48(%rsp), %rsi
movq 0x50(%rsp), %rax
movq 0x30(%rsp), %rdx
movq 0x38(%rsp), %rcx
movq %rbx, %rdi
subq %r15, %rdi
sarq $0x4, %rdi
cmpq $0x2, %rdi
jb 0x441e
movl $0x1, %r9d
movl $0x2, %r8d
leal -0x2(%r8), %r10d
shlq $0x4, %r10
movq (%r15,%r10), %r10
shlq $0x4, %r9
cmpq (%r15,%r9), %r10
jae 0x4439
movl %r8d, %r9d
incl %r8d
cmpq %r9, %rdi
ja 0x43fd
subq %rsi, %rax
sarq $0x3, %rax
subq %rdx, %rcx
sarq $0x3, %rcx
imulq %rax, %rcx
cmpq %rcx, -0x8(%rbx)
sete %al
jmp 0x443b
xorl %eax, %eax
movzbl %al, %esi
movq 0x5ba3(%rip), %rdi      # 0x9fe8
callq 0x3290
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3110
leaq 0x60(%rsp), %rdi
callq 0x4e52
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x4495
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x31d0
movq 0x48(%rsp), %rdi
testq %rdi, %rdi
movq 0x8(%rsp), %rbx
je 0x44b1
movq 0x58(%rsp), %rsi
subq %rdi, %rsi
callq 0x31d0
movq %rbx, %rax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2ec0(%rip), %rdi      # 0x738d
leaq 0x2ed8(%rip), %rsi      # 0x73ac
leaq 0x2edc(%rip), %rcx      # 0x73b7
movl $0x24, %edx
callq 0x30e0
leaq 0x2d3c(%rip), %rdi      # 0x7228
leaq 0x2bcc(%rip), %rsi      # 0x70bf
leaq 0x2d4d(%rip), %rcx      # 0x7247
movl $0x12f, %edx            # imm = 0x12F
callq 0x30e0
jmp 0x4550
movq %rax, %rbx
movq %r13, (%rsp)
movq %r14, %r15
jmp 0x4553
jmp 0x4550
movq %rax, %rbx
movq $0x0, (%rsp)
xorl %r15d, %r15d
jmp 0x4553
jmp 0x4550
jmp 0x4550
movq %rax, %rbx
movq $0x0, (%rsp)
xorl %r15d, %r15d
jmp 0x455d
movq %rax, %rbx
movq $0x0, (%rsp)
xorl %r15d, %r15d
jmp 0x4574
jmp 0x4550
jmp 0x4550
movq %r12, (%rsp)
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x4e52
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x4574
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x31d0
movq 0x48(%rsp), %rdi
testq %rdi, %rdi
je 0x458b
movq 0x58(%rsp), %rsi
subq %rdi, %rsi
callq 0x31d0
testq %r15, %r15
je 0x459f
movq (%rsp), %rsi
subq %r15, %rsi
movq %r15, %rdi
callq 0x31d0
movq %rbx, %rdi
callq 0x32d0