// File: /workspace/github_cpp_makefile_star2_O3/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 $0x58, %rsp
movl %r8d, -0x30(%rbp)
movq %rcx, -0x48(%rbp)
movq %rsi, -0x38(%rbp)
movq %rdi, -0x40(%rbp)
leaq -0x78(%rbp), %rax
movl $0x0, (%rax)
xorl %ebx, %ebx
movq %rbx, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
movq %rbx, 0x20(%rax)
movl %r9d, -0x2c(%rbp)
testl %r9d, %r9d
je 0x3036
movq %rdx, %r12
leaq -0x80(%rbp), %r14
movl %ebx, %eax
movq -0x48(%rbp), %rcx
movslq (%rcx,%rax,4), %r15
movq -0x40(%rbp), %rax
movq (%rax), %rax
cmpl $-0x2, (%rax,%r15,4)
je 0x3153
movq -0x38(%rbp), %rax
movq (%rax), %rax
movl (%rax,%r15,4), %eax
movq %rax, %rcx
shlq $0x20, %rcx
orq %rax, %rcx
movq %rcx, -0x50(%rbp)
movq %r14, %rdi
leaq -0x50(%rbp), %rsi
callq 0x5440
movq (%r12), %rcx
leaq (%r15,%r15,2), %r15
movq (%rcx,%r15,8), %rax
cmpq %rax, 0x8(%rcx,%r15,8)
je 0x302b
movl $0x1, %r13d
xorl %ecx, %ecx
leaq (%rax,%rcx,8), %rsi
movq %r14, %rdi
callq 0x5592
movl %r13d, %ecx
movq (%r12), %rdx
movq (%rdx,%r15,8), %rax
movq 0x8(%rdx,%r15,8), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
incl %r13d
cmpq %rcx, %rdx
ja 0x3000
incl %ebx
cmpl -0x2c(%rbp), %ebx
jne 0x2fa4
movq 0x5f9b(%rip), %rdi      # 0x8fd8
leaq 0x305a(%rip), %rsi      # 0x609e
movl $0xd, %edx
callq 0x2170
movq 0x5f83(%rip), %rdi      # 0x8fd8
movl -0x30(%rbp), %esi
callq 0x2210
movq %rax, %rbx
leaq 0x3045(%rip), %rsi      # 0x60ac
movl $0x8, %edx
movq %rax, %rdi
callq 0x2170
movq %rbx, %rdi
movl -0x2c(%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 -0x68(%rbp), %r13
leaq -0x78(%rbp), %rax
cmpq %rax, %r13
je 0x3167
movl $0x0, -0x2c(%rbp)
xorl %r15d, %r15d
movl 0x20(%r13), %r12d
movl 0x24(%r13), %ebx
movq 0x5f05(%rip), %rdi      # 0x8fd8
movl %ebx, %esi
callq 0x2210
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
leaq 0x2f45(%rip), %rsi      # 0x6031
callq 0x2170
movq %r14, %rdi
movl %r12d, %esi
callq 0x2210
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
leaq 0x3233(%rip), %rsi      # 0x6341
callq 0x2170
movl $0x1, %edx
movq %r12, %rdi
leaq 0x2f70(%rip), %rsi      # 0x6092
callq 0x2170
cmpl $0x1, %ebx
adcl $0x0, %r15d
xorl %eax, %eax
cmpl $0x1, %ebx
sete %al
addl %eax, -0x2c(%rbp)
movq %r13, %rdi
callq 0x2180
movq %rax, %r13
leaq -0x78(%rbp), %rax
cmpq %rax, %r13
jne 0x30c4
jmp 0x3171
movabsq $0x10000000000, %rax    # imm = 0x10000000000
movl $0xfffffffc, %ebx       # imm = 0xFFFFFFFC
jmp 0x328b
xorl %r15d, %r15d
movl $0x0, -0x2c(%rbp)
movq 0x5e60(%rip), %rdi      # 0x8fd8
movq (%rdi), %rax
addq -0x18(%rax), %rdi
movl $0xa, %esi
callq 0x2120
movl %r15d, %r14d
movl -0x2c(%rbp), %r15d
movsbl %al, %esi
movq 0x5e3e(%rip), %rdi      # 0x8fd8
callq 0x2030
movq %rax, %rdi
callq 0x20e0
movq 0x5e2a(%rip), %rdi      # 0x8fd8
leaq 0x2f00(%rip), %rsi      # 0x60b5
movl $0xd, %edx
callq 0x2170
movq 0x5e12(%rip), %rdi      # 0x8fd8
movl %r14d, %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 0x5dd9(%rip), %rdi      # 0x8fd8
leaq 0x2ebd(%rip), %rsi      # 0x60c3
movl $0xc, %edx
callq 0x2170
movq 0x5dc1(%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
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, %r15d
jle 0x3275
movl $0x1, %ebx
xorl %eax, %eax
jmp 0x328b
movl $0xfffffffc, %ebx       # imm = 0xFFFFFFFC
leaq 0x4(%rbx), %rax
xorl %edx, %edx
cmpl %ecx, %r14d
cmovgq %rdx, %rbx
cmovgq %rdx, %rax
orq %rax, %rbx
leaq -0x80(%rbp), %rdi
callq 0x505a
movq %rbx, %rax
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x32b6
jmp 0x32b6
jmp 0x32b6
jmp 0x32b6
movq %rax, %rbx
leaq -0x80(%rbp), %rdi
callq 0x505a
movq %rbx, %rdi
callq 0x2220