質問するログイン新規登録

回答編集履歴

2

追加説明

2021/02/03 01:42

投稿

ppaul
ppaul

スコア24672

answer CHANGED
@@ -49,4 +49,42 @@
49
49
  elif x&1==0 and y&1==0 and y!=0:
50
50
  TypeError: unsupported operand type(s) for &: 'float' and 'int'
51
51
  ```
52
- 4行目、つまり elif x&1==0 and y&1==0 and y!=0:のところで、float型とint型で&はできませんというエラーメッセージが出ています。これは理解できますか。
52
+ 4行目、つまり elif x&1==0 and y&1==0 and y!=0:のところで、float型とint型で&はできませんというエラーメッセージが出ています。これは理解できますか。
53
+
54
+ 自力で解決できたようなので、いくつかのサンプルを載せておきます。
55
+
56
+ syoutaro22さんのアルゴリズムですが、これは互減法のアルゴリズムに2だけ割るアルゴリズムを付け加えたものです。こういう発想はプロ的なのですが、syoutaro22さんは初心者ということですので、たまたま思いつけたということなのでしょう。一般的には、数字が小さいときには互減法は互除法より高速なのです。python3の場合は、64ビットを超えると整数の割り算が極端に遅くなるので、その場合も有効かもしれません。
57
+
58
+ 互減法は、割り算機能のついていない組み込み用の小さなCPUなどでも使います。
59
+ 互減法については[最大公約数をもっと高速に求める](http://lpha-z.hatenablog.com/entry/2019/03/03/231500)などを見てみてください。
60
+
61
+ ```python
62
+ def gcd(x, y):
63
+ if y==0:
64
+ return x
65
+ elif x < y:
66
+ return gcd(y, x) #こうやっておいたほうが間違いが少ない。
67
+ elif x&1==0 and y&1==0:
68
+ return 2*gcd(x//2, y//2)
69
+ elif x&1==0 and y&1==1:
70
+ return gcd(x//2, y)
71
+ elif x&1==1 and y&1==0:
72
+ return gcd(x, y//2)
73
+ elif x&1==1 and y&1==1:
74
+ return gcd(x-y, y) # 大きいほうから小さいほうを引く
75
+ else:
76
+ print('proguram error') # ここに来るならプログラムの間違い
77
+ raise(Exception)
78
+ ```
79
+ 一方、互除法でやるには、y_waiwaiさんが勧めていたようにやります。以下をご覧下さい。
80
+ ```python
81
+ def gcd(x, y):
82
+ if x < y:
83
+ return gcd(y, x)
84
+ elif y==0:
85
+ return x
86
+ elif x == x // y*y:
87
+ return y
88
+ else:
89
+ return gcd(x-y, y)
90
+ ```

1

修正

2021/02/03 01:42

投稿

ppaul
ppaul

スコア24672

answer CHANGED
@@ -6,8 +6,9 @@
6
6
  x,yどちらも奇のとき、gcd(x,y)→gcd((x,y)/2,y)
7
7
  という要領で計算します。
8
8
 
9
- これが間違っています。
9
+ ~~これが間違っています。
10
- まず、互除法をちゃんと理解しましょう。
10
+ まず、互除法をちゃんと理解しましょう。~~
11
+ gcd((x-y)/2,y)が正しいとのことなので、互除法はわかっていますね。
11
12
 
12
13
 
13
14
  **プログラムのデバッグについて**