Komputasi algoritma jika suatu angka adalah kelipatan dari 3

13

Ketika melakukan kalkulus mental, seseorang dapat melakukannya:

  • Dengan bilangan bulat k, jumlahkan semua digit (pada basis 10), dan jika hasilnya kelipatan 3, maka k adalah kelipatan 3.

Apakah Anda tahu ada algoritma yang bekerja sama tetapi beroperasi pada digit angka biner (bit)?

  • Pada awalnya, saya berpikir untuk menggunakan fungsi siap pakai dari bahasa saya mengkonversi integer ke ascii untuk melakukan konversi dari basis 2 ke basis 10, kemudian menerapkan trik kalkulus mental. Tapi tentu saja saya juga bisa mengkodekan konversi basis 2 ke 10 sendiri. Saya belum melakukannya, tapi saya akan mencobanya.

  • Kemudian saya memikirkan divisi euclidian di basis 2 ...

Namun saya bertanya-tanya apakah ada cara lain, algoritma.

Stephane Rolland
sumber
2
Anda mungkin menemukan itu menarik: Desain DFA menerima string biner yang dapat dibagi oleh angka 'n'
Grijesh Chauhan

Jawaban:

22

Pertimbangkan dua pengamatan berikut (dibiarkan sebagai latihan untuk pembaca):

  1. Kekuatan genap dua adalah 1 modulo 3.
  2. Kekuatan ganjil dari keduanya adalah -1 modulo 3.

Kami menyimpulkan bahwa angka (dalam biner) dapat dibagi oleh tiga jika dan hanya jika jumlah bit dalam posisi genap sama dengan jumlah bit dalam posisi ganjil modulo 3.

mhum
sumber
7
Ini seperti aturan untuk habis dibagi 11 dalam desimal.
Yuval Filmus
1
@YuvalFilmus: Tepat. Saya akan menambahkan latihan lain untuk pembaca tetapi memutuskan untuk tidak melakukannya.
mhum
3
OK, bagaimana dengan mencari tahu apakah angka yang ditulis dalam heksadesimal dapat dibagi dengan 17 (desimal)? Atau 15 (desimal)? ;-)
vonbrand
33

Bagaimana dengan otomat keadaan terbatas untuk pekerjaan itu?

masukkan deskripsi gambar di sini

Tentu saja sihir hanya perhitungan modulo 3. Menambahkan simbol balik tali x berarti "nilai biner" dari string pergi dari v a l ( x ) untuk x ke 2axval(x)x untuk x a . Alhasil dari state p dan simbol a kita pindah ke state 2 p + a mod 3 , untuk p { 0 , 1 , 22val(x)+axapa2p+amod3 Dan sebuah { 0 , 1 } . Catatan x { 0 , 1 } adalah string, di mana v a l ( x ) N adalah nilainya sebagai string biner.p{0,1,2}a{0,1}x{0,1}val(x)N

Hendrik Jan
sumber
1
Saya suka idenya, mari kita coba dengan 9. Saya memberi makan 1001 dalam bentuk biner. Bit pertama mengirim saya ke state1, lalu state2, lalu state1 lalu kembali ke state0. Jadi state0 adalah kelipatan dari 3. Dan kompleksitas algoritma adalah jumlah bit yang digunakan, tidak lebih. Itu mengagumkan !
Stephane Rolland
Apakah konsep ini dalam tautan terkait? Saya pikir ini lebih sederhana. geomathry.wordpress.com/2017/02/13/0-1-and-a-new-number
1
0¯0=0¯0¯1=1¯1¯0=2¯1¯1=0¯2¯0=1¯2¯1=2¯Θ,1,01,2,0
Jangan tentang pemrograman. Akankah hal ini lebih efisien di komputer ternary?
4

Dalam biner, angka 1, 100, 10000 (= 100 × 100), 1000000 (= 100 × 100 × 100) dll. Semua memberikan sisa yang sama setelah membaginya dengan 11 (tiga). Oleh karena itu jika kita membagi angka biner ke bagian-bagian dengan panjang genap , jumlah bagian-bagian tersebut memberikan sisa yang sama dengan angka aslinya.

(Saat memisahkan nomor, kami menambahkan nol sebanyak yang diperlukan di awal . Misalnya kami akan membagi 10111 ke grup 01,01,11 atau 0001.0111.)

Secara matematis, cukup bagi angka menjadi kelompok dua digit, lalu tambahkan grup; dan ulangi ini sampai hasil Anda menjadi 00 atau 11 = angka aslinya adalah kelipatan dari tiga; atau 01 atau 10 = angka aslinya bukan kelipatan dari tiga.

Untuk program komputer, menggunakan kelompok delapan atau enam belas atau tiga puluh dua bit mungkin lebih cepat untuk CPU Anda. Misalnya, jika penambahan delapan-bit paling cepat, buat saja jumlah semua byte, dan lagi, sampai hasilnya cocok menjadi satu byte. Kemudian gunakan satu instruksi untuk menentukan sisa setelah dibagi tiga.

(Catatan: Kami mengasumsikan bilangan bulat yang tidak ditandatangani di sini. Dengan nomor yang ditandatangani, perlu sedikit lebih banyak perhatian. Misalnya 129 adalah kelipatan 3, tetapi -127 tidak, meskipun bit 10000001 berarti untuk bekas sebagai byte yang tidak ditandatangani dan yang terakhir sebagai byte yang ditandatangani.)

Viliam Búr
sumber
0

Meskipun tidak spesifik biner, ketika ragu, pengurangan berulang selalu merupakan cara pasti untuk menghitung pembagian dengan sisa (dan dengan demikian jika angka adalah kelipatan dari 3).

Ya ampun
sumber
2
Pengurangan berulang adalah ide yang buruk. Pembagian dengan sisanya jauh lebih cepat.
Yuval Filmus
3
mungkin benar-benar sangat mahal di cpu, tetapi ini adalah algoritma yang berbeda :-) yang tidak pantas -1 :-(
Stephane Rolland