// File: /workspace/github_cpp_makefile_star2_O2/zyLiu6707[P]Arknights-Pull-Simulation/./utils.h
// Function: display_simulation_results(std::vector<unsigned long long, std::allocator<unsigned long long>> const&, std::unordered_map<unsigned long long, unsigned long long, std::hash<unsigned long long>, std::equal_to<unsigned long long>, std::allocator<std::pair<unsigned long long const, unsigned long long>>>&, unsigned long long, unsigned long long, unsigned int, timespec const&, timespec const&)
void display_simulation_results(
    const std::vector<unsigned long long int>& result,
    std::unordered_map<unsigned long long int, unsigned long long int>&
        rare_event,
    unsigned long long int star6_count,
    unsigned long long int target_star6_count, unsigned int seed,
    const struct timespec& start, const struct timespec& end) {
  std::cout << "...finished\n" << std::endl;

  // Simulation summary
  std::cout << "SIMULATION SUMMARY" << std::endl;
  std::cout << "-------------------------" << std::endl;
  std::cout << "Time spent: " << calc_time(start, end) << "s" << std::endl;
  std::cout << "Random seed for this simulation: " << seed << std::endl;
  std::cout << "Star 6 times: " << star6_count << std::endl;
  std::cout << "Target star 6 times: " << target_star6_count << std::endl;

  std::cout << std::endl;

  // Displaying raw data
  std::cout << "RAW DATA" << std::endl;
  std::cout << "-------------------------" << std::endl;
  std::cout << "First " << raw_data_showing_limit << " raw data:" << std::endl;
  std::cout << "\t";
  for (unsigned int i = 0; i < 10; ++i) {
    std::cout << i + 1 << ":\t";
  }
  std::cout << std::endl;
  for (size_t i = 0; i < raw_data_showing_limit; ++i) {
    if (i % 10 == 0) {
      std::cout << i / 10 + 1 << ":\t";
    }
    std::cout << result[i] << '\t';
    if (i % 10 == 9) {
      std::cout << std::endl;
    }
  }
  // If raw_data_showing_limit is not a multiple of 10, print an extra new line
  std::cout << std::endl;
  if (raw_data_showing_limit % 10 != 0) {
    std::cout << std::endl;
  }

  std::cout << std::endl;

  // Displaying rare events
  std::cout << "RARE EVENTS" << std::endl;
  std::cout << "-------------------------" << std::endl;
  std::cout << "Rare events happend " << rare_event.size() << " times in total"
            << std::endl;
  if (rare_event.size() != 0 && rare_event_showing_limit > 0) {
    std::cout << "Some rare events are (only showing "
              << rare_event_showing_limit << " of them here):" << std::endl;

    size_t counter = 0;
    for (const auto& p : rare_event) {
      if (counter < rare_event_showing_limit) {
        std::cout
            << "\tEvent \"Pulling " << p.first
            << " times to get the target star6 at the last pull\" happend "
            << p.second << " times" << std::endl;
        counter++;
      }
    }
    std::cout << std::endl;
    std::cout << "Note: Since the rare events are very sensitive to the error of the actual distribution\n"
                 "      of generated random numbers (i.e., we want a perfect uniform distribution, but\n"
                 "      there would be error under limited times of random number generating), the\n"
                 "      estimated probabilities for these rare events will not be accurate.\n"
                 "      Hence will not show the estimated probabilities of those rare events."
              << std::endl;
  }

  std::cout << std::endl;

  // Displaying the estimated probability
  // that you succeed *on* N-th pull
  std::cout << "ESTIMATED PROBABILITY" << std::endl;
  std::cout << "-------------------------" << std::endl;
  for (unsigned int i = 1;
       i < std::min(estimated_prob_showing_limit, result.size());
       ++i) {  // skip the unused index 0

    std::cout << "Pr(S_" << i
              << ") = " << (100.0 * result[i]) / target_star6_count << " %"
              << std::endl;
  }

  std::cout << std::endl;

  // Displaying the cumulated probability
  // Here "cumulated" means that you succeed *within* N pulls
  double cumulated_probability = 0.0;
  std::cout << "CUMULATED PROBABILITY" << std::endl;
  std::cout << "-------------------------" << std::endl;
  for (unsigned int i = 1;
       i < std::min(estimated_prob_showing_limit, result.size()); ++i) {
    cumulated_probability += result[i];
    std::cout << "Pr(W_" << i
              << ") = " << (100.0 * cumulated_probability) / target_star6_count
              << " %" << std::endl;
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r9, %r13
movl %r8d, 0x10(%rsp)
movq %rcx, %r14
movq %rdx, 0x8(%rsp)
movq %rsi, %r15
movq %rdi, %rbx
movq 0x72e1(%rip), %r12      # 0xafd0
leaq 0x358d(%rip), %rsi      # 0x7283
movq %r12, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
leaq 0x3583(%rip), %rsi      # 0x7290
movq %r12, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
leaq 0x357f(%rip), %rsi      # 0x72a3
movq %r12, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
leaq 0x3582(%rip), %rsi      # 0x72bd
movq %r12, %rdi
callq 0x21a0
movq %rax, %rbp
movq %r13, %rdi
movq 0x60(%rsp), %rsi
callq 0x23dc
movq %rbp, %rdi
callq 0x2260
leaq 0x3682(%rip), %rsi      # 0x73e4
movq %rax, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
leaq 0x3551(%rip), %rsi      # 0x72ca
movq %r12, %rdi
callq 0x21a0
movl 0x10(%rsp), %esi
movq %rax, %rdi
callq 0x2110
movq %rax, %rdi
callq 0x20c0
leaq 0x3550(%rip), %rsi      # 0x72ec
movq %r12, %rdi
callq 0x21a0
movq %rax, %rdi
movq 0x8(%rsp), %rsi
callq 0x2100
movq %rax, %rdi
callq 0x20c0
leaq 0x353b(%rip), %rsi      # 0x72fb
movq %r12, %rdi
callq 0x21a0
movq %rax, %rdi
movq %r14, 0x8(%rsp)
movq %r14, %rsi
callq 0x2100
movq %rax, %rdi
callq 0x20c0
movq %r12, %rdi
callq 0x20c0
leaq 0x3522(%rip), %rsi      # 0x7311
movq %r12, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
movq %r12, %rdi
leaq 0x349a(%rip), %rsi      # 0x72a3
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
leaq 0x34fd(%rip), %rsi      # 0x731a
movq %r12, %rdi
callq 0x21a0
pushq $0x64
popq %rsi
movq %rax, %rdi
callq 0x2110
leaq 0x34ea(%rip), %rsi      # 0x7321
movq %rax, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
leaq 0x34df(%rip), %rsi      # 0x732d
movq %r12, %rdi
callq 0x21a0
pushq $0x1
popq %r14
leaq 0x34cb(%rip), %r13      # 0x732c
cmpq $0xb, %r14
je 0x3e82
movq %r12, %rdi
movq %r14, %rsi
callq 0x2110
movq %rax, %rdi
movq %r13, %rsi
callq 0x21a0
incq %r14
jmp 0x3e61
movq 0x7147(%rip), %r12      # 0xafd0
movq %r12, %rdi
callq 0x20c0
xorl %r13d, %r13d
movb $0xa, %r14b
movzbl %r13b, %eax
divb %r14b
cmpq $0x64, %r13
je 0x3f0d
movzbl %al, %eax
imull $-0xa, %eax, %eax
movzbl %al, %ebp
movq %r13, %rcx
addq %rbp, %rcx
movzbl %r13b, %eax
divb %r14b
testb %cl, %cl
jne 0x3eda
incb %al
movzbl %al, %esi
movq %r12, %rdi
callq 0x2110
movq %rax, %rdi
leaq 0x3457(%rip), %rsi      # 0x732c
callq 0x21a0
addq %r13, %rbp
addq $-0x9, %rbp
movq (%rbx), %rax
movq (%rax,%r13,8), %rsi
movq %r12, %rdi
callq 0x2100
movq %rax, %rdi
pushq $0x9
popq %rsi
callq 0x21d0
testb %bpl, %bpl
jne 0x3f08
movq %r12, %rdi
callq 0x20c0
incq %r13
jmp 0x3e97
movq 0x70bc(%rip), %r14      # 0xafd0
movq %r14, %rdi
callq 0x20c0
movq %r14, %rdi
callq 0x20c0
leaq 0x3404(%rip), %rsi      # 0x732f
movq %r14, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
leaq 0x3361(%rip), %rsi      # 0x72a3
movq %r14, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
leaq 0x33e2(%rip), %rsi      # 0x733b
movq %r14, %rdi
callq 0x21a0
movq 0x18(%r15), %rsi
movq %rax, %rdi
callq 0x2110
leaq 0x33dc(%rip), %rsi      # 0x7350
movq %rax, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
cmpq $0x0, 0x18(%r15)
je 0x405a
movq 0x703a(%rip), %r12      # 0xafd0
leaq 0x33c3(%rip), %rsi      # 0x7360
movq %r12, %rdi
callq 0x21a0
pushq $0xa
popq %rsi
movq %rax, %rdi
callq 0x2110
leaq 0x33cd(%rip), %rsi      # 0x7384
movq %rax, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
addq $0x10, %r15
xorl %r14d, %r14d
leaq 0x33bf(%rip), %r13      # 0x7394
leaq 0x3403(%rip), %rbp      # 0x73df
movq (%r15), %r15
testq %r15, %r15
je 0x4034
cmpq $0x9, %r14
ja 0x3fdc
movq %r12, %rdi
movq %r13, %rsi
callq 0x21a0
movq 0x8(%r15), %rsi
movq %rax, %rdi
callq 0x2100
movq %rax, %rdi
leaq 0x339a(%rip), %rsi      # 0x73a5
callq 0x21a0
movq 0x10(%r15), %rsi
movq %rax, %rdi
callq 0x2100
movq %rax, %rdi
movq %rbp, %rsi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
incq %r14
jmp 0x3fdc
movq 0x6f95(%rip), %r14      # 0xafd0
movq %r14, %rdi
callq 0x20c0
leaq 0x339c(%rip), %rsi      # 0x73e6
movq %r14, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
movq 0x6f6f(%rip), %r14      # 0xafd0
movq %r14, %rdi
callq 0x20c0
leaq 0x3509(%rip), %rsi      # 0x7579
movq %r14, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
leaq 0x321c(%rip), %rsi      # 0x72a3
movq %r14, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
movsd 0x8(%rsp), %xmm0
unpcklps 0x1f9c(%rip), %xmm0     # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x1fa4(%rip), %xmm0     # 0x6050
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movapd %xmm1, 0x10(%rsp)
pushq $0x1
popq %r14
movl $0x3e8, %r15d           # imm = 0x3E8
leaq 0x34c0(%rip), %r12      # 0x758f
leaq 0x34bf(%rip), %r13      # 0x7595
leaq 0x34bd(%rip), %rbp      # 0x759a
movq 0x8(%rbx), %rax
subq (%rbx), %rax
sarq $0x3, %rax
cmpq %r15, %rax
cmovaeq %r15, %rax
cmpq %r14, %rax
jbe 0x416e
movq 0x6ed5(%rip), %rdi      # 0xafd0
movq %r12, %rsi
callq 0x21a0
movq %rax, %rdi
movq %r14, %rsi
callq 0x2110
movq %rax, %rdi
movq %r13, %rsi
callq 0x21a0
movq (%rbx), %rcx
movsd (%rcx,%r14,8), %xmm1
unpcklps 0x1f17(%rip), %xmm1     # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x1f1f(%rip), %xmm1     # 0x6050
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
mulsd 0x1eeb(%rip), %xmm0     # 0x6030
divsd 0x10(%rsp), %xmm0
movq %rax, %rdi
callq 0x2260
movq %rax, %rdi
movq %rbp, %rsi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
incq %r14
jmp 0x40dd
movq 0x6e5b(%rip), %r14      # 0xafd0
movq %r14, %rdi
callq 0x20c0
leaq 0x3419(%rip), %rsi      # 0x759d
movq %r14, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
leaq 0x3108(%rip), %rsi      # 0x72a3
movq %r14, %rdi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
xorpd %xmm0, %xmm0
movsd %xmm0, 0x8(%rsp)
pushq $0x1
popq %r15
movl $0x3e8, %r14d           # imm = 0x3E8
leaq 0x33ed(%rip), %r12      # 0x75b3
leaq 0x33c8(%rip), %r13      # 0x7595
leaq 0x33c6(%rip), %rbp      # 0x759a
movq (%rbx), %rax
movq 0x8(%rbx), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %r14, %rcx
cmovaeq %r14, %rcx
cmpq %r15, %rcx
jbe 0x427f
movsd (%rax,%r15,8), %xmm0
unpcklps 0x1e41(%rip), %xmm0     # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x1e49(%rip), %xmm0     # 0x6050
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movq 0x6da6(%rip), %rdi      # 0xafd0
movq %r12, %rsi
callq 0x21a0
movq %rax, %rdi
movq %r15, %rsi
callq 0x2110
movq %rax, %rdi
movq %r13, %rsi
callq 0x21a0
movsd 0x8(%rsp), %xmm0
mulsd 0x1dda(%rip), %xmm0     # 0x6030
divsd 0x10(%rsp), %xmm0
movq %rax, %rdi
callq 0x2260
movq %rax, %rdi
movq %rbp, %rsi
callq 0x21a0
movq %rax, %rdi
callq 0x20c0
incq %r15
jmp 0x41d4
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq