Last active
September 17, 2025 17:20
-
-
Save iwkjosec/a0c3a7768c84070ee9710b55a1d35186 to your computer and use it in GitHub Desktop.
勝利の女神:NIKKEの初心者用お手入れキットはR等級とSR等級どちらに使うべきか
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| def expected_trials_to_reach(p_list, cutoff): | |
| """ | |
| p_list : list of length 15 with p_0..p_14 (success probabilities) | |
| cutoff : int, max number of trials per state before forced move to k+1 | |
| """ | |
| n = 15 # states 0..14, plus absorbing state 15 | |
| def A_k(p): | |
| q = 1 - p | |
| if p == 0.0: | |
| return float(cutoff) | |
| s = 0.0 | |
| for t in range(1, cutoff + 1): | |
| s += t * (q ** (t - 1)) * p | |
| return s + cutoff * (q ** cutoff) | |
| def s_k(p): | |
| # success at least once within cutoff trials | |
| return 1 - (1 - p) ** cutoff | |
| E = [] | |
| for target in range(0, n + 1): | |
| F = [0.0] * (n + 1) | |
| for k in range(target - 1, -1, -1): | |
| p = p_list[k] | |
| Ak = A_k(p) | |
| sk = s_k(p) | |
| m = (k // 5) * 5 + 5 | |
| if m > n: | |
| m = n | |
| F[k] = Ak + sk * F[m] + (1.0 - sk) * F[k + 1] | |
| E.append(F[0]) | |
| return E | |
| # 例:p_k を適当に設定して実行 | |
| r = [0.176, 0.208, 0.240, 0.272, 0.400, 0.160, 0.192, 0.224, 0.272, 0.400, 0.144, 0.176, 0.224, 0.272, 0.400] | |
| sr = [0.036, 0.059, 0.078, 0.113, 0.150, 0.022, 0.033, 0.049, 0.076, 0.125, 0.012, 0.022, 0.031, 0.047, 0.100] | |
| r_values = expected_trials_to_reach(r, 5) | |
| sr_values = expected_trials_to_reach(sr, 15) | |
| print(f"{'i':>2} | {'r':>10} | {'sr':>10}") | |
| print("-" * 27) | |
| for i, (rv, srv) in enumerate(zip(r_values, sr_values)): | |
| print(f"{i:2} | {rv:10.6f} | {srv:10.6f}") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| def expected_stage_over_time(p_list, cutoff, max_k): | |
| """ | |
| p_list: list of length 15 with p_0..p_14 (success probabilities) | |
| cutoff: max failures before forced move to i+1 | |
| max_k: compute expected stage from 0 to max_k trials | |
| Returns: list of expected stages [E0, E1, ..., E_max_k] | |
| """ | |
| n = 15 | |
| assert len(p_list) == n | |
| # 初期分布 | |
| prob = [ [0.0]*cutoff for _ in range(n) ] + [ [0.0] ] # last for i=15 | |
| prob[0][0] = 1.0 | |
| expected_stages = [] | |
| for step in range(max_k + 1): | |
| # 現在の分布から期待到達段階を計算 | |
| exp_stage = 0.0 | |
| for i in range(n): | |
| exp_stage += i * sum(prob[i]) | |
| exp_stage += n * prob[n][0] | |
| expected_stages.append(exp_stage) | |
| # 次の試行の分布に更新 | |
| new_prob = [ [0.0]*cutoff for _ in range(n) ] + [ [0.0] ] | |
| for i in range(n): | |
| for r in range(cutoff): | |
| mass = prob[i][r] | |
| if mass == 0.0: | |
| continue | |
| p = p_list[i] | |
| # 成功時 | |
| m = (i//5)*5 + 5 | |
| if m > n: m = n | |
| new_prob[m][0 if m < n else 0] += mass * p | |
| # 失敗時 | |
| if r + 1 < cutoff: | |
| new_prob[i][r+1] += mass * (1.0 - p) | |
| else: | |
| ni = i + 1 | |
| if ni > n: ni = n | |
| new_prob[ni][0 if ni < n else 0] += mass * (1.0 - p) | |
| # 吸収状態はそのまま | |
| new_prob[n][0] += prob[n][0] | |
| prob = new_prob | |
| return expected_stages | |
| r = [0.176, 0.208, 0.240, 0.272, 0.400, 0.160, 0.192, 0.224, 0.272, 0.400, 0.144, 0.176, 0.224, 0.272, 0.400] | |
| sr = [0.036, 0.059, 0.078, 0.113, 0.150, 0.022, 0.033, 0.049, 0.076, 0.125, 0.012, 0.022, 0.031, 0.047, 0.100] | |
| k = 20 | |
| E_over_time = expected_stage_over_time(r, 5, k) | |
| E_over_time_s = expected_stage_over_time(sr, 15, k) | |
| print(f"{'試行':>4} | {'r':>10} | {'sr':>10}") | |
| print("-" * 28) | |
| for step, (E_r, E_s) in enumerate(zip(E_over_time, E_over_time_s)): | |
| print(f"{step:4d} | {E_r:10.4f} | {E_s:10.4f}") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| i | r | sr | |
| --------------------------- | |
| 0 | 0.000000 | 0.000000 | |
| 1 | 3.523461 | 11.750749 | |
| 2 | 4.780650 | 17.602167 | |
| 3 | 5.148821 | 19.694427 | |
| 4 | 5.236604 | 20.200602 | |
| 5 | 5.250755 | 20.269630 | |
| 6 | 8.886930 | 33.165994 | |
| 7 | 10.314961 | 41.750477 | |
| 8 | 10.777021 | 46.428024 | |
| 9 | 10.895555 | 48.290181 | |
| 10 | 10.914662 | 48.721111 | |
| 11 | 14.667522 | 62.524333 | |
| 12 | 16.286863 | 73.284560 | |
| 13 | 16.846943 | 80.542391 | |
| 14 | 16.990622 | 84.619838 | |
| 15 | 17.013783 | 86.057203 |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
勝利の女神:NIKKEにおいて、SR等級コレクションを初心者用お手入れキットで5段階まで強化するよりR等級コレクションを初心者用お手入れキットで15段階まで強化してからSR等級に交換した方がお得というのは本当か。
コレクションの1段階強化に必要な経験値
お手入れキット毎の経験値
大成功を外し続けた場合、1段階進むのに必要なお手入れ回数はR等級は初心者用5(=1000/200)回で、SR等級は初心者用15(=3000/200)回で進む。
15段階のR等級をSR等級に交換すると5段階になる。
段階$i$ において$1$ 回の試行で当りが出る確率は$ p_i (i=0 \sim 14)$ である。当たりが出たら次の$5$ の倍数の段階に進み、外れが出たら現在の段階にとどまる。その段階に到達してから$k$ 回外れが出た場合は次の段階$i+1$ に進む。$0$ から$i$ に到達するまでにかかる試行回数の期待値$E_i$ を$i=15$ まで求めたい。
この試行を繰り返して段階
以上の問題を(頭を使いたくないので)ChatGPT(GPT-5 Thinking Mini)に投げると
calc.pyを得る。頭を使いたくないので解法のチェックはしていない(カス)。calc.pyを実行するとoutput.txtを得る。output.txtを見るとと分かる。
初心者用お手入れキットだけを使う場合、初めからSR等級を持たせるよりR等級を15段階にしてからSR等級に交換した方が約3.3回お手入れ回数が少なく済む。ニケ1機当たり初心者用お手入れキット33個分の節約になる。
中/上級者用お手入れキットは貴重なので全部SR等級5段階以降に使おう。
おまけ:
calc2.pyは試行回数毎の段階の期待値を計算するプログラム。当然output.txtの逆引きよりは小さい値になる。