// File: /workspace/github_cpp_makefile_star2_O1/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 %r12
pushq %rbx
subq $0x80, %rsp
movl %esi, %ebp
movq %rdi, %rbx
xorps %xmm0, %xmm0
movups %xmm0, (%rdi)
movq $0x0, 0x10(%rdi)
movq 0x61e0(%rip), %rsi      # 0xa1e8
leaq 0x18(%rsp), %rdi
callq 0x448f
movq 0x61d7(%rip), %rsi      # 0xa1f0
movq %rsp, %rdi
callq 0x448f
leaq 0x48(%rsp), %rdi
leaq 0x18(%rsp), %rsi
movq %rsp, %rdx
callq 0x352f
movl %ebp, %r14d
cmpl $0x3, %ebp
ja 0x4256
leaq 0x304a(%rip), %rax      # 0x7090
movslq (%rax,%r14,4), %rcx
addq %rax, %rcx
movabsq $0x431bde82d7b634db, %r12 # imm = 0x431BDE82D7B634DB
jmpq *%rcx
movq 0x5f88(%rip), %r14      # 0x9fe8
leaq 0x3211(%rip), %rsi      # 0x7278
movl $0x7, %edx
movq %r14, %rdi
callq 0x31e0
movq (%r14), %rax
addq -0x18(%rax), %r14
movq %r14, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq 0x5f56(%rip), %rdi      # 0x9fe8
callq 0x3030
movq %rax, %rdi
callq 0x3110
callq 0x3040
movq %rax, %r14
leaq 0x30(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x3625
leaq 0x30(%rsp), %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0x5c8c
movq (%r15), %rdi
testq %rdi, %rdi
je 0x40db
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x31d0
movq %rbx, %rdi
callq 0x3677
leaq 0x48(%rsp), %rdi
movq %rbx, %rsi
callq 0x34dc
callq 0x3040
movq %rax, %r15
movq 0x5eb9(%rip), %rdi      # 0x9fb8
leaq 0x317a(%rip), %rsi      # 0x7280
movl $0x26, %edx
callq 0x31e0
subq %r14, %r15
movq %r15, %rax
imulq %r12
movq %rdx, %rsi
shrq $0x3f, %rsi
sarq $0x12, %rdx
addq %rdx, %rsi
movq 0x5e8a(%rip), %rdi      # 0x9fb8
callq 0x3190
movq %rax, %r14
leaq 0x301c(%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
cmpl $0x3, %ebp
jne 0x42bb
callq 0x3040
movq %rax, %r14
leaq 0x30(%rsp), %rdi
leaq 0x48(%rsp), %rsi
leaq 0x18(%rsp), %rdx
movq %rsp, %rcx
callq 0x3881
leaq 0x30(%rsp), %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0x5c8c
movq (%r15), %rdi
testq %rdi, %rdi
je 0x41be
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x31d0
movq %rbx, %rdi
callq 0x3ebc
leaq 0x48(%rsp), %rdi
movq %rbx, %rsi
callq 0x34dc
callq 0x3040
movq %rax, %r15
movq 0x5dd6(%rip), %rdi      # 0x9fb8
leaq 0x30be(%rip), %rsi      # 0x72a7
movl $0x30, %edx
callq 0x31e0
subq %r14, %r15
movq %r15, %rax
imulq %r12
movq %rdx, %rsi
shrq $0x3f, %rsi
sarq $0x12, %rdx
addq %rdx, %rsi
movq 0x5da7(%rip), %rdi      # 0x9fb8
callq 0x3190
movq %rax, %r14
leaq 0x2f39(%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
jmp 0x42bb
movq 0x5d8b(%rip), %rdi      # 0x9fe8
leaq 0x3074(%rip), %rsi      # 0x72d8
movl $0x7, %edx
callq 0x31e0
movq 0x5d73(%rip), %rdi      # 0x9fe8
movq %r14, %rsi
callq 0x3100
movq %rax, %r14
leaq 0x3059(%rip), %rsi      # 0x72e0
movl $0x14, %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 0x5d26(%rip), %rdi      # 0x9fe8
leaq 0x302c(%rip), %rsi      # 0x72f5
movl $0x8, %edx
callq 0x31e0
movq (%rbx), %rcx
movq 0x8(%rbx), %rax
cmpq %rax, %rcx
je 0x43dc
movq %rax, %rdx
subq %rcx, %rdx
sarq $0x4, %rdx
cmpq $0x2, %rdx
setb %r8b
jae 0x4324
testb %r8b, %r8b
je 0x4357
movq 0x20(%rsp), %rcx
subq 0x18(%rsp), %rcx
sarq $0x3, %rcx
movq 0x8(%rsp), %rdx
subq (%rsp), %rdx
sarq $0x3, %rdx
imulq %rcx, %rdx
cmpq %rdx, -0x8(%rax)
sete %al
jmp 0x4359
movq (%rcx), %rsi
cmpq 0x10(%rcx), %rsi
jae 0x4357
movl $0x1, %edi
leal 0x1(%rdi), %esi
cmpq %rsi, %rdx
setbe %r8b
jbe 0x42f7
movl %edi, %edi
shlq $0x4, %rdi
movq (%rcx,%rdi), %r8
movq %rsi, %r9
shlq $0x4, %r9
movl %esi, %edi
cmpq (%rcx,%r9), %r8
jb 0x4332
xorl %eax, %eax
movzbl %al, %esi
movq 0x5c85(%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 0x48(%rsp), %rdi
callq 0x4d80
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x43b2
movq 0x10(%rsp), %rsi
subq %rdi, %rsi
callq 0x31d0
movq 0x18(%rsp), %rdi
testq %rdi, %rdi
je 0x43c9
movq 0x28(%rsp), %rsi
subq %rdi, %rsi
callq 0x31d0
movq %rbx, %rax
addq $0x80, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2faa(%rip), %rdi      # 0x738d
leaq 0x2fc2(%rip), %rsi      # 0x73ac
leaq 0x2fc6(%rip), %rcx      # 0x73b7
movl $0x24, %edx
callq 0x30e0
leaq 0x2e26(%rip), %rdi      # 0x7228
leaq 0x2cb6(%rip), %rsi      # 0x70bf
leaq 0x2e37(%rip), %rcx      # 0x7247
movl $0x12f, %edx            # imm = 0x12F
callq 0x30e0
jmp 0x4439
jmp 0x4439
jmp 0x4439
jmp 0x4439
jmp 0x4439
jmp 0x4439
movq %rax, %r14
jmp 0x4446
movq %rax, %r14
jmp 0x445c
movq %rax, %r14
jmp 0x4473
jmp 0x4439
jmp 0x4439
movq %rax, %r14
leaq 0x48(%rsp), %rdi
callq 0x4d80
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x445c
movq 0x10(%rsp), %rsi
subq %rdi, %rsi
callq 0x31d0
movq 0x18(%rsp), %rdi
testq %rdi, %rdi
je 0x4473
movq 0x28(%rsp), %rsi
subq %rdi, %rsi
callq 0x31d0
movq (%rbx), %rdi
testq %rdi, %rdi
je 0x4487
movq 0x10(%rbx), %rsi
subq %rdi, %rsi
callq 0x31d0
movq %r14, %rdi
callq 0x32d0