回答編集履歴
2
追加説明
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
修正
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
|
**プログラムのデバッグについて**
|