7の倍数の判定式を考えるプロセス
「7の倍数」でググると、いくつかの判定法が出てきます:
昔自分が考え付いたときの方法は、単純に、二桁目と三桁目以上と一桁目をわけて、数列をだしてそこから法則をみつけたものでした。以下の表は、7で割り切れる数の一桁目をa、二桁目をb、三桁目以上をcとしたときのaの最小の値の表です:
c\b | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 4 | 1 | 5 | 2 | 6 | 3 | 0 | 4 | 1 |
1 | 5 | 2 | 6 | 3 | 0 | 4 | 1 | 5 | 2 | 6 |
2 | 3 | 0 | 4 | .. | .. | .. | .. | .. | .. | .. |
3 | 1 | 5 | 2 | .. | ||||||
4 | 6 | 3 | 0 | .. | ||||||
5 | 4 | 1 | 5 | .. | ||||||
6 | 2 | 6 | 3 | .. | ||||||
7 | 0 | 4 | 1 | .. | ||||||
8 | 5 | 2 | 6 | .. | ||||||
9 | 3 | 0 | 4 | .. | ||||||
10 | 1 | 5 | 2 | .. | ||||||
.. | .. | .. | .. | .. |
こうしてみるとすぐ気がつきます。aは、bが1増えると3づつへっていき、cが1増えると2づつ減っていくのがわかります(0..6で循環するとして)。つまり、aと3b+2cの関係が一定になるわけです。
こここからごにょごにょ考えると、7の倍数は「a + 3b + 2cが7で割り切れる」、という関係が見つかりました。この式自体も7で割り切れることを判定するためのものなので、再帰的に適用すれば最終的に1桁に収まるわけだったりします。
この判定式をrubyでかくと
def seven?(n) return n % 7 == 0 if n < 10 a = n % 10 b = (n / 10) % 10 c = n / 100 seven?(a + 3 * b + 2 * c) end
チェック例のコード:
(0...100000).map{|i| seven?(i*7)}.all?
(0...100000).map{|i| if seven?(i) and i % 7 != 0 then false else true end}.all?
上は、7の倍数が判定式を満たすか、下は、7の倍数以外で判定式を満たすものがないか、をチェックしてます。
ただ、人間がふつうに考えるなら九九の7の段と70, 77, 84, 91, 98はすぐ区別がつくはずなので、「3桁目以降を二倍して、下二桁と足し合わせたもの、が7で割り切れるか」を繰り返す、つまり
def seven?(n) return n % 7 == 0 if n < 100 seven?(2 * (n / 100) + (n % 100)) end
で十分だったりするんですけれど。
おまけ: 証明
命題:
- 1) a + 10*b + 100*cが7の倍数なら、a + 3*b + 2*cは7の倍数である、かつ、
- 2) a + 10*b + 100*cが7の倍数でないなら、a + 3*b + 2*cは7の倍数でない
1) a + 10*b + 100*cが7の倍数
- → a + 10*b + 100*c = 7*x (xは整数)
- → a = 7*x - 10*b - 100*c
- → (これをa + 3*b + 2*cのaに代入)
- → (7*x - 10*b - 100*c) + 3*b + 2*c
- → = 7*x - 7*b - 98*c
- → = 7* (x - b - 14*c)
- → x, b, cが整数であるので、(x - b - 14*c)も整数である
- → よってa + 3*b + 2*c は7の倍数
(2の証明は対偶でも背理法でも可能。)
2a) 対偶: a + 3*b + 2*cは7の倍数なら、a + 10*b + 100*cが7の倍数である
- ほぼ1と同じやり方で証明成立
2b) 背理法: a + 10*b + 100*cは7の倍数でないとき、a + 3*b + 2*cが7の倍数である、が矛盾する
- → a + 10*b + 100*c = 7*x + r (x,rは整数、rは7の倍数ではない)
- → a + 3*b + 2*c = 7*y (yは整数)
- → (上の等式 - 下の等式)
- → 7*b + 98*c = 7*x - 7*y + r
- → 7*b + 98*c - 7*x + 7*y = r
- → 7 * (b + 14*c - x + y) = r
- → b,c,x,yは整数なので、(b + 14*c - x + y)は整数
- → よってrは7の倍数
- → 仮定(rは7の倍数ではない)と矛盾するので 2が成立
引いたとき、割るための数でくくれる式になるような式を作ればいいので、7以外の数にも応用できますね(有用性はないだろうけど):
- 2 => a % 2 == 0
- 3 => (a + b + c) % 3 == 0
- 4 => (a + 2b) % 4 == 0
- 5 => a % 5 == 0
- 6 => (a + 4b + 4c) % 6 == 0
- 7 => (a + 3b + 2c) % 7 == 0
- 8 => (a + 2b + 4c) % 8 == 0
- 9 => (a + b + c) % 9 == 0
追記: (b - 2*a) % 7 == 0なら(a+10*b) は7の倍数
検索で一番上に出てくるページ
では、一桁目を二倍して、それ以上から引いたものが7で割り切れると7の倍数という判定方法を使ってます。引き算が得意ならこちらもよいかもしれません。
これは
- - 2*a + b
でありa + 10*b = 7*x とおくと、この式は21*b-14*xとなって7で割り切れ(1)、-2*a+b=7yとおくと、a + 10*bは、21*a+70yとなって7で割り切れるため(2a)正しい判定式と証明できます。
ちなみに、命題の(1)は満たすけど、(2)が満たさない例として、4の倍数の判定式としての、一桁目の二倍が4の倍数(2*a % 4 == 0)かどうか、があります。
a + 10*b = 4*xとすると、2*aは、4x - 20*bとなり、4で割り切れ(1)を満たしますが、2*a = 4*yとおいたとき、a + 10*bは2*y + 10*bとなってしまい、yしだいで4で割り切れない状況がでてきます。よって(2)を満たさないため、2*aが4の倍数の判定式としてふさわしくない、と証明できます。
いいかえれば、4の倍数なら一桁目を二倍にしたものは必ず4の倍数になるけれど、一桁目を二倍にしたからといって4の倍数とは限らないよ、ということに過ぎません。