VirtualBox6.0.4でトラブル?
数日前から、ブルースクリーン(PAGE_FAULT_IN_NONPAGED_AREA)が頻発するようになった。再起動すればMEMORY_MANAGEMENT発生。
発生のタイミングは何かのソフトを起動したときが多いが何もしなくても発生することもある。厄介だ。
いろいろ原因の絞り込みを行い、最終的にクリーンインストールやメモリ交換まで覚悟していたそのとき・・・
なぜか全然落ちなくなった。
そこではたと気づいた。青画面で仮想OSが落ちるのが怖くてVirtualBoxを起動していなかったことに。
これはVBxが原因ではないか。そういえば最近6.0にアップデートしたんだった。
そこで一度アンインストールして5.2に戻した。
結果:VBx5.2起動してても全然落ちなくなった。ほぼ間違いなくこれだ。万歳!
大きい数が出やすいサイコロ関数
課題
例えば最小値1,最大値5のとき
1,2,2,3,3,3,4,4,4,4,5,5,5,5,5といった
数字と出やすさが比例する15面体のサイコロを想定して出目を出力する関数を作る。
素直な解
int x = rand(15);
write(f(x));
function f(x) {
int y = 0;
while (x > 0)
{
x -= ++y;
}
return y;
公式で
たしかに上記でもできたけど、できればループより式で一発解答したいものです。
当方のサビついた頭では難しそうと思い込みいろいろ考えた末、実は中学レベルの問題だったことに気付いて愕然とした。
y||x
....
3||4|5|6|
2||2|3|
1||1|
3段目の例でいえばxが4~6のときyが3になるような式を作れば良いことがわかる。
ということで右端の値だけに着目すると
y||x
....
3||6|=1+2+3
2||3|=1+2
1||1|=1
これはx={y(y+1)}/2で表せる式である。
これをyについて解く必要がある。
まず展開すると
x=1/2y^2+1/2y
2倍して
2x=y^2+y
y^2+y-2x=0
あらためて2次方程式の解の公式を使いyについて解くと
y={-1±√(1+8x)}/2
ただしここでいうxはyに対応する最大値なので、小数点以下の端数が出た場合は切り上げることになる。
式 y=ceil({-1±√(1+8x)}/2)
c# double y = Math.Ceiling((-1 + Math.Sqrt(1 + 8 * (double)x)) / 2);