// File: /workspace/github_cpp_makefile_star2_O1/robertomaldonado[P]HypercubeTopologyRouting/links.cpp
// Function: main
int main(int argc, char * argv[]){
    //Check arguments for right input
    if ( !isArgCountCorrect ( argc ) ) return 1;
    total_nodes = std::stoi(argv[1]);
    if ( !isPowerOfTwo(total_nodes) ) return 1;
    string routing_model = argv[2];
    if ( !isValidOption(routing_model) ) return 1;
    bits_for_node = log2(total_nodes);

    //Create a vector to hold a binary representation
    map<int, vector<int> > nodes_map;
    create_map( nodes_map );
    printf("%s", map_to_bin_str( nodes_map, total_nodes).c_str() );

    //TO-DO: Get source and destination from the console*/
    int source = 1, destination = 30, path = 10;

    if( routing_model == "dim" ){

        // int len = dim_order_routing(source, destination, &path );
        printf("Dimensional order routing\n");
        while(1){
            printf("input src dst : ");
            cin >> source; cin >> destination; 

            int bits_to_change =  source^destination;

            vector<bool> vector_src = int_to_bin_vector( bits_for_node, source);
            vector<bool> xor_guide = int_to_bin_vector( bits_for_node, bits_to_change);
            vector<int> dim_ord_route;
            int current;
            dim_ord_route.push_back( source );

            for(int i = 0 ; i < xor_guide.size() ; i++){
                if(xor_guide[i]) {
                    vector_src[i] = !vector_src[i];
                    current = bin_vector_to_int( bits_for_node, vector_src);
                    dim_ord_route.push_back( current );
                }
            }
            printf("path from %d to %d: ", source, destination);
            print_single_route(bits_for_node, dim_ord_route);
        
            if( (source > (total_nodes - 1)) ||  (destination > (total_nodes - 1)) ){
                printf( "dim_order_routing: src %d, dst %d, out of bound 0..%d",
                source, destination, total_nodes);
                return 1;
            }
        }

    }else if(routing_model == "all"){

        // int allpath[MAX_PATH][MAXZ_PATH_LEN];
        // int allpath_routing(source, destination, allpath);
        printf("All shortest path routing\n");

        while(1){
            printf("input src dst : ");
            cin >> source; cin >> destination;  

            //XOR to get a get a guide on which bits need to be changed
            int bits_to_change =  source^destination;
            //Convert source and guide to vector of bits
            vector<bool> vector_src = int_to_bin_vector( bits_for_node, source);
            vector<bool> vector_dst = int_to_bin_vector( bits_for_node, destination);
            vector<bool> xor_guide = int_to_bin_vector( bits_for_node, bits_to_change);
            vector<int> all_ord_route;
            //The structure of neighbors is hold in a map.
            //To store here the path for each route found.
            map<int, vector<int> > paths_map;

            int current;
            //The source is the first node
            all_ord_route.push_back( source );
            //For each  bit changed on on the guide, flip the bit
            recursive_flip(vector_src, vector_dst, xor_guide);

            paths_map[ 0 ] = all_ord_route;
            paths_map[ 1 ] = all_ord_route;

            map<int, vector<int> >::iterator it = paths_map.begin();
            int counter = 0;
            for (int i = 0; i < xor_guide.size(); i++ )
                if( xor_guide[i] )
                    counter++;

            printf("%d shortest paths from %d to %d: \n", factorial(counter), source, destination);
            print_multiple_routes(paths_map);

            if( (source > (total_nodes - 1)) ||  (destination > (total_nodes - 1)) ){
                printf( "dim_order_routing: src %d, dst %d, out of bound 0..%d",
                source, destination, total_nodes);
                return 1;
            }
        }
    }
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1e8, %rsp            # imm = 0x1E8
movq %rsi, %rbx
callq 0x43e8
movl $0x1, %r14d
testl %eax, %eax
je 0x2e15
movq 0x8(%rbx), %rsi
leaq -0x1f0(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x20c0
movq -0x1f0(%rbp), %r15
callq 0x2040
movq %rax, %r14
movl (%rax), %r13d
movl $0x0, (%rax)
leaq -0xc0(%rbp), %r12
movq %r15, %rdi
movq %r12, %rsi
movl $0xa, %edx
callq 0x21f0
cmpq %r15, (%r12)
je 0x2e2a
movslq %eax, %rcx
cmpq %rax, %rcx
jne 0x2e36
movl (%r14), %ecx
cmpl $0x22, %ecx
je 0x2e36
testl %ecx, %ecx
jne 0x2672
movl %r13d, (%r14)
movl %eax, 0x6b10(%rip)      # 0x9188
leaq -0x1e0(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x268d
callq 0x2180
movl 0x6af5(%rip), %edi      # 0x9188
callq 0x4443
testl %eax, %eax
movl $0x1, %r14d
je 0x2e15
movq 0x10(%rbx), %rsi
leaq -0x1c0(%rbp), %rdi
leaq -0x1f0(%rbp), %rdx
callq 0x20c0
leaq -0x200(%rbp), %r14
movq %r14, -0x10(%r14)
movq -0x1c0(%rbp), %rsi
movq -0x1b8(%rbp), %rdx
addq %rsi, %rdx
leaq -0x210(%rbp), %rdi
callq 0x3cf4
leaq -0x210(%rbp), %rdi
callq 0x44d0
movl %eax, %ebx
movq -0x210(%rbp), %rdi
cmpq %r14, %rdi
je 0x2704
callq 0x2180
testl %ebx, %ebx
je 0x2b49
cvtsi2sdl 0x6a74(%rip), %xmm0 # 0x9188
callq 0x2290
cvttsd2si %xmm0, %eax
movl %eax, 0x6a69(%rip)      # 0x918c
leaq -0x1e8(%rbp), %rax
movl $0x0, (%rax)
xorl %ecx, %ecx
movq %rcx, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
movq %rcx, 0x20(%rax)
leaq -0x1f0(%rbp), %rdi
callq 0x30b0
movl 0x6a34(%rip), %edx      # 0x9188
leaq -0xc0(%rbp), %rdi
leaq -0x1f0(%rbp), %rsi
callq 0x4550
leaq -0xb0(%rbp), %rbx
movq -0x10(%rbx), %rsi
leaq 0x38a7(%rip), %rdi      # 0x6020
xorl %eax, %eax
callq 0x2050
movq -0x10(%rbx), %rdi
cmpq %rbx, %rdi
je 0x278e
callq 0x2180
movl $0x1, -0x2c(%rbp)
movl $0x1e, -0x30(%rbp)
leaq 0x3880(%rip), %rsi      # 0x6023
leaq -0x1c0(%rbp), %rdi
callq 0x2090
testl %eax, %eax
je 0x2b54
leaq 0x38c5(%rip), %rsi      # 0x6083
leaq -0x1c0(%rbp), %rdi
callq 0x2090
movl $0x0, -0x34(%rbp)
testl %eax, %eax
jne 0x2df0
leaq 0x394f(%rip), %rdi      # 0x612f
callq 0x2230
xorl %r12d, %r12d
movq 0x67f1(%rip), %r13      # 0x8fe0
leaq -0xc0(%rbp), %r14
movl $0x0, -0x34(%rbp)
leaq 0x3823(%rip), %rdi      # 0x6027
xorl %eax, %eax
callq 0x2050
movq %r13, %rdi
leaq -0x2c(%rbp), %rsi
callq 0x2100
movq %r13, %rdi
leaq -0x30(%rbp), %rsi
callq 0x2100
movl -0x2c(%rbp), %edx
movl -0x30(%rbp), %ebx
xorl %edx, %ebx
movl 0x695b(%rip), %esi      # 0x918c
leaq -0x60(%rbp), %rdi
callq 0x4a77
movl 0x694c(%rip), %esi      # 0x918c
movl -0x30(%rbp), %edx
leaq -0x90(%rbp), %rdi
callq 0x4a77
movl 0x6937(%rip), %esi      # 0x918c
leaq -0xe8(%rbp), %rdi
movl %ebx, %edx
callq 0x4a77
xorpd %xmm0, %xmm0
movapd %xmm0, -0x100(%rbp)
movq %r12, -0xf0(%rbp)
movl $0x0, -0xb8(%rbp)
movq %r12, -0xb0(%rbp)
leaq -0xb8(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq %rax, -0xa0(%rbp)
movq %r12, -0x98(%rbp)
movq -0xf8(%rbp), %rsi
testq %rsi, %rsi
leaq -0x150(%rbp), %rbx
je 0x28c8
movl -0x2c(%rbp), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, -0xf8(%rbp)
jmp 0x28d8
leaq -0x100(%rbp), %rdi
leaq -0x2c(%rbp), %rdx
callq 0x3dbe
movq %rbx, %rdi
leaq -0x60(%rbp), %rsi
callq 0x3966
leaq -0x128(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x3966
leaq -0x178(%rbp), %r15
movq %r15, %rdi
leaq -0xe8(%rbp), %rsi
callq 0x3966
movq %rbx, %rdi
leaq -0x128(%rbp), %rsi
movq %r15, %rdx
callq 0x337f
movq -0x178(%rbp), %rdi
testq %rdi, %rdi
je 0x2953
callq 0x2180
movq %r12, -0x178(%rbp)
movl %r12d, -0x170(%rbp)
movq %r12, -0x168(%rbp)
movl %r12d, -0x160(%rbp)
movq %r12, -0x158(%rbp)
movq -0x128(%rbp), %rdi
testq %rdi, %rdi
je 0x2987
callq 0x2180
movq %r12, -0x128(%rbp)
movl %r12d, -0x120(%rbp)
movq %r12, -0x118(%rbp)
movl %r12d, -0x110(%rbp)
movq %r12, -0x108(%rbp)
movq -0x150(%rbp), %rdi
testq %rdi, %rdi
je 0x29bb
callq 0x2180
movq %r12, -0x150(%rbp)
movl %r12d, -0x148(%rbp)
movq %r12, -0x140(%rbp)
movl %r12d, -0x138(%rbp)
movq %r12, -0x130(%rbp)
movl $0x0, -0x38(%rbp)
movq %r14, %rdi
leaq -0x38(%rbp), %rsi
callq 0x3a04
movq %rax, %rdi
leaq -0x100(%rbp), %rsi
callq 0x3a6c
movl $0x1, -0x38(%rbp)
movq %r14, %rdi
leaq -0x38(%rbp), %rsi
callq 0x3a04
movq %rax, %rdi
leaq -0x100(%rbp), %rsi
callq 0x3a6c
movq -0xe8(%rbp), %rcx
movq -0xd8(%rbp), %rdx
movl -0xd0(%rbp), %eax
subq %rcx, %rdx
shlq $0x3, %rdx
addq %rax, %rdx
je 0x2a3f
xorl %esi, %esi
xorl %eax, %eax
movq %rsi, %rdi
shrq $0x6, %rdi
movq (%rcx,%rdi,8), %rdi
btq %rsi, %rdi
adcl $0x0, %eax
incq %rsi
cmpq %rsi, %rdx
ja 0x2a23
jmp 0x2a41
xorl %eax, %eax
movl $0x1, %esi
testl %eax, %eax
jle 0x2a57
imull %eax, %esi
leal -0x1(%rax), %ecx
cmpl $0x1, %eax
movl %ecx, %eax
jg 0x2a4a
movl -0x2c(%rbp), %edx
movl -0x30(%rbp), %ecx
leaq 0x3623(%rip), %rdi      # 0x6087
xorl %eax, %eax
callq 0x2050
movq %r14, %rdi
callq 0x38e9
movl -0x2c(%rbp), %esi
movl 0x670c(%rip), %ecx      # 0x9188
cmpl %ecx, %esi
setl %al
movl -0x30(%rbp), %edx
cmpl %ecx, %edx
setl %bl
andb %al, %bl
jne 0x2aa2
leaq 0x35b9(%rip), %rdi      # 0x604d
xorl %eax, %eax
callq 0x2050
movl $0x1, -0x34(%rbp)
movq %r14, %rdi
callq 0x3c68
movq -0x100(%rbp), %rdi
testq %rdi, %rdi
je 0x2abb
callq 0x2180
movq -0xe8(%rbp), %rdi
testq %rdi, %rdi
je 0x2aef
callq 0x2180
movq %r12, -0xe8(%rbp)
movl %r12d, -0xe0(%rbp)
movq %r12, -0xd8(%rbp)
movl %r12d, -0xd0(%rbp)
movq %r12, -0xc8(%rbp)
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x2b1a
callq 0x2180
movq %r12, -0x90(%rbp)
movl %r12d, -0x88(%rbp)
movq %r12, -0x80(%rbp)
movl %r12d, -0x78(%rbp)
movq %r12, -0x70(%rbp)
movq -0x60(%rbp), %rdi
testq %rdi, %rdi
je 0x2b3c
callq 0x2180
movq %r12, -0x60(%rbp)
movl %r12d, -0x58(%rbp)
movq %r12, -0x50(%rbp)
movl %r12d, -0x48(%rbp)
movq %r12, -0x40(%rbp)
testb %bl, %bl
jne 0x27fd
jmp 0x2df0
movl $0x1, %r14d
jmp 0x2e00
leaq 0x35ee(%rip), %rdi      # 0x6149
callq 0x2230
xorl %r13d, %r13d
movq 0x6476(%rip), %r15      # 0x8fe0
leaq -0xc0(%rbp), %r14
leaq -0x1a0(%rbp), %rbx
movl $0x0, -0x34(%rbp)
leaq 0x34a1(%rip), %rdi      # 0x6027
xorl %eax, %eax
callq 0x2050
movq %r15, %rdi
leaq -0x2c(%rbp), %rsi
callq 0x2100
movq %r15, %rdi
leaq -0x30(%rbp), %rsi
callq 0x2100
movl -0x2c(%rbp), %r12d
movl -0x30(%rbp), %r15d
movl 0x65d9(%rip), %esi      # 0x918c
movq %r14, %rdi
movl %r12d, %edx
callq 0x4a77
xorl %r12d, %r15d
movl 0x65c5(%rip), %esi      # 0x918c
leaq -0x60(%rbp), %rdi
movl %r15d, %edx
callq 0x4a77
xorpd %xmm0, %xmm0
movapd %xmm0, -0x90(%rbp)
movq $0x0, -0x80(%rbp)
movq -0x88(%rbp), %rsi
testq %rsi, %rsi
je 0x2c05
movl -0x2c(%rbp), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, -0x88(%rbp)
jmp 0x2c15
leaq -0x90(%rbp), %rdi
leaq -0x2c(%rbp), %rdx
callq 0x3dbe
movq -0x60(%rbp), %rax
movq -0x50(%rbp), %rcx
movl -0x48(%rbp), %edx
subq %rax, %rcx
shlq $0x3, %rcx
addq %rdx, %rcx
je 0x2d22
xorl %r15d, %r15d
movl $0x1, %edx
movl %r15d, %ecx
shlq %cl, %rdx
movq %r15, %rcx
shrq $0x6, %rcx
movq (%rax,%rcx,8), %rax
btq %r15, %rax
jae 0x2d04
movq -0xc0(%rbp), %rax
movq (%rax,%rcx,8), %rsi
movq %rdx, %rdi
notq %rdi
andq %rsi, %rdi
movq %rsi, %r8
orq %rdx, %r8
testq %rdx, %rsi
cmovneq %rdi, %r8
movq %r8, (%rax,%rcx,8)
movl 0x650d(%rip), %r12d     # 0x918c
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3966
movl %r12d, %edi
movq %rbx, %rsi
callq 0x49e8
movl %eax, -0xe8(%rbp)
movq -0x1a0(%rbp), %rdi
testq %rdi, %rdi
je 0x2ccf
callq 0x2180
movq %r13, -0x1a0(%rbp)
movl %r13d, -0x198(%rbp)
movq %r13, -0x190(%rbp)
movl %r13d, -0x188(%rbp)
movq %r13, -0x180(%rbp)
movq -0x88(%rbp), %rsi
cmpq -0x80(%rbp), %rsi
je 0x2cf1
movl -0xe8(%rbp), %eax
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, -0x88(%rbp)
jmp 0x2d04
leaq -0x90(%rbp), %rdi
leaq -0xe8(%rbp), %rdx
callq 0x3dbe
incq %r15
movq -0x60(%rbp), %rax
movq -0x50(%rbp), %rcx
movl -0x48(%rbp), %edx
subq %rax, %rcx
leaq (%rdx,%rcx,8), %rcx
cmpq %r15, %rcx
ja 0x2c33
movl -0x2c(%rbp), %esi
movl -0x30(%rbp), %edx
leaq 0x3309(%rip), %rdi      # 0x6038
xorl %eax, %eax
callq 0x2050
movl 0x6450(%rip), %edi      # 0x918c
leaq -0x90(%rbp), %rsi
callq 0x32d9
movl -0x2c(%rbp), %esi
movl 0x6437(%rip), %ecx      # 0x9188
cmpl %ecx, %esi
setl %al
movl -0x30(%rbp), %edx
cmpl %ecx, %edx
setl %r15b
andb %al, %r15b
jne 0x2d79
leaq 0x32e2(%rip), %rdi      # 0x604d
xorl %eax, %eax
callq 0x2050
movl $0x1, -0x34(%rbp)
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x2d8a
callq 0x2180
movq -0x60(%rbp), %rdi
testq %rdi, %rdi
je 0x2dac
callq 0x2180
movq %r13, -0x60(%rbp)
movl %r13d, -0x58(%rbp)
movq %r13, -0x50(%rbp)
movl %r13d, -0x48(%rbp)
movq %r13, -0x40(%rbp)
movq -0xc0(%rbp), %rdi
testq %rdi, %rdi
je 0x2de0
callq 0x2180
movq %r13, -0xc0(%rbp)
movl %r13d, -0xb8(%rbp)
movq %r13, -0xb0(%rbp)
movl %r13d, -0xa8(%rbp)
movq %r13, -0xa0(%rbp)
testb %r15b, %r15b
movq 0x61f6(%rip), %r15      # 0x8fe0
jne 0x2b7f
leaq -0x1f0(%rbp), %rdi
callq 0x3c68
movl -0x34(%rbp), %r14d
leaq -0x1b0(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x2e15
callq 0x2180
movl %r14d, %eax
addq $0x1e8, %rsp            # imm = 0x1E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x32b5(%rip), %rdi      # 0x60e6
callq 0x20f0
leaq 0x32a9(%rip), %rdi      # 0x60e6
callq 0x2200
jmp 0x2ff8
jmp 0x2ff8
movq %rax, %rbx
movq -0x210(%rbp), %rdi
cmpq %r14, %rdi
je 0x3093
callq 0x2180
jmp 0x3093
movq %rax, %rbx
jmp 0x3093
jmp 0x2e73
movq %rax, %rbx
jmp 0x30a8
movq %rax, %rbx
cmpl $0x0, (%r14)
jne 0x2e87
movl %r13d, (%r14)
leaq -0x1e0(%rbp), %rax
jmp 0x309a
jmp 0x2ff8
movq %rax, %rbx
jmp 0x2fc9
movq %rax, %rbx
jmp 0x2f9e
movq %rax, %rbx
jmp 0x2f01
movq %rax, %rbx
jmp 0x2ecd
movq %rax, %rbx
movq -0x178(%rbp), %rsi
testq %rsi, %rsi
je 0x2ecd
leaq -0x178(%rbp), %rdi
callq 0x22d0
movq -0x128(%rbp), %rdi
testq %rdi, %rdi
je 0x2f01
callq 0x2180
xorl %eax, %eax
movq %rax, -0x128(%rbp)
movl %eax, -0x120(%rbp)
movq %rax, -0x118(%rbp)
movl %eax, -0x110(%rbp)
movq %rax, -0x108(%rbp)
movq -0x150(%rbp), %rdi
testq %rdi, %rdi
je 0x2f4d
callq 0x2180
xorl %eax, %eax
movq %rax, -0x150(%rbp)
movl %eax, -0x148(%rbp)
movq %rax, -0x140(%rbp)
movl %eax, -0x138(%rbp)
movq %rax, -0x130(%rbp)
jmp 0x2f4d
jmp 0x2f4a
jmp 0x2f4a
jmp 0x2ff8
movq %rax, %rbx
jmp 0x3053
jmp 0x2f4a
movq %rax, %rbx
leaq -0xc0(%rbp), %rdi
callq 0x3c68
movq -0x100(%rbp), %rdi
testq %rdi, %rdi
je 0x2f6a
callq 0x2180
movq -0xe8(%rbp), %rdi
testq %rdi, %rdi
je 0x2f9e
callq 0x2180
xorl %eax, %eax
movq %rax, -0xe8(%rbp)
movl %eax, -0xe0(%rbp)
movq %rax, -0xd8(%rbp)
movl %eax, -0xd0(%rbp)
movq %rax, -0xc8(%rbp)
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x2fc9
callq 0x2180
xorl %eax, %eax
movq %rax, -0x90(%rbp)
movl %eax, -0x88(%rbp)
movq %rax, -0x80(%rbp)
movl %eax, -0x78(%rbp)
movq %rax, -0x70(%rbp)
movq -0x60(%rbp), %rdi
testq %rdi, %rdi
je 0x3087
callq 0x2180
xorl %eax, %eax
movq %rax, -0x60(%rbp)
movl %eax, -0x58(%rbp)
movq %rax, -0x50(%rbp)
movl %eax, -0x48(%rbp)
movq %rax, -0x40(%rbp)
jmp 0x3087
jmp 0x2ff8
jmp 0x301d
movq %rax, %rbx
jmp 0x3087
movq %rax, %rbx
movq -0x1a0(%rbp), %rsi
testq %rsi, %rsi
je 0x3020
leaq -0x1a0(%rbp), %rdi
callq 0x22fe
jmp 0x3020
movq %rax, %rbx
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x3031
callq 0x2180
movq -0x60(%rbp), %rdi
testq %rdi, %rdi
je 0x3053
callq 0x2180
xorl %eax, %eax
movq %rax, -0x60(%rbp)
movl %eax, -0x58(%rbp)
movq %rax, -0x50(%rbp)
movl %eax, -0x48(%rbp)
movq %rax, -0x40(%rbp)
movq -0xc0(%rbp), %rdi
testq %rdi, %rdi
je 0x3087
callq 0x2180
xorl %eax, %eax
movq %rax, -0xc0(%rbp)
movl %eax, -0xb8(%rbp)
movq %rax, -0xb0(%rbp)
movl %eax, -0xa8(%rbp)
movq %rax, -0xa0(%rbp)
leaq -0x1f0(%rbp), %rdi
callq 0x3c68
leaq -0x1b0(%rbp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x30a8
callq 0x2180
movq %rbx, %rdi
callq 0x2280