// File: 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
movq %rsp, %rbp
subq $0xe0, %rsp
movq 0x10(%rbp), %rax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
movq %r9, -0x30(%rbp)
movq 0x11282(%rip), %rdi     # 0x16fd0
leaq 0xa551(%rip), %rsi      # 0x102a6
callq 0x2210
movq %rax, %rdi
movq 0x1125c(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x11260(%rip), %rdi     # 0x16fd0
leaq 0xa53c(%rip), %rsi      # 0x102b3
callq 0x2210
movq %rax, %rdi
movq 0x1123a(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x1123e(%rip), %rdi     # 0x16fd0
leaq 0xa52d(%rip), %rsi      # 0x102c6
callq 0x2210
movq %rax, %rdi
movq 0x11218(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x1121c(%rip), %rdi     # 0x16fd0
leaq 0xa525(%rip), %rsi      # 0x102e0
callq 0x2210
movq %rax, -0x98(%rbp)
movq -0x30(%rbp), %rdi
movq 0x10(%rbp), %rsi
callq 0x24f0
movq -0x98(%rbp), %rdi
callq 0x2390
movq %rax, %rdi
leaq 0xa61d(%rip), %rsi      # 0x10407
callq 0x2210
movq %rax, %rdi
movq 0x111c7(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x111cb(%rip), %rdi     # 0x16fd0
leaq 0xa4e1(%rip), %rsi      # 0x102ed
callq 0x2210
movq %rax, %rdi
movl -0x24(%rbp), %esi
callq 0x22e0
movq %rax, %rdi
movq 0x1119a(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x1119e(%rip), %rdi     # 0x16fd0
leaq 0xa4d6(%rip), %rsi      # 0x1030f
callq 0x2210
movq %rax, %rdi
movq -0x18(%rbp), %rsi
callq 0x21f0
movq %rax, %rdi
movq 0x1116c(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x11170(%rip), %rdi     # 0x16fd0
leaq 0xa4b7(%rip), %rsi      # 0x1031e
callq 0x2210
movq %rax, %rdi
movq -0x20(%rbp), %rsi
callq 0x21f0
movq %rax, %rdi
movq 0x1113e(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x11142(%rip), %rdi     # 0x16fd0
movq 0x1112b(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x1112f(%rip), %rdi     # 0x16fd0
leaq 0xa48c(%rip), %rsi      # 0x10334
callq 0x2210
movq %rax, %rdi
movq 0x11109(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x1110d(%rip), %rdi     # 0x16fd0
leaq 0xa3fc(%rip), %rsi      # 0x102c6
callq 0x2210
movq %rax, %rdi
movq 0x110e7(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x110eb(%rip), %rdi     # 0x16fd0
leaq 0xa451(%rip), %rsi      # 0x1033d
callq 0x2210
movq %rax, %rdi
movl $0x64, %esi
callq 0x2060
movq %rax, %rdi
leaq 0xa43c(%rip), %rsi      # 0x10344
callq 0x2210
movq %rax, %rdi
movq 0x110a9(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x110ad(%rip), %rdi     # 0x16fd0
leaq 0xa426(%rip), %rsi      # 0x10350
callq 0x2210
movl $0x0, -0x34(%rbp)
cmpl $0xa, -0x34(%rbp)
jae 0x5f68
movl -0x34(%rbp), %esi
addl $0x1, %esi
movq 0x11087(%rip), %rdi     # 0x16fd0
callq 0x22e0
movq %rax, %rdi
leaq 0xa3f7(%rip), %rsi      # 0x1034f
callq 0x2210
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x5f36
movq 0x11061(%rip), %rdi     # 0x16fd0
movq 0x1104a(%rip), %rsi     # 0x16fc0
callq 0x2240
movq $0x0, -0x40(%rbp)
cmpq $0x64, -0x40(%rbp)
jae 0x6035
movq -0x40(%rbp), %rax
movl $0xa, %ecx
xorl %edx, %edx
divq %rcx
cmpq $0x0, %rdx
jne 0x5fd2
movq -0x40(%rbp), %rax
movl $0xa, %ecx
xorl %edx, %edx
divq %rcx
movq %rax, %rsi
addq $0x1, %rsi
movq 0x11012(%rip), %rdi     # 0x16fd0
callq 0x2060
movq %rax, %rdi
leaq 0xa382(%rip), %rsi      # 0x1034f
callq 0x2210
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x7500
movq (%rax), %rsi
movq 0x10fe7(%rip), %rdi     # 0x16fd0
callq 0x21f0
movq %rax, %rdi
movl $0x9, %esi
callq 0x2290
movq -0x40(%rbp), %rax
movl $0xa, %ecx
xorl %edx, %edx
divq %rcx
cmpq $0x9, %rdx
jne 0x6022
movq 0x10fba(%rip), %rdi     # 0x16fd0
movq 0x10fa3(%rip), %rsi     # 0x16fc0
callq 0x2240
jmp 0x6024
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0x5f83
movq 0x10f94(%rip), %rdi     # 0x16fd0
movq 0x10f7d(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x10f81(%rip), %rdi     # 0x16fd0
movq 0x10f6a(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x10f6e(%rip), %rdi     # 0x16fd0
leaq 0xa2e9(%rip), %rsi      # 0x10352
callq 0x2210
movq %rax, %rdi
movq 0x10f48(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x10f4c(%rip), %rdi     # 0x16fd0
leaq 0xa23b(%rip), %rsi      # 0x102c6
callq 0x2210
movq %rax, %rdi
movq 0x10f26(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x10f2a(%rip), %rdi     # 0x16fd0
leaq 0xa2b1(%rip), %rsi      # 0x1035e
callq 0x2210
movq %rax, -0xa0(%rbp)
movq -0x10(%rbp), %rdi
callq 0x7520
movq -0xa0(%rbp), %rdi
movq %rax, %rsi
callq 0x2060
movq %rax, %rdi
leaq 0xa298(%rip), %rsi      # 0x10373
callq 0x2210
movq %rax, %rdi
movq 0x10ed6(%rip), %rsi     # 0x16fc0
callq 0x2240
movq -0x10(%rbp), %rdi
callq 0x7520
cmpq $0x0, %rax
je 0x6244
movq 0x10ec7(%rip), %rdi     # 0x16fd0
leaq 0xa273(%rip), %rsi      # 0x10383
callq 0x2210
movq %rax, %rdi
movl $0xa, %esi
callq 0x2060
movq %rax, %rdi
leaq 0xa27b(%rip), %rsi      # 0x103a7
callq 0x2210
movq %rax, %rdi
movq 0x10e85(%rip), %rsi     # 0x16fc0
callq 0x2240
movq $0x0, -0x48(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
callq 0x7540
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rdi
callq 0x7570
movq %rax, -0x60(%rbp)
leaq -0x58(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x75a0
testb $0x1, %al
jne 0x6180
jmp 0x620f
leaq -0x58(%rbp), %rdi
callq 0x75d0
movq %rax, -0x68(%rbp)
cmpq $0xa, -0x48(%rbp)
jae 0x61ff
movq 0x10e35(%rip), %rdi     # 0x16fd0
leaq 0xa215(%rip), %rsi      # 0x103b7
callq 0x2210
movq %rax, %rdi
movq -0x68(%rbp), %rax
movq (%rax), %rsi
callq 0x21f0
movq %rax, %rdi
leaq 0xa208(%rip), %rsi      # 0x103c8
callq 0x2210
movq %rax, %rdi
movq -0x68(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x21f0
movq %rax, %rdi
leaq 0xa223(%rip), %rsi      # 0x10402
callq 0x2210
movq %rax, %rdi
movq 0x10dd2(%rip), %rsi     # 0x16fc0
callq 0x2240
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x6201
leaq -0x58(%rbp), %rdi
callq 0x7600
jmp 0x616a
movq 0x10dba(%rip), %rdi     # 0x16fd0
movq 0x10da3(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x10da7(%rip), %rdi     # 0x16fd0
leaq 0xa1d9(%rip), %rsi      # 0x10409
callq 0x2210
movq %rax, %rdi
movq 0x10d81(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x10d85(%rip), %rdi     # 0x16fd0
movq 0x10d6e(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x10d72(%rip), %rdi     # 0x16fd0
leaq 0xa337(%rip), %rsi      # 0x1059c
callq 0x2210
movq %rax, %rdi
movq 0x10d4c(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x10d50(%rip), %rdi     # 0x16fd0
leaq 0xa03f(%rip), %rsi      # 0x102c6
callq 0x2210
movq %rax, %rdi
movq 0x10d2a(%rip), %rsi     # 0x16fc0
callq 0x2240
movl $0x1, -0x6c(%rbp)
movl -0x6c(%rbp), %eax
movq %rax, -0xa8(%rbp)
movq -0x8(%rbp), %rdi
callq 0x7670
movq %rax, -0x78(%rbp)
leaq 0xa3c0(%rip), %rdi      # 0x10680
leaq -0x78(%rbp), %rsi
callq 0x7630
movq %rax, %rcx
movq -0xa8(%rbp), %rax
cmpq (%rcx), %rax
jae 0x63a4
movq 0x10ced(%rip), %rdi     # 0x16fd0
leaq 0xa2c8(%rip), %rsi      # 0x105b2
callq 0x2210
movq %rax, %rdi
movl -0x6c(%rbp), %esi
callq 0x22e0
movq %rax, %rdi
leaq 0xa2b4(%rip), %rsi      # 0x105b8
callq 0x2210
movq %rax, -0xb0(%rbp)
movq -0x8(%rbp), %rdi
movl -0x6c(%rbp), %eax
movl %eax, %esi
callq 0x7500
movq -0xb0(%rbp), %rdi
movq (%rax), %xmm0
movaps 0x8d10(%rip), %xmm3     # 0xf040
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
movapd 0x8d14(%rip), %xmm2     # 0xf050
subpd %xmm2, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movsd 0x8cdd(%rip), %xmm1     # 0xf030
mulsd %xmm1, %xmm0
movq -0x20(%rbp), %xmm1
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
callq 0x2390
movq %rax, %rdi
leaq 0xa23b(%rip), %rsi      # 0x105bd
callq 0x2210
movq %rax, %rdi
movq 0x10c2f(%rip), %rsi     # 0x16fc0
callq 0x2240
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0x62a2
movq 0x10c25(%rip), %rdi     # 0x16fd0
movq 0x10c0e(%rip), %rsi     # 0x16fc0
callq 0x2240
xorps %xmm0, %xmm0
movsd %xmm0, -0x80(%rbp)
movq 0x10c0a(%rip), %rdi     # 0x16fd0
leaq 0xa1f3(%rip), %rsi      # 0x105c0
callq 0x2210
movq %rax, %rdi
movq 0x10be4(%rip), %rsi     # 0x16fc0
callq 0x2240
movq 0x10be8(%rip), %rdi     # 0x16fd0
leaq 0x9ed7(%rip), %rsi      # 0x102c6
callq 0x2210
movq %rax, %rdi
movq 0x10bc2(%rip), %rsi     # 0x16fc0
callq 0x2240
movl $0x1, -0x84(%rbp)
movl -0x84(%rbp), %eax
movq %rax, -0xb8(%rbp)
movq -0x8(%rbp), %rdi
callq 0x7670
movq %rax, -0x90(%rbp)
leaq 0xa24f(%rip), %rdi      # 0x10680
leaq -0x90(%rbp), %rsi
callq 0x7630
movq %rax, %rcx
movq -0xb8(%rbp), %rax
cmpq (%rcx), %rax
jae 0x6548
movq -0x8(%rbp), %rdi
movl -0x84(%rbp), %eax
movl %eax, %esi
callq 0x7500
movq (%rax), %xmm1
movaps 0x8bd4(%rip), %xmm0     # 0xf040
movaps %xmm0, -0xe0(%rbp)
punpckldq %xmm0, %xmm1    # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
movapd 0x8bd1(%rip), %xmm0     # 0xf050
movaps %xmm0, -0xd0(%rbp)
subpd %xmm0, %xmm1
movaps %xmm1, %xmm0
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm0, %xmm1
movsd -0x80(%rbp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x80(%rbp)
movq 0x10b26(%rip), %rdi     # 0x16fd0
leaq 0xa125(%rip), %rsi      # 0x105d6
callq 0x2210
movq %rax, %rdi
movl -0x84(%rbp), %esi
callq 0x22e0
movq %rax, %rdi
leaq 0xa0ea(%rip), %rsi      # 0x105b8
callq 0x2210
movaps -0xe0(%rbp), %xmm3
movaps -0xd0(%rbp), %xmm2
movq %rax, %rdi
movsd -0x80(%rbp), %xmm0
movsd 0x8b3f(%rip), %xmm1     # 0xf030
mulsd %xmm1, %xmm0
movq -0x20(%rbp), %xmm1
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
callq 0x2390
movq %rax, %rdi
leaq 0xa09d(%rip), %rsi      # 0x105bd
callq 0x2210
movq %rax, %rdi
movq 0x10a91(%rip), %rsi     # 0x16fc0
callq 0x2240
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0x640d
addq $0xe0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)