f(123)=1+2+3=6
のように定義された関数f(x)がある。
問2
f(nm)=n
となる正の整数n, mを求めよ。
前回の記事である程度(2325個)のデータが蓄積出来たので、n, mを軸に分布図を作ってみる。
データはExcelで集計していたのだが、どうもExcelの散布図が気に入らず、HTML5+Javascriptで自作しました。
横軸をn、縦軸をmとした2325点の分布。
赤○はnの末尾3桁が0
青○はnの末尾2桁が0
緑○はnの末尾1桁が0
黒○は残りすべて
として色分けしてみました。
私が予想していたとおり、nの末尾の0の個数で、mのレンジは明らかに変わってくることは、分布から解る。
それぞれの色はある程度の幅を持ち、帯状に連なっており、何らかの関数で挟み撃ち出来そうではある。
ただし今回作ったプログラムはnはすべて捜査したが、mはある程度の幅でのみの捜査しかしていない。
例外的にレンジから外れるようなものがある可能性は捨てきれない。
そうは言っても、自分の欲求は抑えられないので、何らかのデータが欲しい。
nmを整数として正確に求めなければならない。
そのためにはかなり大きな入れ物が必要になる。
入れ物が大きくなると、その分、計算量も比例して多くなると予想出来る。
もし、期限付きの問題であれば時間内に何らかの答えを出す必要があるので、どれくらいアイディアをひねり出せるのかが勝負だろう。
私は、こういうことに関しては負けず嫌いなので、他人より桁違いの多くのデータを出したがる。
単純に考えてみよう。
nは10000までやりたいと簡単に言えたとして、
mはどこまで捜査すればよいのだろうか解らない。
一般的なプログラミング言語を考えれば、64ビット正整数でやったとしても、
0~18446744073709551615
であるから、20桁あるが19桁が限界。
n=10ならm=19まで、
n=100ならm=9まで、
n=1000ならm=6まで、
n=10000ならm=4まで、
現実的にはn<100すらも漏れなく求めることが出来ない。
例えば、
n=40, m=13
nm=671088640000000000000
nの末尾に0が付くものはmの桁数が大きくなる傾向にある。
n=98, m=18
nm=8007313507497959524352
nの末尾に0は付かなくとも、nが大きくなればm比例するように大きいものになる傾向にある。
n<10000を目指すには多倍長演算は必須である。
例えば、赤○の3点に着目してみよう。
n=4000, m=1465, k=ceil(1465*log10(4000))=5278
n=8000, m=1935, k=ceil(1935*log10(8000))=7553
n=8000, m=1975, k=ceil(1975*log10(8000))=7709
kはnmの桁数である。
この結果を見て8000桁も用意すれば十分だろうというのは誰でも出来るが、データが無い状態ではどれくらい用意すればいいかは解らない。
このグラフを見た上で、nを10万とか100万とかまで回すという人には十分指針になるだろう。
さて、何桁用意するかは置いておいて、別の角度から考えてみる。
単純に各桁に使われる数は0から9ですから、(0+9)/2=4.5が平均である。
桁数が多くなれば、この平均に近づくだろうという推測のもとテストプログラムを組んでみたわけです。
横軸をn、縦軸をn/kで分布図を作ってみる。
k=ceil(m*log10(n))
で、n^mの桁数kを求めています。
黒○は十分に私の予想どおり、nが増えるにつれ4.5に近似していき、帯の幅も狭まっていきます。
プログラムで、黒○、緑○、青○、赤○、隔てなく扱うならば、何らかの補正が必要ですね。
nの末尾の0の個数をzとすると、
nmの末尾の0の個数はmzとなります。
これをkから引いてしまえば、分布は重なるだろう。
縦軸をn/(k-mz)としてみました。
見事に緑○、青○、赤○は、黒○の群衆に飲み込まれましたね。
ただ、私の作ったテストプログラムも漏れなくデータを見つけているかはなんとも言えないのが現状である。
例えば、4000≤nならば、4.0<n/(k-mz)<5.0くらいあれば十分だと考えるとか、何を持って十分なのかは個々の判断です。
とりあえずは今回は分布図をいくつか描いてみたということにすぎないです。
まぁ、2325個も解を見つけたということで、かなり満足はしている。
ではでは
↧
f(123)=1+2+3=6のときf(nᵐ)=nなる正の整数n,mを求めた結果をみて
↧