Algorithmes calculant si un nombre est multiple de 3

13

En faisant du calcul mental, on peut faire:

  • Étant donné un entier k, additionnez tous les chiffres (en base 10), et si le résultat est un multiple de 3, alors k est un multiple de 3.

Connaissez-vous un algorithme fonctionnant de manière similaire mais fonctionnant sur des chiffres binaires (bits)?

  • Au début, je pensais utiliser les fonctions prêtes à l'emploi de mon langage pour convertir un entier en ascii pour effectuer la conversion de la base 2 à la base 10, puis appliquer l'astuce du calcul mental. Mais bien sûr, je pourrais également encoder moi-même la conversion de base 2 en 10. Je ne l'ai pas encore fait, mais je vais essayer.

  • Ensuite, j'ai pensé à la division euclidienne en base 2 ...

Cependant, je me demande s'il existe d'autres moyens, des algorithmes.

Stéphane Rolland
la source
2
Vous pouvez le trouver intéressant: Conception DFA acceptant les chaînes binaires divisibles par un nombre 'n'
Grijesh Chauhan

Réponses:

22

Considérez les deux observations suivantes (laissées en exercice au lecteur):

  1. Les puissances paires de deux sont 1 modulo 3.
  2. Les puissances impaires de deux sont -1 modulo 3.

Nous concluons qu'un nombre (en binaire) est divisible par trois si et seulement si la somme des bits dans les positions paires est égale à la somme des bits dans les positions impaires modulo 3.

mhum
la source
7
C'est comme la règle pour être divisible par 11 en décimal.
Yuval Filmus
1
@YuvalFilmus: Précisément. J'allais ajouter un autre exercice pour le lecteur mais j'ai décidé de ne pas le faire.
mhum
3
OK, que diriez-vous de savoir si un nombre écrit en hexadécimal est divisible par 17 (décimal)? Ou 15 (décimal) d'ailleurs? ;-)
vonbrand
33

Qu'en est-il d'un automate à états finis pour le travail?

entrez la description de l'image ici

Bien sûr, la magie n'est que le calcul modulo 3. Ajouter le symbole derrière la chaîne x signifie que la "valeur binaire" de la chaîne va de v a l ( x ) pour x à 2 v a l ( x ) + a pour x a . Par conséquent, de l'état p et du symbole a, nous passons à l'état 2 p + a mod 3 , pour p { 0 , 1 , 2axval(x)x2val(x)+axapa2p+amod3 et un { 0 , 1 } . Remarque x { 0 , 1 } est une chaîne, alors que v a l ( x ) N est sa valeur sous forme de chaîne binaire.p{0,1,2}a{0,1}x{0,1}val(x)N

Hendrik Jan
la source
1
J'aime l'idée, essayons avec 9. Je nourris 1001 en binaire. Le premier bit m'envoie à l'état1, puis à l'état2, puis à l'état1 puis à l'état0. Donc, state0 est multiple de 3. Et la complexité de l'algorithme est le nombre de bits utilisés, rien de plus. C'est génial!
Stephane Rolland
Ce concept dans le lien est-il lié? Je pense que c'est plus simple. 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,0 sont les évaluations des nombres modulo 1,2,0
Ne faites pas de programmation. Cette chose sera-t-elle plus efficace dans un ordinateur ternaire?
4

En binaire, les nombres 1, 100, 10000 (= 100 × 100), 1000000 (= 100 × 100 × 100) etc. donnent tous le même reste après la division par 11 (trois). Par conséquent, si nous divisons un nombre binaire en parties de longueur paire , la somme des parties donne le même reste que le nombre d'origine.

(Lors de la division du nombre, nous ajoutons autant de zéros que nécessaire au début . Par exemple, nous diviserions 10111 en groupes 01,01,11 ou 0001,0111.)

Mathématiquement, il suffit de diviser le nombre en groupes de deux chiffres, puis d'ajouter les groupes; et répétez cette opération jusqu'à ce que votre résultat devienne 00 ou 11 = le nombre d'origine était un multiple de trois; ou 01 ou 10 = le nombre d'origine n'était pas un multiple de trois.

Pour un programme informatique, l'utilisation de groupes de huit ou seize ou trente-deux bits peut être plus rapide pour votre processeur. Par exemple, si l'ajout de huit bits est le plus rapide, faites simplement une somme de tous les octets, et encore, jusqu'à ce que le résultat tienne dans un octet. Utilisez ensuite une instruction pour déterminer le reste après avoir divisé par trois.

(Remarque: nous supposons ici des entiers non signés . Avec un nombre signé, il a besoin d'un peu plus d'attention. Par exemple, 129 est un multiple de 3, mais -127 ne l'est pas, bien que les bits 10000001 signifient pour ancien comme octet non signé et ce dernier sous forme d'octet signé.)

Viliam Búr
la source
0

Bien qu'elle ne soit pas spécifique aux binaires, en cas de doute, la soustraction répétée est toujours un moyen infaillible de calculer la division avec le reste (et donc si un nombre est un multiple de 3).

jmite
la source
2
La soustraction répétée est une mauvaise idée. La division avec le reste est beaucoup plus rapide.
Yuval Filmus
3
probablement vraiment très coûteux en cpu, mais c'est un algorithme différent :-) qui ne mérite pas -1 :-(
Stephane Rolland