Excel VBA 数学教室ではアフィリエイトプログラムを利用して商品を紹介しています。

【VBA】完全数の探索

【VBA】完全数の探索

ある自然数 $N$ が与えられたとき、その約数の個数を $T(N)$ という関数で表すことにします。たとえば 12 の約数は 1, 2, 3, 4, 6, 12 の計 6 個なので、
\[T(12)=6\]
となります。このような計算をさせるユーザー定義関数 CDIVISOR のプログラムは次のようになります(頭文字の C は Count の略、Divisor は約数です)。

'[VBA]約数の個数を求める関数

'エラー値を代入するため戻り値はVariant
'(関数名のあとにデータ型を宣言しない)
Function CDIVISOR(n As Long, Optional t As Boolean = False)

  Dim k As Long, m As Long

  m = n

  'オプション引数がTrueのときは
  'カウント上限値を1つ減らして
  'n自身を約数としてカウントしない

  If t = True Then
    m = n - 1
  End If

  Select Case n

    '指定引数nが0または負数ならばエラー
    Case Is <= 0
      CDIVISOR = CVErr(xlErrNA)

    Case Else
      '1から順にnを割り切れるかどうか判定して
      '約数であるものだけカウントする
      For k = 1 To m
        If n Mod k = 0 Then
          s = s + 1
        End If
      Next k
      CDIVISOR = s

  End Select

End Function

CDIVISOR() をワークシートで使用するときはセルに

=CDIVISOR(N [,N自身を個数に含めるか否か])

という形式で入力します。N には自然数を指定してください。オプション引数に False または 0 を指定すると N 自身を約数に含めてカウントし、True または 1 を指定すると N 自身を個数から除きます。N = 12 で試してみましょう。

=CDIVISOR(12)

と入力すると、12 自身を含めた約数の個数「6」が返ります。

=CDIVISOR(12,1)

と入力すると、12 自身を除いた約数の個数「5」が返ります。

ある自然数 $N$ が与えられたとき、その約数の総和を $S(N)$ という関数で表すことにします。たとえば 12 の約数は 1, 2, 3, 4, 6, 12 なので、
\[S(12)=1+2+3+4+6+12=28\]
となります。このような計算をさせるユーザー定義関数 SDIVISOR のコードを載せておきます(頭文字の S は Sum の略、Divisor は約数です)。

'[VBA]約数の総和を求める関数

Function SDIVISOR(n As Long, Optional t As Boolean = False)

  Dim k As Long, m As Long
  m = n

  'オプション引数がTrueのときは
  'カウント上限を1つ減らして約数和からn自身を除く
  If t = True Then
    m = n - 1
  End If

  Select Case n

  '指定引数nが0または負数ならばエラー
  Case Is <= 0
    SDIVISOR = CVErr(xlErrNA)

  Case Else
    '1から順にnを割り切れるかどうか判定して約数だけsに加える
    For k = 1 To m
      If n Mod k = 0 Then
        s = s + k
      End If
    Next k
    SDIVISOR = s

 End Select

End Function

SDIVISOR() をワークシートで使用するときは

=SDIVISOR(N [,N自身を加えるか否か])

と入力します。N には自然数を指定してください。オプション引数に False または 0 を指定すると N 自身を含めて和を計算し、True または 1 を指定すると N 自身を除いた和を計算します(後述するように完全数を調べるときは True を指定します)。N = 12 で試してみましょう。

=SDIVISOR(12)

と入力すると、12 自身を含めた約数の総和「28」が返ります。

=SDIVISOR(12,1)

と入力すると、12 自身を除いた約数の個数「16」が返ります。

$S(a)=2a$ が成り立つとき、すなわち $a$ 以外の約数和が $a$ に等しいとき、$a$ を完全数(perfect number)とよびます。たとえば 6 の約数は 1, 2, 3, 6 であり、6 自身を除いた約数の和は
\[1+2+3=6\]
となるので 6 は完全数です。完全数はとても珍しい数です。

SDIVISOR関数を使うと、その数字が完全数であるかどうかを判定することができます。たとえば

=SDIVISOR(28,1)

と入力すると「28」が返ってくるので 28 は完全数です。判定を自動化しましょう。SDIVISOR() を呼びだして完全数を見つけるマクロを載せておきます。

'[VBA]完全数の探索

Sub Search_Perfect()

  Dim k As Long

  For k = 1 To 10000
    If k = SDIVISOR(k, 1) Then
      Debug.Print k;
    End If
  Next k

End Sub

Search_Perfect() を実行すると 10000 までの数について判定を行い、「6 28 496 8128」という 4 個の完全数を見つけ出します。

エクセルや数学に関するコメントをお寄せください