// File: /workspace/github_cpp_makefile_star2_O2/NeoResearch[P]dbft3-spork-detect/main.cpp
// Function: selections(std::vector<int, std::allocator<int>>, int)
vector<vector<pair<int, int>>> selections(vector<int> choices, int f)
{
    int N = 3 * f + 1;
    vector<vector<pair<int, int>>> sel(N, vector<pair<int, int>>(2 * f, make_pair(-2, -2)));
    // for each i in N, select possible 2f responses, in order
    for (int i = 0; i < N; i++)
    {
        if (choices[i] == -2) // faulty node
            continue;
        vector<int> choicesi = make2f(choices, f, i); // 2f responses for replica i
        for (unsigned j = 0; j < choicesi.size(); j++)
            sel[i][j] = make_pair(choicesi[j], choices[choicesi[j]]);
        // may have bug here
        // R_3 | 1(1) |    1(3)    0(0)    | Cancel 1
        // we must prefer response over request, if double response being made
        // I think this only applies to non-prepare nodes
        if (i > 0) // only backups (or primary 1) ... not primary zero
        {
            int prepZero = -1;
            int respZero = -1;
            int prepOne = -1;
            int respOne = -1;
            for (unsigned k = 0; k < sel[i].size(); k++)
            {
                if ((sel[i][k].second == 0) && (sel[i][k].first == 0)) // prepareZero
                    prepZero = k;
                if ((sel[i][k].second == 1) && (sel[i][k].first == 1)) // prepareOne
                    prepOne = k;
                if ((sel[i][k].second == 0) && (sel[i][k].first == i)) // respZero
                    respZero = k;
                if ((sel[i][k].second == 1) && (sel[i][k].first == i)) // respOne
                    respOne = k;
            }
            cout << "*** i=" << i << " | choice=" << choices[i] << " | ";
            for (unsigned k = 0; k < sel[i].size(); k++)
                cout << sel[i][k].second << "(" << sel[i][k].first << ") ";
            cout << endl;

            // disabling multiple response
            /*
            if (choices[i] == 0) // assert that my prepare and response is going out
            {
                //assert(prepZero>-1); // this is my choice, not in this vector (TODO: improve)
                assert(respZero > -1);
                // if re-proposing, must prioritize reply
                if ((prepOne > -1) && (respOne == -1))
                {
                    // propose but no reply, let's change
                    //sel[i][prepOne].first = i; // now I'm responding, not sending proposal only
                    sel[i].push_back(make_pair(i, 1)); // My response
                    //assert(respOne > -1); // THIS must be valid
                }
            }
            if (choices[i] == 1) // assert that my prepare and response is going out
            {
                //assert(prepOne>-1); // this is my choice, not in this vector (TODO: improve)
                if(i != 1) // 'one' does not respond to itself
                    assert(respOne > -1);
                // if re-proposing, must prioritize reply
                if ((prepZero > -1) && (respZero == -1))
                {
                    // propose but no reply, let's change
                    //sel[i][prepZero].first = i; // now I'm responding, not sending proposal only
                    sel[i].push_back(make_pair(i, 0)); // My response
                    //assert(respZero > -1); // THIS must be valid
                }
            }
            */
            // DISABLED: this generates forks

        } // backups
    }

    return sel;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %edx, %r12d
movq %rsi, %r15
movq %rdi, %rbx
leal (%r12,%r12), %eax
movslq %eax, %rsi
movabsq $-0x100000002, %rax     # imm = 0xFFFFFFFEFFFFFFFE
leaq -0x78(%rbp), %rdx
movq %rax, (%rdx)
leaq -0x48(%rbp), %rdi
leaq -0x2a(%rbp), %rcx
callq 0x2fea
leal (%r12,%r12,2), %r14d
leal 0x1(%r14), %eax
movslq %eax, %rsi
leaq -0x48(%rbp), %rdx
leaq -0x29(%rbp), %rcx
movq %rbx, %rdi
callq 0x304a
leaq -0x48(%rbp), %rdi
callq 0x3598
movslq %r14d, %rax
movq %rax, -0x58(%rbp)
xorl %r13d, %r13d
leaq -0x70(%rbp), %r14
movq %r12, -0x50(%rbp)
cmpq -0x58(%rbp), %r13
jg 0x17f5
movq (%r15), %rax
cmpl $-0x2, (%rax,%r13,4)
je 0x17ed
movq %r14, %rdi
movq %r15, %rsi
callq 0x30aa
leaq -0x48(%rbp), %rdi
movq %r14, %rsi
movl %r12d, %edx
movl %r13d, %ecx
callq 0x1542
movq %r14, %rdi
callq 0x322c
movq -0x48(%rbp), %rax
movq -0x40(%rbp), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
imulq $0x18, %r13, %r14
movq (%rbx), %rdx
addq %r14, %rdx
xorl %esi, %esi
movl %esi, %esi
cmpq %rsi, %rcx
jbe 0x1717
movslq (%rax,%rsi,4), %rdi
movq (%r15), %r8
movl (%r8,%rdi,4), %r8d
movq (%rdx), %r9
movl %edi, (%r9,%rsi,8)
movl %r8d, 0x4(%r9,%rsi,8)
incl %esi
jmp 0x16f5
testq %r13, %r13
je 0x17e0
movq 0x58b1(%rip), %rdi      # 0x6fd8
leaq 0x2945(%rip), %rsi      # 0x4073
callq 0x1100
movq %rax, %rdi
movl %r13d, %esi
callq 0x11d0
movq %rax, %rdi
leaq 0x2932(%rip), %rsi      # 0x407a
callq 0x1100
movq (%r15), %rcx
movl (%rcx,%r13,4), %esi
movq %rax, %rdi
callq 0x11d0
movq %rax, %rdi
leaq 0x291f(%rip), %rsi      # 0x4085
callq 0x1100
xorl %r12d, %r12d
movl %r12d, %r12d
movq (%rbx), %rcx
movq (%rcx,%r14), %rax
movq 0x8(%rcx,%r14), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %r12, %rcx
jbe 0x17d0
movl 0x4(%rax,%r12,8), %esi
movq 0x5843(%rip), %rdi      # 0x6fd8
callq 0x11d0
movq %rax, %rdi
leaq 0x288d(%rip), %rsi      # 0x4031
callq 0x1100
movq (%rbx), %rcx
movq (%rcx,%r14), %rcx
movl (%rcx,%r12,8), %esi
movq %rax, %rdi
callq 0x11d0
movq %rax, %rdi
leaq 0x2aef(%rip), %rsi      # 0x42b5
callq 0x1100
incl %r12d
jmp 0x176e
movq 0x5801(%rip), %rdi      # 0x6fd8
callq 0x1090
movq -0x50(%rbp), %r12
leaq -0x48(%rbp), %rdi
callq 0x322c
leaq -0x70(%rbp), %r14
incq %r13
jmp 0x169d
movq %rbx, %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %r14
leaq -0x48(%rbp), %rdi
callq 0x3598
jmp 0x183e
movq %rax, %r14
jmp 0x183e
movq %rax, %r14
leaq -0x70(%rbp), %rdi
jmp 0x1831
movq %rax, %r14
jmp 0x1836
jmp 0x182a
movq %rax, %r14
leaq -0x48(%rbp), %rdi
callq 0x322c
movq %rbx, %rdi
callq 0x3102
movq %r14, %rdi
callq 0x11e0