Déterminer si un entier est divisible par 3

20

Votre objectif est de déterminer si un nombre est divisible par 3 sans utiliser de conditions. L'entrée sera un nombre non signé de 8 bits compris entre 0 et 255. Créativité encouragée!

Vous êtes UNIQUEMENT autorisé à utiliser

  • L' égalité / inégalité ( ==, !=, >, <, >=, <=)

  • Arithmétique ( +, -, x)

  • Opérateurs logiques ( !pas, &&et, || ou)

  • Opérateurs de bits ( ~non, &et, |ou, ^xor, <<, >>, >>>gauche arithmétiques et logiques et décalages à droite)

  • Constantes (ce serait mieux si vous gardiez ces petites)

  • Affectation variable

Sortie 0si faux, 1si vrai.

Les règles standard de golf à code atomique s'appliquent. Si vous avez des questions, veuillez les laisser dans les commentaires. Exemples de méthodes ici . Un jeton est l'un des éléments ci-dessus à l'exclusion des constantes et des variables.

qwr
la source
@GregHewgill Ma faute de frappe, elle devrait être un nombre de 8 bits.
qwr
2
Sommes-nous uniquement autorisés à utiliser les opérateurs ci-dessus? Sinon, modulo rendrait cela trop facile.
Jwosty
Et la recherche de table?
Greg Hewgill
3
Pouvez-vous clarifier ce que vous entendez par sans condition? Est-ce limité aux instructions IF ou s'applique-t-il également à des choses comme les boucles?
Ruslan
1
@Ruslan Vous êtes uniquement autorisé à utiliser ce qui précède.
qwr

Réponses:

31

C - 2 jetons

int div3(int x) {
    return x * 0xAAAAAAAB <= x;
}

Semble fonctionner jusqu'à 2 31 -1.

Crédits à zalgo("nhahtdh")pour l'idée inverse multiplicative.

aditsu
la source
1
+1. A été un peu déconcerté par le <=fonctionnement, et s'est rappelé que 0xAAAAAAAB est considéré comme du unsigned inttype, donc le résultat de la multiplication n'est pas signé.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
Les opérateurs d'inégalité @DigitalTrauma sont autorisés, non interdits
aditsu
@aditsu Oups! J'ai besoin de lire plus attentivement parfois! +1 bonne réponse!
Digital Trauma
@aditsu, désolé je suis noob, comment ça marche exactement?
Kartik_Koro
2
@Kartik_Koro 0xAAAAAAAB * 3 == 1 en raison d'un débordement, donc pour tout int x, x * 0xAAAAAAAB * 3 == x. De plus, y * 3 a des valeurs différentes pour différents y, donc y = x * 0xAAAAAAAB doit être le seul y tel que y * 3 == x. Si x est un multiple de 3, alors y doit être x / 3, sinon il doit fonctionner par débordement. Un moyen simple de vérifier est de comparer y avec x. Voir aussi en.wikipedia.org/wiki/Modular_multiplicative_inverse
aditsu
17

Python, 3 2 jetons

Solution de force brute, mais ça marche.

0x9249249249249249249249249249249249249249249249249249249249249249>>x&1

Merci à Howard pour la réduction de 1 jeton.

Greg Hewgill
la source
Hou la la! Votre solution est probablement la plus courte (3 jetons), mais je veux également encourager d'autres réponses.
qwr
11
Il y a même une solution jeton 2: 0x9......>>x&1.
Howard
6

C - 5 4 (?) Jetons

int div3_m2(uint32_t n) {
    return n == 3 * (n * 0xAAAAAAABull >> 33);
}

Fonctionne pour tout numéro 32 bits non signé .

Ce code utilise le modulo inverse multiplicatif 2 32 d'un diviseur pour convertir l'opération de division en opération de multiplication.

Éditer

Ma solution (postée 2 minutes après) a le même esprit que la solution aditsu. Nous lui remercions d'avoir utilisé== améliore ma solution d'un jeton.

Référence

n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
la source
1
C'est incroyable. Je connaissais les nombres magiques grâce à la fameuse astuce inverse squareroot, mais je ne savais pas qu'il pouvait être utilisé pour un diviseur arbitraire. C'est Bull: P
qwr
Oui, 0xAAAAAAAB = (2 ^ 33 + 1) / 3 et 171 = (2 ^ 9 + 1) / 3. J'ai choisi la plus petite constante qui fait l'affaire. Hmm, en fait, il semble également fonctionner avec 86 = (2 ^ 8 + 2) / 3
aditsu
Rats, même 43 = (2 ^ 7 + 1) / 3 œuvres, je ne sais pas comment je l'ai raté. Modifié maintenant.
aditsu
4

Jetons C - 15 (?)

int div3_m1(unsigned int n) {
    n = (n & 0xf) + (n >> 4);
    n = (n & 0x3) + (n >> 2);
    n = (n & 0x3) + (n >> 2);
    return n == 0 || n == 3;
}

Depuis 4 ≡ 1 (mod 3), nous avons 4 n ≡ 1 (mod 3). La règle de sommation des chiffres ne se limite pas à la sommation des chiffres, mais nous permet également de décomposer arbitrairement le nombre en séquences de chiffres et de les additionner tous tout en conservant la congruence.

Un exemple en base 10, diviseur = 9:

1234 ≡ 12 + 34 ≡ 1 + 2 + 3 + 4 ≡ 123 + 4 ≡ 1 (mod 9)

Toutes les instructions du programme utilisent cette propriété. Il peut en fait être simplifié en une boucle qui exécute l'instruction n = (n & 0x3) + (n >> 2);jusqu'à ce que n < 4, car l'instruction décompose simplement le nombre en base 4 au chiffre le moins significatif et additionne les 2 parties.

n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
la source
+1: intéressant, cela fonctionne pour n jusqu'à 512 (en fait n = 590), mais je ne sais pas trop pourquoi.
Paul R
@PaulR: Cela ne fonctionnera pas pour les plus grands nombres en raison du transport (notez que j'ai utilisé l'addition dans le calcul). Notez également les lignes répétées.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
Oui, je ne sais tout simplement pas pourquoi cela fonctionne pour des valeurs de 9 bits, car il ne semble tester que 8 bits?
Paul R
pour les nombres de 9 bits après le premier ajout, il devient au plus 5 bits, après le premier n = (n & 0x3) + (n >> 2);le résultat est réduit à 3 bits et la répétition l'a fait rester seulement 2 bits stackoverflow.com/a/3421654/995714
phuclv
1
oh j'ai fait une erreur. Un nombre à 5 bits + un nombre à 4 bits peut donner un nombre à 6 bits. Mais si n <= 588, l'addition des 4 premiers bits et des 2 derniers bits de ce nombre à 6 bits produit une somme de seulement 4 bits. Une fois encore, cela ajoute un nombre de 2 bits. 589 et 590 résultent en 3 bits dans la dernière somme mais accessoirement ils ne sont pas divisibles par 3 donc le résultat est correct
phuclv
2

Python (2 jetons?)

1&66166908135609254527754848576393090201868562666080322308261476575950359794249L>>x

Ou

1&0x9249249249249249249249249249249249249249249249249249249249249249L>>x

Ou

1&0b1001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001>>x
ɐɔıʇǝɥʇuʎs
la source
2
Duplicate of Howard's comment
aditsu
@aditsu ... Les grands esprits pensent de même? Je jure que je n'ai pas vu ça avant de poster ça.
ɐɔıʇǝɥʇuʎs
2

JavaScript - 3 jetons

function div3(n) {
    var a = n * 0.3333333333333333;
    return (a | 0) == a;
}

Cela abuse du fait que l'utilisation d'opérateurs au niveau du bit sur un nombre le tronque en un entier en JavaScript.

Tyilo
la source
Devrait être 4 jetons: =, *, |,==
n̴̖̋h̷͉a̷̭̿h̸̡̅ẗ̵̨d̷̰ĥ̷̳
1
Je ne pense pas que l'affectation de variable compte comme un jeton.
Tyilo
1

C - 4 jetons

int div3(int x) {
    return ((x * 43) >> 7) * 3 == x;
}

Fonctionne jusqu'à 383.

Version précédente (constantes plus grandes):

int div3(int x) {
    return ((x * 171) >> 9) * 3 == x;
}

Fonctionne jusqu'à 1535

aditsu
la source
1

bash - ???

Je ne sais pas comment noter cela.

seq 0 85 | awk '{print $1 * 3}' | grep -w [number] | wc -l

par exemple

$ seq 0 85 | awk '{print $1 * 3}' | grep -w 11 | wc -l
0

$ seq 0 85 | awk '{print $1 * 3}' | grep -w 12 | wc -l
1

$seq 0 85 | awk '{print $1 * 3}' | grep -w 254 | wc -l
0

$seq 0 85 | awk '{print $1 * 3}' | grep -w 255 | wc -l
1

la source
1

Befunge 93-5 jetons

Corrigé - division supprimée.

v      @._1.@
         \   
         0   
         +   
         3   
>&>3-:0\`|   
  ^      <   

Obtient une entrée, continue de soustraire 3 jusqu'à ce qu'il soit inférieur à 0, dirige le pointeur vers le haut ('|'), puis ajoute 3. Si la valeur est 0, le pointeur se déplace vers la droite (" 1. @" sort "1"), sinon se déplace vers la gauche ("@. " affiche "0"). '@' termine le programme.

AndoDaan
la source
1

Lot - 7 jetons

je pense

@echo off
for /L %%a in (0,3,%1) do set a=%%a
if %a%==%1 echo 1

Renvoie 1si le nombre donné (comme stdin) est divisible par trois.

dégrader
la source
Les boucles sont-elles autorisées?
sergiol
1

Rubis, 6 (?) Jetons

Je ne sais vraiment pas comment compter les jetons. OP, pouvez-vous me marquer?

Je pense qu'il est 6 ... 1, 0, 0, *, 255,x

Notez que la *multiplication n'est pas un entier.

def div3(x)
  ([1,0,0]*255)[x]
end
Pas que Charles
la source
Un jeton au sens du PO ne serait-il qu'un des éléments énumérés ci-dessus dans la question?
C5H8NNaO4
@ C5H8NNaO4 Et alors? 0?
Pas que Charles
@ C5H8NNaO4 peut-être 4 pour les constantes?
Pas que Charles
1

Python 0

J'ai posté eariler mais j'ai utilisé des conditionnels. Voici à utiliser pas de conditions et pas de jetons, juste des mots clés

def g(x): return ([[lambda : g(sum(int(y) for y in list(str(x)))),lambda: 0][[False,True].index(x in[0,1,2,4,5,7,8])], lambda: 1][[False,True].index((lambda y: y in[3,6,9])(x))])()

utilise l'astuce que plusieurs des 3 ont des chiffres qui s'ajoutent à 3

Edit: Suppression de lambda inutile

def g(x):return([[lambda: g(sum(int(y) for y in list(str(x)))),lambda:0][[False,True].index(x in[0,1,2,4,5,7,8])], lambda:1][[False,True].index(x in[3,6,9])])()

Edit: Golfé plus loin (117 caractères) toujours pas de jetons

exec"g=`x:(((`:g(sum(int(y)for y in str(x)),`:0)[x in[0,1,2,4,5,7,8]],`:1)[x in[3,6,9]])()".replace('`','lambda ')

Accès direct tué pour le plus astucieux getitem de Python à 132 car.

exec"g={0}x:((({0}:g(sum(int(y)for y in str(x))),{0}:0{1}0,1,2,4,5,7,8]),{0}:1{1}3,6,9]))()".format('lambda ',').__getitem__(x in[')

http://www.codeskulptor.org/#user34_uUl7SwOBJb_0.py

Dylan Madisetti
la source
L'accès aux baies []n'est cependant pas autorisé.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
Il est? Après ces règles, codegolf.stackexchange.com/tags/atomic-code-golf/info
Dylan Madisetti
Eh bien, la question n'utilise pas la règle dans le wiki du tag. La question a des restrictions sur les opérations autorisées. Notez le mot only.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Eh bien, c'est une bonne chose que le python ait un attribut natif pour cela aussi
Dylan Madisetti
0

Python - 25 jetons

Pour commencer, j'ai une longue solution qui est une implémentation de l'une des réponses dans le lien dans mon premier post. nest entrée.

a = (n>>7)-((n&64)>>6)+((n&32)>>5)-((n&16)>>4)+((n&8)>>3)-((n&4)>>2)+((n&2)>>1)-(n&1)
print(a==0 or a==3)

orest équivalent à ||.

qwr
la source
0

JavaScript - 3 jetons

Testez-le sur la console de votre navigateur:

a = prompt().split('');
sum = 0;

do {
  sum = a.reduce(function(p, c) {
     return parseInt(p) + parseInt(c); 
  });

  a = sum.toString().split('');

} while(a.length > 1)

alert([3, 6, 9].indexOf(+sum) > -1)
William Barbosa
la source
Comment êtes-vous arriver à cette conclusion? Je compte environ 37 jetons.
nyuszika7h
"Un jeton est l'un des éléments ci-dessus à l'exclusion des constantes et des variables". Comment avez-vous compté 37?
William Barbosa
1
Oh je vois. L'OP semble en désaccord avec la page d'informations de atomic-code-golf .
nyuszika7h
En fait, maintenant je ne sais pas si j'ai raison ou non. Mon score serait de 70+ selon le violon de golf à code atomique.
William Barbosa
1
Le problème ne concerne pas le nombre de jetons, mais les opérations que vous utilisez. Je ne pense pas que toString, parseInt, boucles, tableaux, etc. soient autorisés.
aditsu
0

JavaScript
n'est pas sûr du jeton #

function mod3 (i) { return {'undefined':'100','0':'0'}[[0][i]][i.toString (3).split('').pop ()]}

ou si la sortie pour 0 est autorisée à 1;

function mod3 (i) { return '100'[i.toString (3).split('').pop ()]}

C5H8NNaO4
la source
2
Je dois dire que je ne sais pas quelles règles s'appliquent à ce défi. Les appels de fonction et les accès aux propriétés sont-ils autorisés?
C5H8NNaO4
0

Tcl , 83 octets

proc T n {while \$n>9 {set n [expr [join [split $n ""] +]]};expr {$n in {0 3 6 9}}}

Essayez-le en ligne!

sergiol
la source
Outgolf échoué: 96 octets proc T n {set n [expr [join [split [expr [join [split $n ""] +]] ""] +]];expr {$n in {0 3 6 9}}} Essayez-le en ligne!
sergiol
Un autre échec: ** 87 octets ** proc T n {expr {[expr [join [split [expr [join [split $n ""] +]] ""] +]] in {0 3 6 9}}} Essayez-le en ligne!
sergiol