先日、以下の動画を見ました。
ぷりんは思いました。
「そんな雑な計算で満足すんの??」
ということで、真面目に追試してみます。
問題の条件
通常のシャトルランのルールは以下のサイトにまとまっていたので、この記事では詳細は割愛します。
音源は youtube で簡単に聞くことができます。例えば↓
ルールの重要な部分だけまとめると、以下の通りです。
- 平行線の間隔は20m
- 所定の法則に則って決められた時間内に一方の直線から他方に移動することを繰り返す
- 二回連続でラインを踏めなければアウト
これらのルールに則った上で
- 法則を適当に外挿し、仮想的にいくらでもシャトルランが続く状況を作る
- 平行線の間は光速
で移動できるものとする
- 方向転換の時間は無視する
の条件で
- 最大レベル
- 最後に平行線に到達した時点までの累計移動回数
- 同累計移動距離
- 同累計移動時間
をなるべく正確に計算したいと思います。
条件の整理
公式?では247回までの折り返し回数を想定しており、具体的に間隔が与えられています。以下は wikipedia に掲載されていた法則を抜粋したものです。
| レベル | 折り返し回数 | 速度 (km/h) | 折り返し時間 (秒) | レベル内 合計時間(秒) |
|---|---|---|---|---|
| 1 | 7 | 8 | 9 | 63 |
| 2 | 8 | 9 | 8 | 64 |
| 3 | 8 | 9.5 | 7.58 | 60.63 |
| 4 | 9 | 10 | 7.2 | 64.8 |
| 5 | 9 | 10.5 | 6.86 | 61.71 |
| 6 | 10 | 11 | 6.55 | 65.5 |
| 7 | 10 | 11.5 | 6.26 | 62.61 |
| 8 | 11 | 12 | 6 | 66 |
| 9 | 11 | 12.5 | 5.76 | 63.36 |
| 10 | 11 | 13 | 5.54 | 60.92 |
| 11 | 12 | 13.5 | 5.33 | 64 |
| 12 | 12 | 14 | 5.14 | 61.71 |
| 13 | 13 | 14.5 | 4.97 | 64.55 |
| 14 | 13 | 15 | 4.8 | 62.4 |
| 15 | 13 | 15.5 | 4.65 | 60.39 |
| 16 | 14 | 16 | 4.5 | 63 |
| 17 | 14 | 16.5 | 4.36 | 61.09 |
| 18 | 15 | 17 | 4.24 | 63.53 |
| 19 | 15 | 17.5 | 4.11 | 61.71 |
| 20 | 16 | 18 | 4 | 64 |
| 21 | 16 | 18.5 | 3.89 | 62.27 |
この表から法則性を見出し、高いレベルまで外挿します。
じっと眺めると、折り返し時間 (秒) とレベル内合計時間
(秒) の間に
最大レベル
光速を (m/s)とすれば、ギリギリ光速を超えないレベル
は
累計移動回数
累計移動回数 は
累計移動距離
累計移動距離は
累計移動時間
もはや厳密に計算するのが厳しいため、近似計算を行います。 が大きい近似を行うと
[追記: 2020/08/22]
プログラムを組んで計算してみたところ
結果
以上をまとめると次のようになります。
- 最大レベル
21億5850万5681
- 累計移動回数
97京655兆5941億1501万5833回
- 同累計移動距離
1941京3111兆8823億0031万6660m (約2053.373光年)
- 同累計移動時間
約4106.746年
[追記: 2020/08/22]
129510342313.7983240214824584秒(若干の誤差含む)
いやはや、光ってすごいですね。
追記(2020/08/22): 累計移動時間の計算プログラム
以下の Julia のコードで計算しました。
mutable struct LongFloat
seisu::Int
shosu::Float64
end
function Base.show(io::IO, x::LongFloat)
s_seisu = string(x.seisu)
s_shosu = string(x.shosu)
print(io, s_seisu, " + ", s_shosu)
end
function simplify!(x::LongFloat)
if x.shosu < 0 || x.shosu >= 1
n = floor(Int, x.shosu)
x.seisu += n
x.shosu -= n
end
end
function num(level::Int)::Int
if level==1
return 7
else
return div(92 + 5*level, 12)
end
end
function time!(level::Int, cum_time::LongFloat)
if level==1
cum_time.seisu += 63
else
numer = num(level) * 144
denom = 16 + level
add_sei = div(numer, denom)
add_sho = (numer % denom) / denom
cum_time.seisu += add_sei
cum_time.shosu += add_sho
simplify!(cum_time)
end
end
function main()
LMAX = 2158505681
all_time = LongFloat(0, 0.)
for level = 1:LMAX
time!(level, all_time)
end
println(all_time)
end
main()