数値が3の倍数である場合に計算するアルゴリズム


13

暗算を行うとき、次のことができます。

  • 整数kが与えられ、すべての桁数(10を底とする)を合計します。結果が3の倍数である場合、kは3の倍数になります。

同様に機能するが、2進数(ビット)で動作するアルゴリズムを知っていますか?

  • 最初は、整数をASCIIに変換する言語の既製の関数を使用して、基数2から基数10への変換を実行してから、精神計算のトリックを適用することを考えていました。ただし、もちろん、ベース変換2から10を自分でエンコードすることもできます。まだやっていませんが、試してみます。

  • 次に、ベース2のユークリッド分割について考えました...

しかし、他の手段、アルゴリズムがあるのだろうか。


回答:


22

次の2つの観察事項を検討します(読者への演習として残します)。

  1. 2の偶数乗は1モジュロ3です。
  2. 2の奇数のべき乗は-1モジュロ3です。

偶数位置のビットの合計が3を法とする奇数位置のビットの合計と等しい場合にのみ、(バイナリの)数値は3で割り切れると結論付けます。


7
これは、10進数で11で割り切れる規則に似ています。
ユヴァルフィルマス

1
@YuvalFilmus:正確に。読者のために別の演習を追加するつもりでしたが、それに反対しました。
ムム

3
では、16進数で書かれた数値が17(10進数)で割り切れるかどうかを調べるのはどうでしょうか。それとも15(10進数)ですか?;-)
フォンブランド

33

ジョブの有限状態オートマトンはどうですか?

ここに画像の説明を入力してください

もちろん魔法だけで計算モジュロ3.シンボルを追加しているの背後にある文字列、文字列の「バイナリ値」はから行く意味ためののため。従って状態から及びシンボル私達が状態に移行用と。注意は文字列で、wherasはバイナリ文字列としての値です。、X 、V L X X 2 V L X + A X 、P 2 、P + MOD 3 のp { 0 1 2 } { 0 1 } のx { 0 1 } * V L X Naxval(x)x2val(x)+axapa2p+amod3p{0,1,2}a{0,1}x{0,1}val(x)N


1
私はこのアイデアが好きです。9で試してみましょう。1001をバイナリでフィードします。最初のビットは、state1、state2、state1、state0の順に送ります。したがって、state0は3の倍数です。そして、アルゴリズムの複雑さは使用されるビット数であり、それ以上のものはありません。それは素晴らしいです !
ステファンローランド

リンクのこの概念は関連していますか?もっとシンプルだと思います。geomathry.wordpress.com/2017/02/13/0-1-and-a-new-number

1
@WaqarAhmadはい、関連していて、単純ではありません。説明のように、有限オートマトンの遷移を使用してL2R評価を記述することもできます。遷移は、、、、、、ます。ここには3つの状態があるため、状態の3つのシンボルが必要です。シンボルはそれぞれ法とする数値の評価であり、L2R評価の最初のシンボルは「状態」です。ディスカッションが必要な場合は、サイトで新しい質問を開始することをお勧めします!ˉ 0 1= ˉ 1 ˉ 1 0= ˉ 2 ˉ 1 1= ˉ 0 ˉ 2 0= ˉ 1 ˉ 2 1= ˉ 2 Θ101200¯0=0¯0¯1=1¯1¯0=2¯1¯1=0¯2¯0=1¯2¯1=2¯Θ,1,01,2,0
ヘンドリックヤン

プログラミングについてではありません。このことは、ターナリコンピューターでより効率的になりますか?

4

2進数では、数字1、100、10000(= 100×100)、1000000(= 100×100×100)などはすべて、11(3)で除算した後、同じ剰余を与えます。したがって、2進数を偶数の長さの部分に分割する場合、その部分の合計は元の数と同じ剰余になります。

(数値を分割するとき、必要なだけゼロを先頭に追加します。たとえば、10111をグループ01,01,11または0001,0111に分割します。)

数学的には、数値を2桁のグループに分割してから、グループを追加します。結果が00または11 =元の数が3の倍数になるまでこれを繰り返します。または01または10 =元の数は3の倍数ではありませんでした。

コンピュータプログラムの場合、8ビット、16ビット、または32ビットのグループを使用すると、CPU が高速になる場合があります。たとえば、8ビットの加算が最も速い場合、結果が1バイトに収まるまで、すべてのバイトの合計を作成します。次に、1つの命令を使用して、3で割った後の残りを特定します。

(注:ここでは符号なし整数を想定してます。符号付き数値では、もう少し注意が必要です。たとえば、129は3の倍数ですが、-127はそうではありませんが、ビット10000001は前者を符号なしバイトとして、後者は符号付きバイトとして。)


0

バイナリ固有ではありませんが、疑わしい場合、繰り返しの減算は常に剰余除算を計算する確実な方法です(したがって、数値が3の倍数である場合)。


2
繰り返しの減算は悪い考えです。剰余による除算ははるかに高速です。
ユヴァルフィルマス

3
おそらく本当にCPUでコストがかかりますが、異なるアルゴリズムです:-) -1に値しません:
ステファン・ローランド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.