// File: /workspace/github_cpp_makefile_star2_O1/NeoResearch[P]dbft3-spork-detect/main.cpp
// Function: verifyCommitSubset(std::vector<int, std::allocator<int>>, std::vector<int, std::allocator<int>>, std::vector<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int>>>, std::allocator<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int>>>>>, int*, int, int)
CommitStatus verifyCommitSubset(vector<int> cancels, vector<int> choices, vector<vector<pair<int, int>>> selections, int t[], int p, int k)
{
    int N = p;
    int f = (N - 1) / 3;
    //vector<pair<int, int>> pack; // pack all information
    std::set<pair<int, int>> pack;
    int count_cancel_zero = 0;
    int count_cancel_one = 0;
    //bool includes_primaryZero = false;
    for (unsigned c = 0; c < k; c++)
    {
        int e = t[c]; // get element from subset
        if (cancels[e] == -2)
            return CommitStatus{-4, false, true}; // dead node
        if (cancels[e] == 0)
            count_cancel_zero++;
        if (cancels[e] == 1)
            count_cancel_one++;
        /*
        if(e == 0)
        {
            includes_primaryZero = true;
            return 0; // very strong primary 0
        }
        */
        pack.insert(make_pair(choices[e], choices[e])); // first proposal (responded to)
        for (unsigned j = 0; j < selections[e].size(); j++)
            pack.insert(selections[e][j]); // responses (and possible more proposals)
    }

    cout << "PACK for p=N=" << p << " 2f+1=k=" << k << endl;
    /*
    sort(pack.begin(), pack.end(), [](const pair<int,int> & a, const pair<int,int> & b) -> bool
    { 
        return (a.first < b.first) && (a.second < b.second); 
    });
    unique(pack.begin(), pack.end());
    */
    //sort(pack.begin(), pack.end());
    //pack.erase(unique(pack.begin(), pack.end()));
    // remove repeated
    //for(unsigned i=0; i<int(pack.size())-1; i++)
    //    for(unsigned j=i+1; j<pack.size(); j++)

    //for(int j=0; j<pack.size(); j++)
    //    cout << pack[j].second << "(" << pack[j].first << ")" << "\t";
    int count_zero = 0;
    int count_one = 0;
    for (auto dp : pack)
    {
        cout << dp.second << "(" << dp.first << ")"
             << "\t";
        if (dp.second == 0)
            count_zero++;
        if (dp.second == 1)
            count_one++;
    }
    cout << endl;
    cout << "count_zero = " << count_zero << endl;
    cout << "count_one = " << count_one << endl;
    //if(count_zero >= 2) // f+1
    //    return 0;
    //if(count_zero >= k) // >=2f+1
    if (count_one >= 2 * f + 1) // >=2f+1 // this is correct one
                                //if (count_one >= f+1) // >=f+1 // NOT GOOD!! JUST TESTING (INTENDS TO FAIL AND CREATE FORKS!!)
        return 1;
    if (count_zero >= f + 1) // >=f+1  // this is correct one
        return 0;

    // THINK, WHAT ELSE?
    //return 0; // default zero (seems to cause problem, when all is 1, an intersection doesnt give 2f+1 ones...)
    // probably, voting.

    // VERY DUBIOUS CASE HERE... 0(0)    1(1)    1(3)
    /*
R_0 | 0(0) |    1(1)    1(3)    | Cancel 0
R_1 | 1(1) |    0(0)    1(3)    | Cancel 1
R_2 | 0(0) |    0(2)    1(1)    | Cancel 0
R_3 | 1(1) |    1(3)    0(0)    | Cancel 1
    */
    // but it should be zero.

    // try to vote by cancels.... desperate measure
    //if(count_cancel_zero > 0)
    //    return 0;
    //else
    //    return 1;
    // didn't work out...
    // all ones and only first is zero. No one answered it. So, it must go one.
    //if((count_one == 2) && (count_zero==1))
    //    return 1;
    // default
    //return 0;

    // cannot decide (THIS IS THE SOLUTION!!!)
    // sometimes, one should simply wait for more information...
    // ... and if really not possible, then Change View (rare cases, only 12.5% with permanent fault)
    return CommitStatus{-4, true};

    /*
    // didn't work out... dubious case:  0(0)    1(1)    1(3)
    if(count_one > count_zero)
        return 1;
    else
        return 0; // equality, still zero
        */
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movl %r8d, -0x30(%rbp)
movq %rcx, -0x50(%rbp)
movq %rsi, -0x40(%rbp)
movq %rdi, -0x48(%rbp)
leaq -0x80(%rbp), %rax
movl $0x0, (%rax)
xorl %r13d, %r13d
movq %r13, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
movq %r13, 0x20(%rax)
movl %r9d, -0x34(%rbp)
testl %r9d, %r9d
je 0x300c
movq %rdx, %r12
leaq -0x88(%rbp), %r14
movl %r13d, %eax
movq -0x50(%rbp), %rcx
movslq (%rcx,%rax,4), %rbx
movq -0x48(%rbp), %rax
movq (%rax), %rax
movl (%rax,%rbx,4), %eax
cmpl $-0x2, %eax
je 0x3130
movl %eax, -0x2c(%rbp)
movq -0x40(%rbp), %rax
movq (%rax), %rax
movl (%rax,%rbx,4), %eax
movq %rax, %rcx
shlq $0x20, %rcx
orq %rax, %rcx
movq %rcx, -0x58(%rbp)
movq %r14, %rdi
leaq -0x58(%rbp), %rsi
callq 0x5406
movq (%r12), %rcx
leaq (%rbx,%rbx,2), %rbx
movq (%rcx,%rbx,8), %rax
cmpq %rax, 0x8(%rcx,%rbx,8)
je 0x2ff5
movl $0x1, %r15d
xorl %ecx, %ecx
leaq (%rax,%rcx,8), %rsi
movq %r14, %rdi
callq 0x5576
movl %r15d, %ecx
movq (%r12), %rdx
movq (%rdx,%rbx,8), %rax
movq 0x8(%rdx,%rbx,8), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
incl %r15d
cmpq %rcx, %rdx
ja 0x2fca
cmpl $-0x2, -0x2c(%rbp)
je 0x3130
incl %r13d
cmpl -0x34(%rbp), %r13d
jne 0x2f6a
movq 0x5fc5(%rip), %rdi      # 0x8fd8
leaq 0x3084(%rip), %rsi      # 0x609e
movl $0xd, %edx
callq 0x2170
movq 0x5fad(%rip), %rdi      # 0x8fd8
movl -0x30(%rbp), %esi
callq 0x2210
movq %rax, %rbx
leaq 0x306f(%rip), %rsi      # 0x60ac
movl $0x8, %edx
movq %rax, %rdi
callq 0x2170
movq %rbx, %rdi
movl -0x34(%rbp), %esi
callq 0x2210
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2120
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x20e0
movq -0x70(%rbp), %rbx
leaq -0x80(%rbp), %rax
cmpq %rax, %rbx
je 0x3144
xorl %r12d, %r12d
xorl %r15d, %r15d
movl %r12d, -0x2c(%rbp)
movl 0x20(%rbx), %r12d
movl 0x24(%rbx), %r13d
movq 0x5f2f(%rip), %rdi      # 0x8fd8
movl %r13d, %esi
callq 0x2210
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x2f6e(%rip), %rsi      # 0x6031
callq 0x2170
movq %r14, %rdi
movl %r12d, %esi
callq 0x2210
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
leaq 0x325c(%rip), %rsi      # 0x6341
callq 0x2170
movl $0x1, %edx
movq %r12, %rdi
leaq 0x2f99(%rip), %rsi      # 0x6092
callq 0x2170
cmpl $0x1, %r13d
adcl $0x0, %r15d
xorl %eax, %eax
cmpl $0x1, %r13d
sete %al
movl -0x2c(%rbp), %r12d
addl %eax, %r12d
movq %rbx, %rdi
callq 0x2180
movq %rax, %rbx
leaq -0x80(%rbp), %rax
cmpq %rax, %rbx
jne 0x3096
jmp 0x314a
movabsq $0x10000000000, %rax    # imm = 0x10000000000
movl $0xfffffffc, %ebx       # imm = 0xFFFFFFFC
jmp 0x325d
xorl %r15d, %r15d
xorl %r12d, %r12d
movq 0x5e87(%rip), %rdi      # 0x8fd8
movq (%rdi), %rax
addq -0x18(%rax), %rdi
movl $0xa, %esi
callq 0x2120
movsbl %al, %esi
movq 0x5e6c(%rip), %rdi      # 0x8fd8
callq 0x2030
movq %rax, %rdi
callq 0x20e0
movq 0x5e58(%rip), %rdi      # 0x8fd8
leaq 0x2f2e(%rip), %rsi      # 0x60b5
movl $0xd, %edx
callq 0x2170
movq 0x5e40(%rip), %rdi      # 0x8fd8
movl %r15d, %esi
callq 0x2210
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2120
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x20e0
movq 0x5e07(%rip), %rdi      # 0x8fd8
leaq 0x2eeb(%rip), %rsi      # 0x60c3
movl $0xc, %edx
callq 0x2170
movq 0x5def(%rip), %rdi      # 0x8fd8
movl %r12d, %esi
callq 0x2210
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2120
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x20e0
movl -0x30(%rbp), %eax
decl %eax
cltq
imulq $0x55555556, %rax, %rcx # imm = 0x55555556
movq %rcx, %rax
shrq $0x3f, %rax
shrq $0x20, %rcx
addl %eax, %ecx
leal (%rcx,%rcx), %eax
cmpl %eax, %r12d
jle 0x3247
movl $0x1, %ebx
xorl %eax, %eax
jmp 0x325d
movl $0xfffffffc, %ebx       # imm = 0xFFFFFFFC
leaq 0x4(%rbx), %rax
xorl %edx, %edx
cmpl %ecx, %r15d
cmovgq %rdx, %rbx
cmovgq %rdx, %rax
orq %rax, %rbx
leaq -0x88(%rbp), %rdi
callq 0x5020
movq %rbx, %rax
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x328b
jmp 0x328b
jmp 0x328b
jmp 0x328b
movq %rax, %rbx
leaq -0x88(%rbp), %rdi
callq 0x5020
movq %rbx, %rdi
callq 0x2220