// File: /workspace/github_cpp_makefile_star2_O2/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 %rbx
subq $0x88, %rsp
movl %esi, %ebp
movq %rdi, %rbx
xorps %xmm0, %xmm0
movups %xmm0, (%rdi)
andq $0x0, 0x10(%rdi)
movq 0x74ac(%rip), %rsi      # 0xb1e0
leaq 0x20(%rsp), %rdi
callq 0x4053
movq 0x74a3(%rip), %rsi      # 0xb1e8
leaq 0x8(%rsp), %rdi
callq 0x4053
leaq 0x50(%rsp), %rdi
leaq 0x20(%rsp), %rsi
leaq 0x8(%rsp), %rdx
callq 0x34e3
movl %ebp, %r14d
cmpl $0x3, %ebp
ja 0x3ed1
leaq 0x32ea(%rip), %rax      # 0x7060
movslq (%rax,%r14,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq 0x7262(%rip), %rdi      # 0xafe8
leaq 0x34bb(%rip), %rsi      # 0x7248
callq 0x31c0
movq %rax, %rdi
callq 0x30c0
callq 0x3030
movq %rax, %r14
leaq 0x38(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0x35d9
leaq 0x38(%rsp), %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0x5982
movq %r15, %rdi
callq 0x5454
movq %rbx, %rdi
callq 0x3625
leaq 0x50(%rsp), %rdi
movq %rbx, %rsi
callq 0x348c
callq 0x3030
movq %rax, %r15
movq 0x71d3(%rip), %rdi      # 0xafc0
leaq 0x345c(%rip), %rsi      # 0x7250
callq 0x31c0
movq %rax, %rdi
subq %r14, %r15
movl $0xf4240, %ecx          # imm = 0xF4240
movq %r15, %rax
cqto
idivq %rcx
movq %rax, %rsi
callq 0x31a0
leaq 0x330e(%rip), %rsi      # 0x7129
movq %rax, %rdi
callq 0x31c0
movq %rax, %rdi
callq 0x30c0
cmpl $0x3, %ebp
jne 0x3f06
callq 0x3030
movq %rax, %r14
leaq 0x38(%rsp), %rdi
leaq 0x50(%rsp), %rsi
leaq 0x20(%rsp), %rdx
leaq 0x8(%rsp), %rcx
callq 0x378b
leaq 0x38(%rsp), %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0x5982
movq %r15, %rdi
callq 0x5454
movq %rbx, %rdi
callq 0x3c3c
leaq 0x50(%rsp), %rdi
movq %rbx, %rsi
callq 0x348c
callq 0x3030
movq %rax, %r15
movq 0x712f(%rip), %rdi      # 0xafc0
leaq 0x33df(%rip), %rsi      # 0x7277
callq 0x31c0
movq %rax, %rdi
subq %r14, %r15
movl $0xf4240, %ecx          # imm = 0xF4240
movq %r15, %rax
cqto
idivq %rcx
movq %rax, %rsi
callq 0x31a0
leaq 0x326a(%rip), %rsi      # 0x7129
movq %rax, %rdi
callq 0x31c0
movq %rax, %rdi
callq 0x30c0
jmp 0x3f06
movq 0x7110(%rip), %rdi      # 0xafe8
leaq 0x33c9(%rip), %rsi      # 0x72a8
callq 0x31c0
movq %rax, %rdi
movq %r14, %rsi
callq 0x3120
leaq 0x33ba(%rip), %rsi      # 0x72b0
movq %rax, %rdi
callq 0x31c0
movq %rax, %rdi
callq 0x30c0
movq 0x70db(%rip), %rdi      # 0xafe8
leaq 0x33b1(%rip), %rsi      # 0x72c5
callq 0x31c0
movq (%rbx), %rdx
movq 0x8(%rbx), %rcx
cmpq %rcx, %rdx
je 0x3fc7
movq %rcx, %rsi
subq %rdx, %rsi
sarq $0x4, %rsi
xorl %r8d, %r8d
leal 0x1(%r8), %edi
cmpq %rdi, %rsi
jbe 0x3f5e
movl %r8d, %r8d
shlq $0x4, %r8
movq (%rdx,%r8), %r9
movq %rdi, %r10
shlq $0x4, %r10
movl %edi, %r8d
cmpq (%rdx,%r10), %r9
jb 0x3f36
xorl %ecx, %ecx
jmp 0x3f85
movq 0x28(%rsp), %rdx
subq 0x20(%rsp), %rdx
sarq $0x3, %rdx
movq 0x10(%rsp), %rsi
subq 0x8(%rsp), %rsi
sarq $0x3, %rsi
imulq %rdx, %rsi
cmpq %rsi, -0x8(%rcx)
sete %cl
movzbl %cl, %esi
movq %rax, %rdi
callq 0x3280
movq %rax, %rdi
callq 0x30c0
leaq 0x50(%rsp), %rdi
callq 0x4678
leaq 0x8(%rsp), %rdi
callq 0x509a
leaq 0x20(%rsp), %rdi
callq 0x509a
movq %rbx, %rax
addq $0x88, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x338f(%rip), %rdi      # 0x735d
leaq 0x33a7(%rip), %rsi      # 0x737c
leaq 0x33ab(%rip), %rcx      # 0x7387
pushq $0x24
popq %rdx
callq 0x3100
leaq 0x320d(%rip), %rdi      # 0x71f8
leaq 0x309d(%rip), %rsi      # 0x708f
leaq 0x321e(%rip), %rcx      # 0x7217
movl $0x12f, %edx            # imm = 0x12F
callq 0x3100
jmp 0x4022
jmp 0x4022
jmp 0x4022
jmp 0x4022
jmp 0x4022
jmp 0x4022
movq %rax, %r14
jmp 0x402f
movq %rax, %r14
jmp 0x4039
movq %rax, %r14
jmp 0x4043
jmp 0x4022
jmp 0x4022
movq %rax, %r14
leaq 0x50(%rsp), %rdi
callq 0x4678
leaq 0x8(%rsp), %rdi
callq 0x509a
leaq 0x20(%rsp), %rdi
callq 0x509a
movq %rbx, %rdi
callq 0x5454
movq %r14, %rdi
callq 0x32c0