質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

964閲覧

友愛数のコードを書いています。(初心者です)

nobita

総合スコア66

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/09/13 04:13

基本的なコード
for や if や list 、 while  程度のコードを使って友愛数を求めています。
現在書いたコードが下記のようなのですが、どうしてもうまくいきません。
重複してしまったり、友愛数でないものも入ってしまいます。
アドバイスをお願い致します。。

for a in range(2,15000): aaaa = [] aaa = 0 for aa in range(1,15000): if a == aa: break if a % aa == 0: aaa += aa aaaa.append(aaa) bbb = 0 bbbb = [] for b in aaaa: for bb in range(1,15000): if b == bb: break if b % bb == 0: bbb += bb bbbb.append(bbb) if a == bbb: print(f"{a}:{aaa}")

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

以前の質問で、約数を列挙するプログラムを書きましたよね。
それを利用してやれば少し見通しが良くなると思います。

Python

1amicable_numbers = [] 2for a in range(2, 15000): 3 a_divisors = aの約数のリスト 4 5 b = sum(a_divisors[:-1]) # 自らを除いた約数の総和 6 b_divisors = bの約数のリスト 7 8 if sum(b_divisors[:-1]) == a: 9 amicable_numbers.append((a, b))

とりあえずここまで書いてみましょう。
重複を排除するには集合を使えば良いですが、後からでもできます。

追記:
集合をいちいち使うのは社交数を意識してのことですが、
こと友愛数に限るならばStars1024さんの方法のように大小関係を見た方が良いかもです。

気になる事

  • 雑な命名

プログラミングの際には意味のある命名を心掛けましょう。
読みやすくなるだけでなく、思考も整理されます。

  • if, for, while縛り

関数を適宜作成するようにしましょう。
今回の場合、約数を列挙する部分は関数にした方が扱いやすいです。

  • 巨大なテスト

いきなり15000弱もループしたらデバッグしづらいです。
人手で検証できるレベルから始めましょう。

投稿2018/09/13 04:29

編集2018/09/13 05:12
LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nobita

2018/09/13 07:04

for a in range(2, 15000): a_divisors = aの約数のリスト     ↑に for文を追加して最終的に a_divisorsにaの約数のリストを追加できればいいってことですか?
nobita

2018/09/13 07:04

回答ありがとうございます。
LouiS0616

2018/09/13 07:07

どんな方法であろうと、a_divisorsにaの約数のリストが入っていれば良いです。 その部分は疑似コードだと思って読んでください。
nobita

2018/09/13 07:35 編集

''' total = [] for i in range(2,250): a_l =[] a = 0 for j in range(1,250): if i % j == 0: a += j a_l.append(j) print(a_l) '''
nobita

2018/09/13 07:31

上段部分はこんなかんじでしょうか?
LouiS0616

2018/09/13 07:40

それだと約数の和のリストを作っちゃってますね。 そういうアプローチも無いわけではないですが、疑似コードを実現しているかと問うなら答えはNOです。
nobita

2018/09/13 07:58

なるほど。 元の数値が 2なら 1と2が 追加されればいいんですか? [[1,2],[1,3],[1,2,4]] という感じに。
LouiS0616

2018/09/13 08:01

いえ、リストのリストは作らなくて良いです。 6があったら [1, 2, 3, 6] を取得できるようなコード片を考えます。
nobita

2018/09/13 08:13

辞書ってことですかね? {6:1,2,3,6}という。 すみません。レベル低くて・・・
LouiS0616

2018/09/13 08:22

その場合、全ての数の約数を列挙した辞書を作らなきゃならないですね。 もちろん自動的にも作れますが、メモリをかなり食いそうな予感がします。 穴埋め問題と一緒です。 分からない部分に当てはまるコードを考えるだけです。
nobita

2018/09/13 13:03

’’’ for a in range(2,1500): aaa = 0 for aa in range(1,a): if a == aa: break if a % aa == 0: aaa += aa bbb = 0 if aaa <= a: continue b = aaa for bb in range(1,b): if b == bb: break if b % bb == 0: bbb += bb if a == bbb: print(f"{a}:{aaa}") ’’’
nobita

2018/09/13 13:04

できました!!!! 試行錯誤しました ありがとうございました。「
LouiS0616

2018/09/13 13:23

解決したようで何よりです。 ただ、変数名に関しては再検討した方が良いでしょうね。
nobita

2018/09/15 10:24

遅れて申し訳ございません。 変数はわかりやすくするように気を付けます!!!! ありがとうございました。
guest

0

(I)自分自身以外の約数の和を求める関数を作る
約数の性質としてnの約数にiが含まれたらn / inの約数です。そのためループは2以上√n未満です。
.nが平方数の場合だけ約数の和sumにその平方根を加えましょう。

(II)for文で友愛数を求める
下にあるコードでif num2 == i and num1 < num2:とありますがそれぞれの意味は
(i)num2 == i 友愛数なら
(ii)num1 < num2 友愛数の一つの組が一つだけ表示されるように(例えば, (220,284) (284,220)などと
表示しされるのを (220,284)だけ表示されるようにする) 

です。

python

1import math 2 3def sum_divisor(n): 4 if n <= 1: 5 return 0 6 sum = 1 7 for i in range(2,int(math.sqrt(n))): 8 if n % i == 0: 9 sum += i 10 sum += n / i 11 if int(math.sqrt(n)) ** 2 == n: 12 sum += int(math.sqrt(n)) 13 return int(sum) 14 15for i in range(2,15000): 16 num1 = sum_divisor(i) 17 num2 = sum_divisor(num1) 18 if num2 == i and num1 < num2: 19 print(num1,num2) 20

<実行結果>
220 284
1184 1210
2620 2924
5020 5564
6232 6368
10744 10856
12285 14595

<追記>
.importを使わずに書く方法です。LouiS0616さんのご指摘のように平方根はn ** 0.5でできます。

python

1def sum_divisor(n): 2 if n <= 1: 3 return 0 4 sum = 1 5 for i in range(2,int(n ** 0.5)): 6 if n % i == 0: 7 sum += i 8 sum += n / i 9 10 if int(n ** 0.5) ** 2 == n: 11 sum += int(n ** 0.5) 12 return int(sum) 13 14for i in range(2,15000): 15 num1 = sum_divisor(i) 16 num2 = sum_divisor(num1) 17 if num2 == i and num1 < num2: 18 print(num1,num2)

<追記2>
処理速度は落ちますが、listを使った方法も一応載せておきます。

python

1def sum_divisors(n): 2 divisors = [] 3 for i in range(1,n): 4 if n % i == 0: 5 divisors.append(i) 6 sum = 0 7 for number in divisors: 8 sum += number 9 return sum 10 11for i in range(2,1500): 12 num1 = sum_divisors(i) 13 num2 = sum_divisors(num1) 14 if i == num2 and num1 < num2: 15 print(num1,num2)

投稿2018/09/13 04:39

編集2018/09/13 12:31
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nobita

2018/09/13 07:05

すごいです。 でもまだimport等は勉強してないので、使わずに作りたいんです。
退会済みユーザー

退会済みユーザー

2018/09/13 07:28 編集

importを使わずにやる方法を書きました。
LouiS0616

2018/09/13 07:22

@Stars1024 さん 内部実装の恩恵を受けられないかもしれませんが、n ** .5 で代替できます。
退会済みユーザー

退会済みユーザー

2018/09/13 07:28

@LouiS0616さんへ n ** 0.5で√nが表現できるのを忘れていました。おかげでimportなしで 処理速度も落ちずに書き換えることができました。ありがとうございます
nobita

2018/09/13 07:59

すごいです! ありがとうございます。
退会済みユーザー

退会済みユーザー

2018/09/13 12:33 編集

@nobitaさんへ 一応、listを使った方法も載せておきます。 あと、先ほど num1 != num2 and num1 < num2 と書きましたが num1 < num2 でカバーできるのでその部分を訂正しました。
nobita

2018/09/13 13:02

ありがとうございます。勉強になります(^^)/
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問