// File: umatin[P]LogarithmicErrorRegression/./src/helpers/io_handler.h
// Function: parse_arguments(int, char**)
std::vector<double> parse_arguments(int argc, char *argv[]){
    if(argc < 3){
        std::cout << "Specify Dataset and Size" << std::endl;
        std::cout << "Available option are:" << std::endl;
        std::cout << "path_to_dataset" << std::endl;
        std::cout << "rand" << std::endl;
        std::cout << "normal" << std::endl;
        std::cout << "lognormal" << std::endl;
        std::cout << "randint" << std::endl;
        std::cout << "debug" << std::endl;
        std::cout << "exp" << std::endl;
        std::cout << "outlier" << std::endl;
        exit(0);
    }
    
    long num_data = strtol(argv[2], nullptr, 0);
    std::vector<double> data;

    std::random_device rd;
    std::mt19937 gen(rd());
    
    if(strcmp(argv[1],"rand") == 0){
        std::uniform_real_distribution<double> dis(0, 2147483647);
        for (long i = 0; i < num_data; i++){
            data.push_back(dis(gen));
        }
    }
    else if(strcmp(argv[1],"normal") == 0){
        std::normal_distribution<double> dis(0.0,4.0);
        for (long i = 0; i < num_data; i++){
            data.push_back(dis(gen));
        }
    }
    else if(strcmp(argv[1],"lognormal") == 0){
        std::lognormal_distribution<double> dis(0.0, 4.0);
        for (long i = 0; i < num_data; i++){
            data.push_back(dis(gen));
        }
    }
    else if(strcmp(argv[1],"randint") == 0){
        for (long i = 0; i < num_data; i++){
            long val = rand();
            data.push_back(val);
        }
    }
    else if(strcmp(argv[1],"debug") == 0){
        for (long i = 0; i < num_data; i++){
            long val = rand()%30;
            data.push_back(val);
        }
    }
    else if(strcmp(argv[1],"randfixed") == 0){
        for (long i = 0; i < num_data; i++){
            std::uniform_real_distribution<double> dis(0, 10000);
            data.push_back(dis(gen));
        }
    }
    else if(strcmp(argv[1],"exp") == 0){
        for (long i = 0; i < num_data; i++){
            long val = std::pow(2,i);
            data.push_back(val);
        }
    }
    else if(strcmp(argv[1],"manual") == 0){
        for (long i = 2; i < argc; i++){
            data.push_back(strtol(argv[i], nullptr, 0));
        }
        std::cout << data.size() << std::endl;
        std::sort(data.begin(), data.end());
        return data;
    }
    else if(strcmp(argv[1],"outlier") == 0){
        int num_outliers = 1;
        for (long i = 0; i < num_data - num_outliers; i++){
            std::uniform_real_distribution<double> dis(0, 100000);
            data.push_back(dis(gen));
        }
        for (long i = 0; i < num_outliers; i++){
            std::uniform_real_distribution<double> dis(200000000000000, 300000000000000);
            data.push_back(dis(gen));
        }
    }
    else{
        if (cache_data.size() == 0){
            std::cout << argv[1] << "\n";
            cache_data = load_data<u_int64_t>(argv[1]);
        }

        data.reserve(num_data);
        std::uniform_int_distribution<long> dis(0, std::max<long>((long)cache_data.size()-1-num_data, 0));
        int start = dis(gen);
        for(long i = 0; cache_data[i] < LONG_MAX && i < num_data && i < cache_data.size(); i++){
            data.push_back((double)cache_data[start+i]);
        }
    }
    std::sort(data.begin(), data.end());
    //data.erase( unique( data.begin(), data.end() ), data.end() );
    //std::sort(data.begin(), data.end());
    return data;
}

// Assembly:
subq $0x2988, %rsp           # imm = 0x2988
movq %rdi, 0x70(%rsp)
movq %rdi, %rax
movq %rax, 0x78(%rsp)
movq %rdi, 0x2980(%rsp)
movl %esi, 0x297c(%rsp)
movq %rdx, 0x2970(%rsp)
cmpl $0x3, 0x297c(%rsp)
jge 0x3e64
movq 0x172c0(%rip), %rdi     # 0x1afd0
leaq 0x11411(%rip), %rsi     # 0x15128
callq 0x2210
movq %rax, %rdi
movq 0x1729a(%rip), %rsi     # 0x1afc0
callq 0x2240
movq 0x1729e(%rip), %rdi     # 0x1afd0
leaq 0x11408(%rip), %rsi     # 0x15141
callq 0x2210
movq %rax, %rdi
movq 0x17278(%rip), %rsi     # 0x1afc0
callq 0x2240
movq 0x1727c(%rip), %rdi     # 0x1afd0
leaq 0x113fc(%rip), %rsi     # 0x15157
callq 0x2210
movq %rax, %rdi
movq 0x17256(%rip), %rsi     # 0x1afc0
callq 0x2240
movq 0x1725a(%rip), %rdi     # 0x1afd0
leaq 0x113ea(%rip), %rsi     # 0x15167
callq 0x2210
movq %rax, %rdi
movq 0x17234(%rip), %rsi     # 0x1afc0
callq 0x2240
movq 0x17238(%rip), %rdi     # 0x1afd0
leaq 0x113d0(%rip), %rsi     # 0x1516f
callq 0x2210
movq %rax, %rdi
movq 0x17212(%rip), %rsi     # 0x1afc0
callq 0x2240
movq 0x17216(%rip), %rdi     # 0x1afd0
leaq 0x113ab(%rip), %rsi     # 0x1516c
callq 0x2210
movq %rax, %rdi
movq 0x171f0(%rip), %rsi     # 0x1afc0
callq 0x2240
movq 0x171f4(%rip), %rdi     # 0x1afd0
leaq 0x11393(%rip), %rsi     # 0x15176
callq 0x2210
movq %rax, %rdi
movq 0x171ce(%rip), %rsi     # 0x1afc0
callq 0x2240
movq 0x171d2(%rip), %rdi     # 0x1afd0
leaq 0x11379(%rip), %rsi     # 0x1517e
callq 0x2210
movq %rax, %rdi
movq 0x171ac(%rip), %rsi     # 0x1afc0
callq 0x2240
movq 0x171b0(%rip), %rdi     # 0x1afd0
leaq 0x1135d(%rip), %rsi     # 0x15184
callq 0x2210
movq %rax, %rdi
movq 0x1718a(%rip), %rsi     # 0x1afc0
callq 0x2240
movq 0x1718e(%rip), %rdi     # 0x1afd0
leaq 0x1133f(%rip), %rsi     # 0x15188
callq 0x2210
movq %rax, %rdi
movq 0x17168(%rip), %rsi     # 0x1afc0
callq 0x2240
xorl %edi, %edi
callq 0x2290
movq 0x2970(%rsp), %rax
movq 0x10(%rax), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x22e0
movq 0x70(%rsp), %rdi
movq %rax, 0x2968(%rsp)
movb $0x0, 0x2967(%rsp)
callq 0x69c0
leaq 0x15d8(%rsp), %rdi
callq 0x69d0
jmp 0x3ea2
leaq 0x15d8(%rsp), %rdi
callq 0x6a70
movl %eax, 0x6c(%rsp)
jmp 0x3eb5
movl 0x6c(%rsp), %eax
movl %eax, %eax
movl %eax, %esi
leaq 0x240(%rsp), %rdi
callq 0x6a80
jmp 0x3ecc
movq 0x2970(%rsp), %rax
movq 0x8(%rax), %rdi
leaq 0x11288(%rip), %rsi     # 0x15167
callq 0x22d0
cmpl $0x0, %eax
jne 0x3fc6
leaq 0x230(%rsp), %rdi
vpxor %xmm0, %xmm0, %xmm0
vmovsd 0x1113f(%rip), %xmm1    # 0x15040
callq 0x6ab0
jmp 0x3f08
movq $0x0, 0x228(%rsp)
movq 0x228(%rsp), %rax
cmpq 0x2968(%rsp), %rax
jge 0x3fc1
leaq 0x230(%rsp), %rdi
leaq 0x240(%rsp), %rsi
callq 0x6b10
vmovsd %xmm0, 0x60(%rsp)
jmp 0x3f47
movq 0x70(%rsp), %rdi
vmovsd 0x60(%rsp), %xmm0
vmovsd %xmm0, 0x220(%rsp)
leaq 0x220(%rsp), %rsi
callq 0x6ae0
jmp 0x3f6a
jmp 0x3f6c
movq 0x228(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x228(%rsp)
jmp 0x3f14
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x15d0(%rsp)
movl %eax, 0x15cc(%rsp)
jmp 0x4905
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x15d0(%rsp)
movl %eax, 0x15cc(%rsp)
leaq 0x15d8(%rsp), %rdi
callq 0x6f00
jmp 0x4905
jmp 0x4889
movq 0x2970(%rsp), %rax
movq 0x8(%rax), %rdi
leaq 0x11196(%rip), %rsi     # 0x1516f
callq 0x22d0
cmpl $0x0, %eax
jne 0x407d
leaq 0x200(%rsp), %rdi
vpxor %xmm0, %xmm0, %xmm0
vmovsd 0x1103d(%rip), %xmm1    # 0x15038
callq 0x6b40
jmp 0x4002
movq $0x0, 0x1f8(%rsp)
movq 0x1f8(%rsp), %rax
cmpq 0x2968(%rsp), %rax
jge 0x4078
leaq 0x200(%rsp), %rdi
leaq 0x240(%rsp), %rsi
callq 0x6b90
vmovsd %xmm0, 0x58(%rsp)
jmp 0x403d
movq 0x70(%rsp), %rdi
vmovsd 0x58(%rsp), %xmm0
vmovsd %xmm0, 0x1f0(%rsp)
leaq 0x1f0(%rsp), %rsi
callq 0x6ae0
jmp 0x4060
jmp 0x4062
movq 0x1f8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x1f8(%rsp)
jmp 0x400e
jmp 0x4887
movq 0x2970(%rsp), %rax
movq 0x8(%rax), %rdi
leaq 0x110dc(%rip), %rsi     # 0x1516c
callq 0x22d0
cmpl $0x0, %eax
jne 0x4134
leaq 0x1c0(%rsp), %rdi
vpxor %xmm0, %xmm0, %xmm0
vmovsd 0x10f86(%rip), %xmm1    # 0x15038
callq 0x6bc0
jmp 0x40b9
movq $0x0, 0x1b8(%rsp)
movq 0x1b8(%rsp), %rax
cmpq 0x2968(%rsp), %rax
jge 0x412f
leaq 0x1c0(%rsp), %rdi
leaq 0x240(%rsp), %rsi
callq 0x6c10
vmovsd %xmm0, 0x50(%rsp)
jmp 0x40f4
movq 0x70(%rsp), %rdi
vmovsd 0x50(%rsp), %xmm0
vmovsd %xmm0, 0x1b0(%rsp)
leaq 0x1b0(%rsp), %rsi
callq 0x6ae0
jmp 0x4117
jmp 0x4119
movq 0x1b8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x1b8(%rsp)
jmp 0x40c5
jmp 0x4885
movq 0x2970(%rsp), %rax
movq 0x8(%rax), %rdi
leaq 0x1102f(%rip), %rsi     # 0x15176
callq 0x22d0
cmpl $0x0, %eax
jne 0x41c2
movq $0x0, 0x1a8(%rsp)
movq 0x1a8(%rsp), %rax
cmpq 0x2968(%rsp), %rax
jge 0x41bd
callq 0x2080
movq 0x70(%rsp), %rdi
cltq
movq %rax, 0x1a0(%rsp)
vcvtsi2sdq 0x1a0(%rsp), %xmm0, %xmm0
vmovsd %xmm0, 0x198(%rsp)
leaq 0x198(%rsp), %rsi
callq 0x6ae0
jmp 0x41a5
jmp 0x41a7
movq 0x1a8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x1a8(%rsp)
jmp 0x415d
jmp 0x4883
movq 0x2970(%rsp), %rax
movq 0x8(%rax), %rdi
leaq 0x10fa9(%rip), %rsi     # 0x1517e
callq 0x22d0
cmpl $0x0, %eax
jne 0x427c
movq $0x0, 0x190(%rsp)
movq 0x190(%rsp), %rax
cmpq 0x2968(%rsp), %rax
jge 0x4277
callq 0x2080
movq 0x70(%rsp), %rdi
movslq %eax, %rcx
imulq $-0x77777777, %rcx, %rcx # imm = 0x88888889
shrq $0x20, %rcx
addl %eax, %ecx
movl %ecx, %edx
shrl $0x1f, %edx
sarl $0x4, %ecx
addl %edx, %ecx
movl %ecx, %edx
shll $0x5, %edx
addl %ecx, %ecx
subl %edx, %ecx
addl %ecx, %eax
cltq
movq %rax, 0x188(%rsp)
vcvtsi2sdq 0x188(%rsp), %xmm0, %xmm0
vmovsd %xmm0, 0x180(%rsp)
leaq 0x180(%rsp), %rsi
callq 0x6ae0
jmp 0x425c
jmp 0x425e
movq 0x190(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x190(%rsp)
jmp 0x41ef
jmp 0x4881
movq 0x2970(%rsp), %rax
movq 0x8(%rax), %rdi
leaq 0x10f01(%rip), %rsi     # 0x15190
callq 0x22d0
cmpl $0x0, %eax
jne 0x4336
movq $0x0, 0x178(%rsp)
movq 0x178(%rsp), %rax
cmpq 0x2968(%rsp), %rax
jge 0x4331
leaq 0x168(%rsp), %rdi
vpxor %xmm0, %xmm0, %xmm0
vmovsd 0x10d61(%rip), %xmm1    # 0x15030
callq 0x6ab0
jmp 0x42d6
leaq 0x168(%rsp), %rdi
leaq 0x240(%rsp), %rsi
callq 0x6b10
vmovsd %xmm0, 0x48(%rsp)
jmp 0x42f3
movq 0x70(%rsp), %rdi
vmovsd 0x48(%rsp), %xmm0
vmovsd %xmm0, 0x160(%rsp)
leaq 0x160(%rsp), %rsi
callq 0x6ae0
jmp 0x4316
jmp 0x4318
movq 0x178(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x178(%rsp)
jmp 0x42a9
jmp 0x487f
movq 0x2970(%rsp), %rax
movq 0x8(%rax), %rdi
leaq 0x10e3b(%rip), %rsi     # 0x15184
callq 0x22d0
cmpl $0x0, %eax
jne 0x43e6
movq $0x0, 0x158(%rsp)
movq 0x158(%rsp), %rax
cmpq 0x2968(%rsp), %rax
jge 0x43e1
movq 0x158(%rsp), %rsi
movl $0x2, %edi
callq 0x6c40
vmovsd %xmm0, 0x40(%rsp)
jmp 0x438f
movq 0x70(%rsp), %rdi
vmovsd 0x40(%rsp), %xmm0
vcvttsd2si %xmm0, %rax
movq %rax, 0x150(%rsp)
vcvtsi2sdq 0x150(%rsp), %xmm0, %xmm0
vmovsd %xmm0, 0x148(%rsp)
leaq 0x148(%rsp), %rsi
callq 0x6ae0
jmp 0x43c9
jmp 0x43cb
movq 0x158(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x158(%rsp)
jmp 0x4363
jmp 0x487d
movq 0x2970(%rsp), %rax
movq 0x8(%rax), %rdi
leaq 0x10da1(%rip), %rsi     # 0x1519a
callq 0x22d0
cmpl $0x0, %eax
jne 0x4505
movq $0x2, 0x140(%rsp)
movq 0x140(%rsp), %rax
movslq 0x297c(%rsp), %rcx
cmpq %rcx, %rax
jge 0x447f
movq 0x2970(%rsp), %rax
movq 0x140(%rsp), %rcx
movq (%rax,%rcx,8), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x22e0
movq 0x70(%rsp), %rdi
vcvtsi2sd %rax, %xmm0, %xmm0
vmovsd %xmm0, 0x138(%rsp)
leaq 0x138(%rsp), %rsi
callq 0x6ae0
jmp 0x4467
jmp 0x4469
movq 0x140(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x140(%rsp)
jmp 0x4413
movq 0x70(%rsp), %rdi
callq 0x6400
movq %rax, %rsi
movq 0x16b3d(%rip), %rdi     # 0x1afd0
callq 0x2060
movq %rax, 0x38(%rsp)
jmp 0x449f
movq 0x38(%rsp), %rdi
movq 0x16b15(%rip), %rsi     # 0x1afc0
callq 0x2240
jmp 0x44b2
movq 0x70(%rsp), %rdi
callq 0x6cb0
movq 0x70(%rsp), %rdi
movq %rax, 0x130(%rsp)
callq 0x6ce0
movq %rax, 0x128(%rsp)
movq 0x130(%rsp), %rdi
movq 0x128(%rsp), %rsi
callq 0x6c70
jmp 0x44ed
movb $0x1, 0x2967(%rsp)
movl $0x1, 0x124(%rsp)
jmp 0x48d7
movq 0x2970(%rsp), %rax
movq 0x8(%rax), %rdi
leaq 0x10c70(%rip), %rsi     # 0x15188
callq 0x22d0
cmpl $0x0, %eax
jne 0x4673
movl $0x1, 0x120(%rsp)
movq $0x0, 0x118(%rsp)
movq 0x118(%rsp), %rax
movq 0x2968(%rsp), %rcx
movslq 0x120(%rsp), %rdx
subq %rdx, %rcx
cmpq %rcx, %rax
jge 0x45d3
leaq 0x108(%rsp), %rdi
vpxor %xmm0, %xmm0, %xmm0
vmovsd 0x10ab7(%rip), %xmm1    # 0x15028
callq 0x6ab0
jmp 0x4578
leaq 0x108(%rsp), %rdi
leaq 0x240(%rsp), %rsi
callq 0x6b10
vmovsd %xmm0, 0x30(%rsp)
jmp 0x4595
movq 0x70(%rsp), %rdi
vmovsd 0x30(%rsp), %xmm0
vmovsd %xmm0, 0x100(%rsp)
leaq 0x100(%rsp), %rsi
callq 0x6ae0
jmp 0x45b8
jmp 0x45ba
movq 0x118(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x118(%rsp)
jmp 0x453d
movq $0x0, 0xf8(%rsp)
movq 0xf8(%rsp), %rax
movslq 0x120(%rsp), %rcx
cmpq %rcx, %rax
jge 0x466e
leaq 0xe8(%rsp), %rdi
vmovsd 0x10a14(%rip), %xmm0    # 0x15018
vmovsd 0x10a14(%rip), %xmm1    # 0x15020
callq 0x6ab0
jmp 0x4613
leaq 0xe8(%rsp), %rdi
leaq 0x240(%rsp), %rsi
callq 0x6b10
vmovsd %xmm0, 0x28(%rsp)
jmp 0x4630
movq 0x70(%rsp), %rdi
vmovsd 0x28(%rsp), %xmm0
vmovsd %xmm0, 0xe0(%rsp)
leaq 0xe0(%rsp), %rsi
callq 0x6ae0
jmp 0x4653
jmp 0x4655
movq 0xf8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xf8(%rsp)
jmp 0x45df
jmp 0x4879
leaq 0x16bde(%rip), %rdi     # 0x1b258
callq 0x6d10
cmpq $0x0, %rax
jne 0x46f3
movq 0x2970(%rsp), %rax
movq 0x8(%rax), %rsi
movq 0x16938(%rip), %rdi     # 0x1afd0
callq 0x2210
movq %rax, 0x20(%rsp)
jmp 0x46a4
movq 0x20(%rsp), %rdi
leaq 0x10af1(%rip), %rsi     # 0x151a1
callq 0x2210
jmp 0x46b7
movq 0x2970(%rsp), %rax
movq 0x8(%rax), %rsi
leaq 0xc8(%rsp), %rdi
callq 0x4920
jmp 0x46d2
leaq 0x16b7f(%rip), %rdi     # 0x1b258
leaq 0xc8(%rsp), %rsi
callq 0x6d30
leaq 0xc8(%rsp), %rdi
callq 0x6960
movq 0x70(%rsp), %rdi
movq 0x2968(%rsp), %rsi
callq 0x6d70
jmp 0x4707
leaq 0x16b4a(%rip), %rdi     # 0x1b258
callq 0x6d10
movq %rax, %rcx
movq 0x2968(%rsp), %rax
notq %rax
addq %rcx, %rax
movq %rax, 0xb0(%rsp)
movq $0x0, 0xa8(%rsp)
leaq 0xb0(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x66b0
movq %rax, 0x18(%rsp)
jmp 0x4754
movq 0x18(%rsp), %rax
movq (%rax), %rdx
xorl %eax, %eax
movl %eax, %esi
leaq 0xb8(%rsp), %rdi
callq 0x6e80
jmp 0x476f
leaq 0xb8(%rsp), %rdi
leaq 0x240(%rsp), %rsi
callq 0x6eb0
movq %rax, 0x10(%rsp)
jmp 0x478b
movq 0x10(%rsp), %rax
movl %eax, 0xa4(%rsp)
movq $0x0, 0x98(%rsp)
movq 0x98(%rsp), %rsi
leaq 0x16aa6(%rip), %rdi     # 0x1b258
callq 0x6ee0
movq %rax, %rcx
xorl %eax, %eax
movabsq $0x7fffffffffffffff, %rdx # imm = 0x7FFFFFFFFFFFFFFF
cmpq %rdx, (%rcx)
movb %al, 0xf(%rsp)
jae 0x4810
movq 0x98(%rsp), %rcx
xorl %eax, %eax
cmpq 0x2968(%rsp), %rcx
movb %al, 0xf(%rsp)
jge 0x4810
movq 0x98(%rsp), %rax
movq %rax, (%rsp)
leaq 0x16a5e(%rip), %rdi     # 0x1b258
callq 0x6d10
movq %rax, %rcx
movq (%rsp), %rax
cmpq %rcx, %rax
setb %al
movb %al, 0xf(%rsp)
movb 0xf(%rsp), %al
testb $0x1, %al
jne 0x481a
jmp 0x4877
movslq 0xa4(%rsp), %rsi
movq 0x98(%rsp), %rax
addq %rax, %rsi
leaq 0x16a24(%rip), %rdi     # 0x1b258
callq 0x6ee0
movq 0x70(%rsp), %rdi
vcvtusi2sdq (%rax), %xmm0, %xmm0
vmovsd %xmm0, 0x90(%rsp)
leaq 0x90(%rsp), %rsi
callq 0x6ae0
jmp 0x485c
jmp 0x485e
movq 0x98(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x98(%rsp)
jmp 0x47a3
jmp 0x4879
jmp 0x487b
jmp 0x487d
jmp 0x487f
jmp 0x4881
jmp 0x4883
jmp 0x4885
jmp 0x4887
jmp 0x4889
movq 0x70(%rsp), %rdi
callq 0x6cb0
movq 0x70(%rsp), %rdi
movq %rax, 0x88(%rsp)
callq 0x6ce0
movq %rax, 0x80(%rsp)
movq 0x88(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0x6c70
jmp 0x48c4
movb $0x1, 0x2967(%rsp)
movl $0x1, 0x124(%rsp)
leaq 0x15d8(%rsp), %rdi
callq 0x6f00
testb $0x1, 0x2967(%rsp)
jne 0x48f8
movq 0x70(%rsp), %rdi
callq 0x6560
movq 0x78(%rsp), %rax
addq $0x2988, %rsp           # imm = 0x2988
retq
movq 0x70(%rsp), %rdi
callq 0x6560
movq 0x15d0(%rsp), %rdi
callq 0x23b0
nopl (%rax)