// File: /workspace/github_cpp_makefile_star2_O3/stoianmihail[P]XY-sorting/algorithm.cpp
// Function: main
int main(int argc, char** argv) {
    srand(time(NULL));
    
    if (argc != 5) {
        std::cerr << "Usage: " << argv[0] << " [OPTION] [MAX_N] [MAX_VALUE_X] [MAX_VALUE_Y]" << std::endl;
        return -1;
    }
    
    OPTION = atoi(argv[1]);
    MAX_N = atoi(argv[2]);
    double d = boost::lexical_cast<double>(argv[3]);
    MAX_VALUE_X = static_cast<uint64_t>(d);
    d = boost::lexical_cast<double>(argv[4]);
    MAX_VALUE_Y = static_cast<uint64_t>(d);

    std::cerr << "check " << MAX_VALUE_X << " and " << MAX_VALUE_Y << std::endl;
    
    std::vector<cdf_coord> ret = chooseAlgorithm(OPTION);
#if 0
    printVector("X", xs);
    printVector("Y", ys);
#endif

#if 0
    std::unordered_map<uint32_t, bool> seen;
    sums.reserve(xs.size() * ys.size());
    for (unsigned index = 0; index < xs.size(); ++index) {
        for (unsigned ptr = 0; ptr < ys.size(); ++ptr) {
            uint32_t sum = xs[index] + ys[ptr];
            if (seen[sum])
                continue;
            seen[sum] = true;
            sums.push_back(std::make_pair(xs[index] + ys[ptr], std::make_pair(index, ptr)));
        }
    }
    
#if 1
    std::sort(sums.begin(), sums.end(), [](auto left, auto right) {
        return left.first < right.first;
    });
#endif

#endif

#if 0    
    cdf = util::buildCdf<sumCoord>(sums);
    spline = buildArtificial("artificial", xs, ys);
    
    util::printErrors(cdf, buildArtificial("artificial", xs, ys));
    
    std::cerr << "First point of spline: (" << spline.front().first << "," << spline.front().second << ") and last point of spline: (" << spline.back().first << "," << spline.back().second << ")" << std::endl; 
#endif
    
#if 0
    for (auto elem: spline) {
        std::cerr << elem.first << " " << elem.second << std::endl;
    }
#endif
    
#if 0
    adj.resize(sums.size(), 0);
    list.resize(sums.size() + 1); // the first buffer is not used
    for (auto elem: sums) {
        uint32_t currSum = elem.first;
        double estimation = interpolate(currSum);
        uint32_t index = static_cast<uint32_t>(round(estimation));
        index = index % sums.size();
        addSum(currSum, index);
    }
    
    std::cerr << "alles gut hier" << std::endl;
    
    unsigned currPos = 0;
    double avgLen = 0, maxLen = 0;
    std::cerr << "before resize with " << sums.size() << std::endl;
    final_.resize(sums.size());
    std::cerr << "after resize" << std::endl;
    for (unsigned index = 0; index < sums.size(); ++index) {
        // std::cerr << "Progress: " << index << std::endl;
        std::vector<uint32_t> currChain = computeChain(index);
        if (!currChain.empty()) {
            for (auto elem: currChain)
                insert(currPos++, elem);
        }
    }
    
    assert(currPos == sums.size());
    
    std::cerr << "Is sorted? " << std::is_sorted(final_.begin(), final_.end()) << std::endl;
#endif
    return 0;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x30, %rsp
movq %rsi, %r14
movl %edi, %ebx
xorl %edi, %edi
callq 0x3170
movl %eax, %edi
callq 0x31a0
cmpl $0x5, %ebx
jne 0x48e2
movq 0x8(%r14), %rdi
callq 0x3250
movl %eax, %ebx
leaq 0x18(%rsp), %r15
movq $0x0, (%r15)
leaq 0x4(%rsp), %r13
movq %r13, 0xc(%r13)
movq 0x18(%r14), %r12
movq %r12, 0x4(%r13)
movq %r12, %rdi
callq 0x30a0
addq %r12, %rax
movq %rax, 0xc(%r13)
leaq 0x20(%rsp), %rdi
movq %r12, (%rdi)
movq %rax, 0x8(%rdi)
movq %r15, %rsi
callq 0x5d1e
testb %al, %al
je 0x4986
leaq 0x18(%rsp), %r15
movsd (%r15), %xmm0
cvttsd2si %xmm0, %rax
movq %rax, %rcx
subsd 0x28e4(%rip), %xmm0     # 0x70a0
cvttsd2si %xmm0, %rdx
sarq $0x3f, %rcx
andq %rcx, %rdx
orq %rax, %rdx
movq %rdx, 0x5a16(%rip)      # 0xa1e8
movq $0x0, (%r15)
movq %r13, 0x10(%rsp)
movq 0x20(%r14), %r14
movq %r14, 0x8(%rsp)
movq %r14, %rdi
callq 0x30a0
addq %r14, %rax
movq %rax, 0x10(%rsp)
leaq 0x20(%rsp), %rdi
movq %r14, (%rdi)
movq %rax, 0x8(%rdi)
movq %r15, %rsi
callq 0x5d1e
testb %al, %al
je 0x49ae
movsd 0x18(%rsp), %xmm0
cvttsd2si %xmm0, %rax
movq %rax, %rcx
subsd 0x2877(%rip), %xmm0     # 0x70a0
cvttsd2si %xmm0, %rdx
sarq $0x3f, %rcx
andq %rcx, %rdx
orq %rax, %rdx
movq %rdx, 0x59b1(%rip)      # 0xa1f0
movq 0x57a2(%rip), %r14      # 0x9fe8
leaq 0x2ae7(%rip), %rsi      # 0x7334
movl $0x6, %edx
movq %r14, %rdi
callq 0x31e0
movq 0x5987(%rip), %rsi      # 0xa1e8
movq %r14, %rdi
callq 0x3100
movq %rax, %r14
leaq 0x2ac8(%rip), %rsi      # 0x733b
movl $0x5, %edx
movq %rax, %rdi
callq 0x31e0
movq 0x5969(%rip), %rsi      # 0xa1f0
movq %r14, %rdi
callq 0x3100
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
movq %rsp, %r14
movq %r14, %rdi
movl %ebx, %esi
callq 0x4027
movq (%r14), %rdi
testq %rdi, %rdi
je 0x48db
movq 0x10(%rsp), %rsi
subq %rdi, %rsi
callq 0x31d0
xorl %eax, %eax
jmp 0x4978
movq 0x56ff(%rip), %rbx      # 0x9fe8
leaq 0x2a0e(%rip), %rsi      # 0x72fe
movl $0x7, %edx
movq %rbx, %rdi
callq 0x31e0
movq (%r14), %r14
testq %r14, %r14
je 0x4921
movq %r14, %rdi
callq 0x30a0
movq 0x56d4(%rip), %rdi      # 0x9fe8
movq %r14, %rsi
movq %rax, %rdx
callq 0x31e0
jmp 0x4938
movq (%rbx), %rax
movq -0x18(%rax), %rax
leaq (%rbx,%rax), %rdi
movl 0x20(%rbx,%rax), %esi
orl $0x1, %esi
callq 0x32b0
leaq 0x29c7(%rip), %rsi      # 0x7306
movl $0x2d, %edx
movq %rbx, %rdi
callq 0x31e0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x31b0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x3030
movq %rax, %rdi
callq 0x3110
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
leaq 0x53cb(%rip), %rax      # 0x9d58
movq %rsp, %rdi
movq %rax, (%rdi)
movq 0x563e(%rip), %rax      # 0x9fd8
movq %rax, 0x8(%rdi)
movq 0x564b(%rip), %rax      # 0x9ff0
movq %rax, 0x10(%rdi)
callq 0x6161
leaq 0x53a3(%rip), %rax      # 0x9d58
movq %rsp, %rdi
movq %rax, (%rdi)
movq 0x5616(%rip), %rax      # 0x9fd8
movq %rax, 0x8(%rdi)
movq 0x5623(%rip), %rax      # 0x9ff0
movq %rax, 0x10(%rdi)
callq 0x6161
jmp 0x49d8
movq %rax, %rbx
movq %rsp, %rdi
callq 0x3260
movq %rbx, %rdi
callq 0x32d0