金字塔数について
金字塔数の種類:
完成・金字塔数 /
可変頂上幅・金字塔数 /
可変踏板幅・金字塔数 /
扇数
金字塔数のPythonのコード :
完成・金字塔関数 /
可変頂上幅・金字塔関数 /
可変踏板幅・金字塔関数 /
扇関数
金字塔数とは?
1, 121, 12321, 1234321, 123454321 , .. , 12345678987654321という、扇数どうしを掛け合わせることで得られる数値をこのページやアンドールのYouTubeちゃんねるの中では金字塔数と呼ぶ事にしました。
12,345,678,987,654,321のように、扇数(repunit)を自乗して得られる値の事を数学の世界ではデムロ数(Demlo numbers)と呼んでいます。
このAlbert H. Beiler氏の著書の参考文献の一覧ページ66ではSelkin, F. B “Number Games Bordering on Arithmetic and Algebra, ” Teachers College Recored, 13 (1912), 68.とありますので、K. R. GUNJIKAR氏とD. R. KAPREKAR氏の独立再発見と考えられます。
扇数とは?
1, 11, 111, …, 1111111111のように、1の連続だけで表す事ができる数の事を扇数と呼ぶ事にしました
エースの札だけを沢山用意し、扇の様に広げた際に、それぞれの札を、各桁の数値と見立てて得られる値を、ここでは扇数と呼ぶ事にします。
「扇数」は数学的な専門用語では、repunit (repeated unitの省略)で、「レプユニット」、または「レピュニット」と呼ばれ、「単位反復数」とも訳されます。
このページやアンドールシステムサポートのYouTubeちゃんねる、電脳寺子屋 数学を学ぶシリーズの中では、出来るだけ短く表記したいので、「扇数」と呼ぶ事にします。
扇関数を求める計算式
n進数(base = n)のx桁の扇数を返す関数をA(x, base = n)とした場合下記の式で表す事ができます。
\(A(x, base = n)\) \(=\displaystyle \sum_{k=0}^{x-1}n^{k}\) \(= \displaystyle \frac{n^x-1}{n-1}\)
扇関数の特長
扇関数は、引数\(x = 0\)の場合には、全ての進数で0を返します。
\(
A(0, base = n) = 0
\)
扇関数は、引数\(x = 1\)の場合には、全ての進数で1を返します。
\(
A(1, base = n) = 1
\)
扇数を求めるPythonのコード
総和をそのままfor文を利用して実装した場合は下記の関数となります。
def A(x, base = 10):
s = 0
for k in range (0, x):
s += base**k
return s
n進数の扇数を返す扇関数A(x, n)を等比数列の総和公式から得た上記の式をPythonで関数として記述すると下記の関数となります。
def A(x, base = 10): return ((base**x)-1) // (base - 1)
補足:上記の関数では2番目の仮引数をbase = 10としてるので、2番目の仮引数を省略した場合、A(x) = A(x, 10)となります。
扇数の関連動画
アンドールシステムサポートのYouTubeちゃんねるでは「扇数」を題材とし、組み込みの開発に役立つ解説を行っております。
電脳寺子屋 数学を学ぶ「扇数と再帰関数」扇関数を例に、再帰関数と組み込みにおけるスタック・メモリの影響について説明ます。
電脳寺子屋 数学を学ぶ「扇数とPython」- Pythonのすすめ扇関数をC言語で実装した例と、Pythonで実装した例を通して、C言語に馴染んでいる方向けに、C言語の記述例とPythonの記述例を比較する形で、 Pythonの文法や特長の一部を紹介させて頂きます。
金字塔数を求める数式
段数を\( x\)、進数の底を\(base = n\)とする金字塔数を求める金字塔関数\(P(x, base = n)\)をPythonで記述すると下記の関数となります。
\(P(x, base = n) = A(x, n)^2\)
同じ進数の同じ桁数の扇数どうしの値を掛け合わせて得られる金字塔数は、n進数では、n-1桁の扇数の場合に、各桁の数値を高さと見なした場合、頂点の長さが1となり、完成(perfect)した金字塔の形に見えることがら、他の金字塔数と区別が必要な場合には完成・金字塔数と呼び、完成金字塔数を求める関数Pを完成・金字塔数と呼ぶ事にしました。
金字塔関数の特長
引数が\(x = 0\)の場合には、全ての進数で0となります。
\(
P(0, base = n) = 0
\)
引数が\(x = 1\)の場合には、全ての進数で1となります。
\(
P(1, base = n) = 1
\)
金字塔数を求めるPythonのコード
def P(x, base=10): return A(x, base) ** 2
扇関数A(x, base)のPythonのコードについてはこちらを参照してください。
補足:上記の関数では2番目の仮引数をbase = 10としてるので、2番目の仮引数を省略した場合、P(x) = P(x, 10)となります。
10進数で金字塔数関数が返す金字塔数の例
10進数の場合、引数の値が0~9までの範囲の場合と、10以上の場合とでは、現れるパターンが変化します。
金字塔関数に対し、10進数で引数を0から20まで与えた際にえられる金字塔数の値
\(P(1) = A(1)^2 = 1^2 = 1\)
\(P(2) = A(2)^2 = 11^2 = 121\)
\(P(3) = A(3)^2 = 111^2 = 12321\)
\(P(4) = A(4)^2 = 1111^2 = 1234321\)
\(P(5) = A(5)^2 = 11111^2 = 123454321\)
\(P(6) = A(6)^2 = 111111^2 = 12345654321\)
\(P(7) = A(7)^2 = 1111111^2 = 1234567654321\)
\(P(8) = A(8)^2 = 11111111^2 = 123456787654321\)
\(P(9) = A(9)^2 = 111111111^2 = 12345678987654321\)
\(P(10) = A(10)^2 = 1111111111^2 = 1234567900987654321\)
\(P(11) = A(11)^2 = 11111111111^2 = 123456790120987654321\)
\(P(12) = A(12)^2 = 111111111111^2 = 12345679012320987654321\)
\(P(13) = A(13)^2 = 1111111111111^2 = 1234567901234320987654321\)
\(P(14) = A(14)^2 = 11111111111111^2 = 123456790123454320987654321\)
\(P(15) = A(15)^2 = 111111111111111^2 = 12345679012345654320987654321\)
\(P(16) = A(16)^2 = 1111111111111111^2 = 1234567901234567654320987654321\)
\(P(17) = A(17)^2 = 11111111111111111^2 = 123456790123456787654320987654321\)
\(P(18) = A(18)^2 = 111111111111111111^2 = 12345679012345678987654320987654321\)
\(P(19) = A(19)^2 = 1111111111111111111^2 = 1234567901234567900987654320987654321\)
\(P(20) = A(20)^2 = 11111111111111111111^2 = 123456790123456790120987654320987654321\)
金字塔数は、n進数の場合は、引数xがn-1の範囲までの値の場合と、それを超えた場合で、規則性が変化します。
- 未崩壊: 引数xがn-1の範囲までの値
- 崩壊: 引数xがnの値を答えた場合の値
未崩壊の範囲の場合
引数で与えられた桁数が中心となり、各桁に入る値も中央の桁が最大となります。
また、最上位の桁と最下位の桁は1となり、中央の桁に向かって値が1つづつ増加するという性質を持ちます。
崩壊の範囲の場合
n進数で、xがnの値を超えた場合であっても、未崩壊の場合と同じように、n進数の数値として観測される前の段階では、並んでいますが、
各桁の値で表現できる値はn進数の場合には、n-1までとなるため、nを超えた値は、上位の桁に向かって桁上りが生じます。
そのため、n進数として観測した際には、桁上りにより、上位の桁に向かって規則正しい連続性の崩壊が生じます。
この崩壊のパターンには規則性があるため、下記のようにPythonのコードで表すことができ、ここまで、説明させて頂いた、金字塔数を求めるコードが返す値と完全に一致します。
パターンに基づいた金字塔数を返すPythonのコード
金字塔数が持つパターン性に基づいて金字塔数を返すPythonのコード
# 上位側の桁のパターンを生成するPythonの関数
def _get_tpv(base): tpv = 0 for k in range(1, base-1): tpv = tpv * base +k if (2==base): tpv = 1 else: tpv = (tpv+1) * base return tpv
# 中間の桁のパターンを生成するPythonの関数
def _get_cpv(r, base): cpv = 0 if (r > 0): for k in range(1, r + 2): cpv = (cpv * base) + k for k in range(0,r-1): cpv = (cpv * base) + (r - k) return cpv
# 下位側の桁のパターンを生成するPythonの関数
def _get_bpv(base): bpv = 0 for k in range(1, base-1): bpv = (bpv * base) + (base -k) return bpv
# 上記の3つの関数を利用して金字塔数をパターンとして生成するPythonの関数
def Pn(x, base = 10): if(0 == x): return 0 tpl = base-1 bpl = tpl tpv = _get_tpv(base) bpv = _get_bpv(base) q = ((x-1) // (base-1)) r = ((x-1) % (base-1)) cpl = r *2 if(2 == base): cpl = 1 y = 0 for k in range(0, q): y = y *(base **tpl) + tpv y = y * (base ** cpl) + _get_cpv(r, base) for k in range(0, q): y = y * (base **bpl) + bpv return (y*base + 1)
上記のPythonの関数Pn(x, base)とP(x, base)の返す値は一致します。
金字塔数のバリエーション
扇数を掛け合わせることで得られる金字塔数には複数の種類があります。
金字塔数の種類:
完成・金字塔数 /
可変頂上幅・金字塔数 /
可変踏板幅・金字塔数
金字塔数のPythonのコード :
完成・金字塔関数 /
可変頂上幅金字塔関数 /
可変踏板幅金字塔関数
完成・金字塔数と完成・金字塔関数
前述の同じ進数の同じ桁数の扇数どうしの値を掛け合わせて得られる金字塔数は、n進数では、n-1桁の扇数の場合に、各桁の数値を高さと見なした場合、頂点の長さが1となり、完成(perfect)した金字塔の形に見えることがら、他の金字塔数と区別する場合には完成・金字塔数と呼び、完成金字塔数を求める関数Pを完成・金字塔数と呼ぶ事にしました。
完成・金字塔数を求める完成・金字塔関数の式を扇関数を利用して定義すると下記のようになります。
\( P(x, base = n) = A(x, n)^2 \)
金字塔関数の特長
引数が\(x = 0\)の場合には、全ての進数で0となります。
\(
P(0, base = n) = 0
\)
引数が\(x = 1\)の場合には、全ての進数で1となります。
\(
P(1, base = n) = 1
\)
可変頂上幅・金字塔数と可変頂上幅・金字塔関数
金字塔数の最上段である頂点の桁数を可変にできる関数を可変頂上幅・金字塔関数と呼ぶ事とします。
段数を\( x\)、 頂上の幅を\(v\)、進数の底\(base = n\)とする金字塔数を求める可変頂上幅金字塔関数\(V(x, v, base = n)\)をPythonで記述すると下記の関数となります。
\(V(x, v, base = n) = A(x, n) \times A(x+v-1, n)\)実際に10進数で可変頂上幅・金字塔関数で得られる値の例
\(V(0,2) = A(0) \times A(4) = 0 \times 0 = 11\)
\(V(0,3) = A(0) \times A(5) = 0 \times 0 = 111\)
\(V(1,1) = A(1) \times A(3) = 1 \times 111 = 1\)
\(V(1,2) = A(1) \times A(4) = 1 \times 1111 = 11\)
\(V(1,3) = A(1) \times A(5) = 1 \times 11111 = 111\)
\(V(2,1) = A(2) \times A(3) = 11 \times 111 = 121\)
\(V(2,2) = A(2) \times A(4) = 11 \times 1111 = 1221\)
\(V(2,3) = A(2) \times A(5) = 11 \times 11111 = 12221\)
\(V(3,1) = A(3) \times A(3) = 111 \times 111 = 12321\)
\(V(3,2) = A(3) \times A(4) = 111 \times 1111 = 123321\)
\(V(3,3) = A(3) \times A(5) = 111 \times 11111 = 1233321\)
可変頂上幅・金字塔数を求めるPythonのコード
def V(x, v=1, base=10): return A(x, base) * A(x+v-1, base)
可変頂上幅・金字塔関数と完成・金字塔関数との関係
可変頂上幅・点金字塔関数で、頂上幅vを1にすると、完成・金字塔関数の値が一致します。
\(V(x,1, base = n) = P(x, base = n)\)
可変頂上幅・金字塔関数と扇関数との関係
可変頂上幅・金字塔関数は引数を\(x = 1\)とした場合、扇関数と値が一致します。
\(
V(1, v, base = n) = A(v, base = n)
\)
可変踏板幅・金字塔数と可変踏板幅・金字塔関数
n進数の扇数と、nのw乗進数の扇数を掛け合わせる事で得られる数値です。
段数を\( x\)、 各段の踏板の幅を\(w\)、進数の底\(base = n\)とする可変踏板幅・金字塔数を求める可変踏板幅・金字塔関数\(W(x, w, base = n)\)を下記の式で表すことができます。
金字塔関数に、各段の桁が持つ値の個数を幅と見なし、引数wで幅の個数を制御できる引数を追加したものとなっています。
実際に10進数で可変踏板幅・金字塔関数で得られる値の例
\(W(0,2) = A(0 \times 2,10) \times A(0, 10^2) = 0 \times 0 = 0\)
\(W(0,3) = A(0 \times 3,10) \times A(0, 10^3) = 0 \times 0 = 0\)
\(W(1,1) = A(1 \times 1,10) \times A(1, 10^1) = 1 \times 1 = 1\)
\(W(1,2) = A(1 \times 2,10) \times A(1, 10^2) = 11 \times 1 = 11\)
\(W(1,3) = A(1 \times 3,10) \times A(1, 10^3) = 111 \times 1 = 111\)
\(W(2,1) = A(2 \times 1,10) \times A(2, 10^1) = 11 \times 11 = 121\)
\(W(2,2) = A(2 \times 2,10) \times A(2, 10^2) = 1111 \times 101 = 112211\)
\(W(2,3) = A(2 \times 3,10) \times A(2, 10^3) = 111111 \times 1001 = 111222111\)
\(W(3,1) = A(3 \times 1,10) \times A(3, 10^1) = 111 \times 111 = 12321\)
\(W(3,2) = A(3 \times 2,10) \times A(3, 10^2) = 111111 \times 10101 = 1122332211\)
\(W(3,3) = A(3 \times 3,10) \times A(3, 10^3) = 111111111 \times 1001001 = 1112223332221111\)
可変踏板幅・金字塔関数のPythonのコード
段数を\( x\)、 各段の踏板の幅を\(w\)、進数の底\(base = n\)とする可変幅金字塔数を求める可変踏板幅金字塔関数\(W(x, w, base = n)\)をPythonで記述すると下記の関数となります。
def W(x, w=1, base=10): return A(x*w, base) * A(x, base**w)
可変踏板幅・金字塔関数と完成・金字塔関数との関係
可変踏板幅・金字塔関数で、踏板の幅wを1にすると、完成・金字塔関数と値が一致します。
\(W(x,1, base = n) = P(x, base = n)\)
可変踏板幅・金字塔関数と扇関数との関係
可変踏板幅・金字塔関数は引数を\(x = 1\)とした場合、扇関数と値が一致します。
\(
W(1, w, base = n) = A(w, base = n)
\)

