FreeBASIC マニュアルのトップに戻る

FreeBASIC 友愛数 素数 完全数

目次→フォーラム→FreeBASIC→補足Amicable pairs←オリジナル・サイト

友愛数 素数 完全数 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

←リンク元に戻る プログラム開発関連に戻る


友愛数を表示

 NHK のドラマ10で、「この声をきみに」という番組が有りました。
 ドラマの中で「数学的媚薬」(作:アレックス・ゴールト/訳:畔柳和代)という実話?が紹介されていて、その中に「友愛数」を計算するところが有りました。
https://40exchange.com/konokoewokimini6-24104

 友愛数とは
https://ja.wikipedia.org/wiki/%E5%8F%8B%E6%84%9B%E6%95%B0

 これに触発されて、プログラム集ロゼッタ・コード
で公開されている FreeBASIC で「友愛数」を計算するプログラムを紹介します。

(関連で、素数完全数 および 過剰数、不足数、完全数の分類 のプログラムも紹介しています。)

' version 04-10-2016
' compile with: fbc -s console
' replaced the function with 2 FOR NEXT loops

' エラトステネスのふるいを使う
' http://rosettacode.org/wiki/Amicable_pairs#using_.22Sieve_of_Erathosthenes.22_style

#Include "vbcompat.bi"   'Now を使えるようにする

'#Define maxNo 20000      ' test for pairs below maxNo
#Define maxNo 500000      ' 以下のペア・テストの最大数
#Define maxNo_1 maxNo -1
 
Dim As String u_str = String(Len(Str(maxNo))+1,"#")
Dim As UInteger n, f
Dim Shared As UInteger sum(maxNo_1)
Dim TimeStart As Double
Dim TimeEnd As Double
 
TimeStart = Now         ' 開始時刻を変数に格納します。

For n = 2 To maxNo_1
  sum(n) = 1
Next
 
For n = 2 To maxNo_1 \ 2
  For f  = n * 2 To maxNo_1 Step n
    sum(f) += n
  Next
Next
 
Print
Print Using "以下は、最大数" & u_str & " の友愛数の対 :"; maxNo
Print
 
For n = 1 To maxNo_1 -1
  f = Sum(n)
  If f <= n OrElse f > maxNo Then Continue For
  If f = sum(n) AndAlso n = sum(f) Then
    Print Using u_str & " と" & u_str ; n; f
  End If
Next

Print
TimeEnd = Now           ' 終了時刻を変数に格納します。
Print  " 処理時間は、" ;
Print Format (TimeEnd - TimeStart, "hh:mm:ss")

' empty keyboard buffer
While InKey <> "" : Wend
Print : Print "何かキーを押すとプログラムを終了します"
Sleep
End

 参考1:1から20,000,000までの友愛数の一覧
http://www.vaxasoftware.com/doc_eduen/mat/numamigos_eng.pdf
 参考2:1000万以下の完全数一覧表
http://www.hyogo-c.ed.jp/~meihoku-hs/club/astronomy-yui.html
このページの先頭に戻る↑ トップページに戻る

エラトステネスのふるいで素数を表示

 エラトステネスのふるいとは
https://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%A9%E3%83%88%E3%82%B9%E3%83%86%E3%83%8D%E3%82%B9%E3%81%AE%E7%AF%A9

 素数一覧表(1000万まで…)
http://www.ysr.net.it-chiba.ac.jp/yashiro/sosu/

 上の 友愛数 と関連して、プログラム集ロゼッタ・コード
で公開されている「エラトステネスのふるい」の FreeBASIC プログラムを紹介します。

' FB 1.05.0
' http://rosettacode.org/wiki/Sieve_of_Eratosthenes

Sub sieve(n As Integer)
  If n < 2 Then Return
  Dim a(2 To n) As Integer
  For i As Integer = 2 To n : a(i) = i : Next
  Dim As Integer p = 2, q
  
  ' 対応する配列要素を 0 に設定して非素数をマークする
  Do
    For j As Integer = p * p To n Step p
      a(j) = 0
    Next j
    ' 'p' の後に配列内の次の非ゼロ要素を探します。
    q = 0
    For j As Integer = p + 1 To Sqr(n)
      If a(j) <> 0 Then
        q = j
        Exit For
      End If
    Next j    
    If q = 0 Then Exit Do
    p = q
  Loop
 
  ' 残りの非ゼロの数字、すなわち素数を表示
  For i As Integer = 2 To n
    If a(i) <> 0 Then
      Print Using "########"; a(i);      
    End If
  Next
  Print
End Sub
 
Print "10,000までの素数は :"
Print
Dim As Double t1=Timer,t2
sieve(10000)
t2=Timer
Print
Print t2 - t1
Print "何かキーを押すと終了します。"
Sleep

以下は FreeBASIC 掲示版で dodicat さんが公開しているバージョンです。
'prime numbers searcher in QB
'https://www.freebasic.net/forum/viewtopic.php?f=8&t=27799
'by dodicat ≫ Jan 18, 2020 16:01 

Sub generateprimes(primes() As Integer,nmax As Integer)
    ReDim primes(1 To nmax)
   Var np = 0
    Dim As Integer i, k
    For k = 2 To nmax
        If primes(k) = 0 Then
            np += 1
            primes(np) = k
            For i = 2*k To nmax Step k
                primes(i) = 1
            Next i
        End If
    Next k
    ReDim Preserve primes(1 To np)
End Sub

Dim As Double t1=Timer,t2
ReDim As Integer p()
generateprimes(p(),2000000)
t2=Timer

'For n As Long=1 To 20
'    Print p(n)
'Next
'
'Print ". . ."
'Print ". . ."
'
'For n As Long=UBound(p)-20 To UBound(p)
'    Print p(n)
'Next

For n As Long=1 To 1229
    Print p(n),
Next

Print
Print t2-t1

Sleep
このページの先頭に戻る↑ トップページに戻る

完全数

'Perfect numbers
'http://rosettacode.org/wiki/Perfect_numbers#FreeBASIC

' FB 1.05.0 Win64

#Include "vbcompat.bi"   'Now を使えるようにする

Dim TimeStart As Double
Dim TimeEnd As Double

Function isPerfect(n As Integer) As Boolean
   If n < 2 Then Return FALSE
   If n Mod 2 = 1 Then Return FALSE '' 奇数は完全数でないと仮定できます
   Dim As Integer sum = 1, q
   For i As Integer = 2 To Sqr(n)
     If n Mod i = 0 Then
       sum += i
       q = n \ i
       If q > i Then sum += q
     End If
   Next 
   Return n = sum
End Function
 
TimeStart = Now         ' 開始時刻を変数に格納します。

Print "最初の5つの完全数は : "
For i As Integer = 2 To 33550336
  If isPerfect(i) Then Print i; " ";
Next

Print
Print
TimeEnd = Now           ' 終了時刻を変数に格納します。
Print  " 処理時間は、" ;
Print Format (TimeEnd - TimeStart, "hh:mm:ss")

Print
Print "何かキー入力でプログラム終了"
Sleep
このページの先頭に戻る↑ トップページに戻る

過剰数、不足数、完全数の分類

'Abundant, deficient and perfect number classifications
'過剰数、不足数、完全数の分類
'(自然数について、その数以外の約数〈1 を含む〉の和と、もとの数を大小比較する)
'http://rosettacode.org/wiki/Abundant,_deficient_and_perfect_number_classifications#FreeBASIC

' FreeBASIC v1.05.0 win64
 
#Include "vbcompat.bi"   'Now を使えるようにする 

Function SumProperDivisors(number As Integer) As Integer
  If number < 2 Then Return 0
  Dim sum As Integer = 0
  For i As Integer = 1 To number \ 2
    If number Mod i = 0 Then sum += i
  Next
  Return sum
End Function
 
Dim As Integer sum, deficient, perfect, abundant
Dim TimeStart As Double
Dim TimeEnd As Double

Print "1から20,000までの完全数は、以下の通りです : "
'完全数は、小さい順に 6, 28, 496, 8128, 33550336, 8589869056, 

TimeStart = Now         ' 開始時刻を変数に格納します。

For n As Integer = 1 To 20000
'For n As Integer = 1 To 40000000
  If n Mod 10000000 = 0 Then 
     Print "カウンター" ; n ;   
     TimeEnd = Now           ' 終了時刻を変数に格納します。
     Print  " 処理時間は、" ;
     Print Format (TimeEnd - TimeStart, "hh:mm:ss")
  ElseIf n Mod 1000000 = 0 Then
   Print "カウンター" ; n ;
     TimeEnd = Now           ' 終了時刻を変数に格納します。
     Print  " 処理時間は、" ;
     Print Format (TimeEnd - TimeStart, "hh:mm:ss")
  End If 

  sum = SumProperDivisors(n)
  If sum < n Then
    deficient += 1
  ElseIf sum = n Then
    perfect += 1
    Print n
  Else
    abundant += 1
  EndIf
Next

Print
Print "1から20,000までの数の分類は、以下の通りです : "
Print
'不足数、輸数◆その数自身を除く全ての約数の和がその数自身よりも小さな整数
Print "不足数 = "; deficient

'完全数◆自分自身を除く正の約数の和に等しくなる自然数
Print "完全数 = "; perfect

'過剰数、豊数◆その数自身を除く全ての約数の和がその数自身よりも大きな整数
Print "過剰数 = "; abundant
Print
Print "何かキーを押すとプログラムを終了します"
Sleep
End

 注:繰り返し数を 40,000,000 にしてみたのですが、処理時間がかかりすぎるので、中断しました。

1から20,000までの完全数は、以下の通りです :
 6
 28
 496
 8128
カウンター 1000000 処理時間は、00:11:02
カウンター 2000000 処理時間は、00:43:52
カウンター 3000000 処理時間は、01:37:49
カウンター 4000000 処理時間は、02:53:22

 
補足 に戻る
←リンク元に戻る プログラム開発関連に戻る
ページ歴史:2017-11-13 作成:2017-11-13
日本語翻訳:WATANABE Makoto

ホームページのトップに戻る

表示-非営利-継承