37 votes

Vérifiez si un nombre est divisible par 3

J'ai besoin de trouver si un nombre est divisible par 3 sans utiliser % , / o * . Le conseil donné était d'utiliser atoi() fonction. Une idée de comment faire ?

48 votes

C'est une question d'entretien plutôt stupide, n'est-ce pas ? Elle ne teste pas vraiment vos connaissances en programmation, mais plutôt si vous connaissez ou non des propriétés obscures sur les nombres...

5 votes

Une autre de ces questions d'entretien stupides... cela n'a rien à voir avec les compétences en programmation. Cela prouverait simplement que vous savez (peut-être par hasard) que la somme des chiffres doit être divisible par 3 (ce que je ne savais pas/ne me rappelais pas, honnêtement ;) ).

9 votes

Ça pourrait aussi être une question d'examen de mon professeur d'université. Ce type n'a jamais travaillé sur de vrais projets mais a pensé que de telles questions refléteraient le monde réel. ha.

70voto

MSalters Points 74024

Les réponses actuelles se concentrent toutes sur les chiffres décimaux, en appliquant la méthode "additionner tous les chiffres et voir si cela divise par 3". Cette astuce fonctionne également en hexadécimal ; par exemple, 0x12 peut être divisé par 3 car 0x1 + 0x2 = 0x3. Et la "conversion" en hexadécimal est beaucoup plus facile que la conversion en décimal.

Pseudo-code :

int reduce(int i) {
  if (i > 0x10)
    return reduce((i >> 4) + (i & 0x0F)); // Reduces 0x102 to 0x12 to 0x3.
  else
   return i; // Done.
}
bool isDiv3(int i) {
  i = reduce(i);
  return i==0 || i==3 || i==6 || i==9 || i==0xC || i == 0xF;
}

[modifier] Inspiré de R, une version plus rapide (O log log N) :

int reduce(unsigned i) {
  if (i >= 6)
    return reduce((i >> 2) + (i & 0x03));
  else
   return i; // Done.
}
bool isDiv3(unsigned  i) {
  // Do a few big shifts first before recursing.
  i = (i >> 16) + (i & 0xFFFF);
  i = (i >> 8) + (i & 0xFF);
  i = (i >> 4) + (i & 0xF);
  // Because of additive overflow, it's possible that i > 0x10 here. No big deal.
  i = reduce(i);
  return i==0 || i==3;
}

7 votes

Par ailleurs, en base N, l'astuce fonctionne pour tous les facteurs de (N-1). Par exemple, en hexagone, cela fonctionne également pour 5 ("divisible par 5" est une autre question d'entretien similaire).

0 votes

Cela ne fonctionne pas pour les négatifs, mais ajouter une condition à isDiv3 serait facile.

0 votes

+1 pour avoir signalé que vous pouvez faire cela avec l'hexagone. Je ne l'avais pas réalisé et c'est vraiment utile. Merci aussi à @MSalters d'avoir mentionné comment cela s'étend à d'autres valeurs de N ; il pourrait être utile avec d'autres valeurs de puissance 2 de N avec plus de facteurs.

59voto

Forrest Voight Points 1966

Soustrayez 3 jusqu'à ce que vous ayez

a) le résultat 0 - le nombre était divisible par 3

b) obtenir un nombre inférieur à 0 - le nombre n'était pas divisible

-- version éditée pour corriger les problèmes notés

while n > 0:
    n -= 3
while n < 0:
    n += 3
return n == 0

0 votes

Si le nombre est signé, vous devez ajouter deux conditions supplémentaires pour que la méthode se termine lorsque x est négatif et lorsque x est 0.

7 votes

Ce n'est pas très efficace ; c'est (n), alors que la solution de @tdammers est (log n)

0 votes

Pas, cependant, la plus efficace (puisque la solution atoi utilise secrètement la division et le mod)

32voto

tdammers Points 14202

Divisez le nombre en chiffres. Additionnez les chiffres. Répétez jusqu'à ce qu'il ne reste qu'un seul chiffre. Si ce chiffre est 3, 6 ou 9, le nombre est divisible par 3 (et n'oubliez pas de traiter le 0 comme un cas particulier).

7 votes

Il pourrait y avoir une violation des exigences en utilisant ce processus qui n'est pas d'utiliser %, /, * pour obtenir des chiffres à partir du nombre que nous devons utiliser. mieux de convertir le nombre entier dans la chaîne et obtenir chaque caractère et le couvrir dans le nombre de nouveau et les ajouter et trouver le reslut.

1 votes

"pour obtenir les chiffres d'un nombre, nous devons les utiliser" non, ce n'est pas vrai

0 votes

C'est là où je voulais en venir. Vous convertissez le nombre en une chaîne, vous la divisez en chiffres et vous traitez chaque chiffre comme un nombre compris entre 0 et 9.

17voto

pelotom Points 14817

Bien que la technique consistant à convertir en une chaîne de caractères puis à additionner les chiffres décimaux soit élégante, elle nécessite une division ou est inefficace dans l'étape de conversion en une chaîne de caractères. Existe-t-il un moyen d'appliquer l'idée directement à un nombre binaire, sans avoir à le convertir d'abord en une chaîne de chiffres décimaux ?

Il s'avère que oui :

Étant donné un nombre binaire, la somme de ses bits impairs moins la somme de ses bits pairs est divisible par 3 si le nombre original était divisible par 3.

Par exemple, prenons le nombre 3726, qui est divisible par 3. En binaire, cela donne 111010001110 . Nous prenons donc les chiffres impairs, en commençant par la droite et en allant vers la gauche, qui sont [1, 1, 0, 1, 1, 1] ; la somme de ceux-ci est de 5 . Les bits pairs sont [0, 1, 0, 0, 0, 1] ; la somme de ceux-ci est 2 . 5 - 2 = 3, ce qui nous permet de conclure que le nombre original est divisible par 3.

4 votes

Cette opération (addition des chiffres/pits pairs et impairs) est à nouveau un cas particulier d'une astuce générale, consistant à vérifier en base N si un nombre peut être divisé par (N+1).

0 votes

@MSalters : Pouvez-vous donner une référence à la preuve de cette affirmation ?

1 votes

@user1599964 : En base N, (N+1) s'écrit comme 11. Donc, la propriété est valable pour 11 * 1. Si et seulement si la propriété est valable pour le nombre x, elle est également valable pour x+11. C'est trivial s'il n'y a pas de débordement (par exemple, 100 + 11 = 111, quelle que soit la base). Avec un débordement, le débordement se fait d'un chiffre impair vers un chiffre pair ou d'un chiffre pair vers un chiffre impair, ce qui préserve l'équilibre. Le débordement déduit N du chiffre qui déborde et ajoute +1 au chiffre supérieur. Comme nous prenons la différence des sommes des chiffres pairs et impairs, le débordement modifie la différence par N+1, ce qui n'affecte pas la divisibilité par N+1.

6voto

polygenelubricants Points 136838

La question de l'entretien vous demande essentiellement de trouver (ou d'avoir déjà connu) la règle de divisibilité en abrégé avec 3 comme diviseur.

L'une des règles de divisibilité pour 3 est la suivante :

Prenez n'importe quel nombre et additionnez chaque chiffre du nombre. Prenez ensuite cette somme et déterminez si elle est divisible par 3 (en répétant la même procédure si nécessaire). Si le nombre final est divisible par 3, alors le nombre initial est divisible par 3.

Exemple :

16,499,205,854,376
=> 1+6+4+9+9+2+0+5+8+5+4+3+7+6 sums to 69
=> 6 + 9 = 15 => 1 + 5 = 6, which is clearly divisible by 3.

Voir aussi

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X