Pour vérifier si un nombre décimal est divisible par 7:
Effacez le dernier chiffre. Multipliez-le par 2 et soustrayez de ce qui reste. Si le résultat est divisible par 7, le nombre d'origine est divisible par 7.
(également décrit par exemple ici )
Cette règle est bonne pour le contrôle manuel de divisibilité. Par exemple:
2016 est-il divisible par 7?
Soustrayez
6*2
de 201; nous obtenons 189. Est-ce divisible par 7? Pour le vérifier, appliquons à nouveau la règle.Soustrayez
9*2
de 18; nous obtenons 0. Par conséquent, 2016 est divisible par 7.
Dans ce défi, vous devez appliquer cette règle jusqu'à ce que le statut de divisibilité soit évident , c'est-à-dire que le nombre ne dépasse pas 70 (cependant, voir ci-dessous pour plus de détails). Créez une fonction ou un programme complet.
Entrée : un entier positif; votre code doit prendre en charge des entrées jusqu'à 32767 (la prise en charge d'entiers de précision arbitraire est un bonus; voir ci-dessous).
Sortie : un entier (éventuellement négatif), non supérieur à 70, résultant de l'application de la règle de divisibilité par 7 zéro ou plusieurs fois.
Cas de test:
Input Output Alternative output
1 1
10 10 1
100 10 1
13 13 -5
42 42 0
2016 0
9 9
99 -9
9999 -3
12345 3
32767 28 -14
---------- Values below are only relevant for the bonus
700168844221 70 7
36893488147419103232 32 -1
231584178474632390847141970017375815706539969331281128078915168015826259279872 8
Lorsque deux sorties possibles sont spécifiées, l'un ou l'autre résultat est correct: le second correspond à l'application de la règle une fois de plus. Il est interdit d'appliquer la règle sur un numéro à un chiffre: si vous effacez le chiffre, il ne reste plus rien (pas 0).
Bonus : si votre algorithme
- Prend en charge les entiers de précision arbitraire
- Effectue un seul passage sur l'entrée
- A une complexité spatiale
o(n)
(c.-à-d. Inférieure àO(n)
) et - A une complexité temporelle
O(n)
,
où n
est le nombre de chiffres décimaux:
Soustrayez 50% du nombre d'octets de votre code.
Véritable bonus :
De plus, si votre algorithme lit l'entrée dans la direction normale, en commençant par le chiffre le plus significatif, soustrayez à nouveau 50% - votre score est de 25% de votre nombre d'octets (cela semble possible, mais je ne suis pas absolument sûr).
la source
1000000000000000000001
.long long
s ou un type équivalent intégré?Réponses:
Golfscript,
2722 octetsVous pouvez l'utiliser de cette façon:
Explication
5 octets économisés grâce à Dennis!
la source
@wizzwizz4
(@
puis mon nom d'utilisateur) au début (ou n'importe où dans) un commentaire.{...}{}if
partie en tant que{...}*
, ce qui appliquera simplement le bloc de code zéro une fois, selon la valeur poussée par>
. De plus, nous sommes autorisés à effectuer une autre itération (donc le remplacer70
par9
enregistre un octet), et je ne pense pas que vous ayez besoin de sauter le bloc avec;
.Haskell, 35 octets
Exemple d'utilisation:
until(<71)(\n->div n 10-2*mod n 10) 36893488147419103232
->32
.Rien à expliquer, c'est une implémentation directe de l'algorithme.
la source
Gelée, 11 octets
Essayez-le en ligne!
Comment ça marche
la source
Python 2, 38 octets
Essayez-le ici !
Approche récursive simple. Imprime x si son <70 applique autrement la règle de divisibilité et s'appelle avec le résultat.
la source
)
f=lambda x:x*(x<70)or f(x/10-x%10*2)
x*(x<70) != 0
comme la condition de fin. Si x arrive à 0 - comme c'est le cas avec 2016 - la condition de fin ne se produit jamais.Pyth, 13 octets
Essayez-le en ligne: démonstration ou suite de tests
Cela imprimera toutes les réponses alternatives.
Explication:
la source
Julia,
2726 octetsIl s'agit d'une fonction récursive qui accepte un entier et renvoie a
BigInt
. Si l'entrée est un grand nombre comme dans le dernier exemple, Julia le traite comme unBigInt
, donc aucune conversion manuelle n'est nécessaire.L'approche n'est qu'une implémentation simple de l'algorithme. Il produira les sorties alternatives. Prendre le module lors de la division par 10 donne le dernier chiffre et le quotient de la division entière par 10 donne tout sauf le dernier chiffre.
Enregistré un octet grâce à Dennis!
la source
70
par9
enregistre un octet.Pyth, 17 octets
Essayez-le ici!
Même approche récursive que dans ma réponse python . Définit un lambda
y
qui est appelé comme ceci:y12345
.Le compteur d'octets dans l'interpréteur en ligne affiche 19 octets parce que j'y ai ajouté l'appel lambda, vous pouvez donc simplement l'essayer en appuyant sur le bouton d'exécution.
Explication
la source
CJam - 19 octets
Version Do-while:
Essayez-le en ligne ou alors que la version # 1:
Essayez-le en ligne ou alors que la version # 2:
Essayez-le en ligne .
la source
Oracle SQL 11.2, 116 octets
Non golfé
la source
Haskell,
157192184167159147138 + 5 octets - 50% = 71,5 octetsO (1) espace, O (n) temps, passage unique!
Utilisez as
0![6,1,0,2]
pour appliquer la règle à 2016, c'est-à-dire transmettez-lui d'abord un nombre sous forme de flux avec le chiffre le moins significatif. De cette façon, il passera sur le nombre chiffre par chiffre, en appliquant la règle avec la complexité d'espace O (1).Le code non golfé est ici:
L'essentiel de la façon dont cela fonctionne est qu'il implémente un algorithme de soustraction chiffre par chiffre , mais tire parti du fait que chaque nombre à soustraire est au plus de 2 chiffres, et donc nous pouvons soustraire une quantité arbitraire de ces 1 - ou -2 chiffres à partir du chiffre principal (en plus de manger les chiffres les moins significatifs).
L'algorithme de soustraction est O (1) et ne stocke que la valeur d'emprunt actuelle. J'ai modifié cela pour ajouter le chiffre supplémentaire (soit 0 ou 1), et nous notons que cette valeur d'emprunt est limitée (dans la plage [-2,2], nous n'avons donc besoin que de 3 bits pour le stocker).
Les autres valeurs stockées en mémoire sont des variables temporaires représentant le nombre actuel à 2 chiffres à ajouter, une seule anticipation dans le flux et à appliquer une étape de l'algorithme de soustraction (c'est-à-dire qu'il faut deux chiffres et une valeur d'emprunt, et renvoie un chiffre et une nouvelle valeur d'emprunt).
Enfin, à la fin, il traite les deux derniers chiffres du flux à la fois pour renvoyer un numéro à un chiffre plutôt qu'une liste de chiffres.
NB La
sev
fonction dans la version non golfée fonctionnera sur unInteger
, le convertissant en forme de flux inversé.la source
Mod[18 - Quotient[n, 10] - 2*n, 21] - 18 + Quotient[n, 10]
fonctionne empiriquement pour n entre 10 et 99, mais devient plus compliqué avec plus de n chiffres ...0
lors de l'appel!
, par exemple comme une section(0!)
(+ une nouvelle ligne), c'est-à-dire +5 octets. De l'autre côté, vous pouvez raccourcir le premier pour faire correspondre les correspondances de!
àp![d]=
etp![d,e]=
. , Modèle d'utilisation protège également au lieu delet
:p!(d:e:f)|(b,a)<-quotRem(2*d)10,(q,r)<-h$e-a-p=(b+q)!(r:f)
.(0!)
sa propre ligne.(0!)
est la fonction que vous donnez comme réponse. Le0
est requis, mais n'a rien à voir avec l'entrée, vous ne pouvez donc pas l'externaliser à l'appelant. Bien sûr, vous pouvez également l'utiliserf x=0!x
, mais c'est plus long.GNU dc,
2015 octetsCeci définit mon premier (jamais) fonction continue,
F
. Il prend l'entrée en haut de la pile et laisse sa sortie en haut de la pile. Exemple d'utilisation:la source
Mathematica,
4744 octetsApproche récursive simple. Pourrait probablement être joué au golf plus loin.
la source
#0[{1,-2}.QuotientRemainder[#,10]]
enregistre un octet.R, 43 octets
Explication:
Exemples de cycles:
la source
JavaScript ES6, 38 octetsLes échecs avec
36893488147419103232
et en utilisant~~(1/10)
échoueront également pour700168844221
Tester:
la source
Fail
s ... 70 et 32f=n=>n>70?f((n-n%10*21)/10):n
est une version plus courte mais ne fonctionne toujours que jusqu'à2**56
.Mathematica, 33 octets
Cas de test
la source
Perl 5,
4746 octetsA dû utiliser
bigint
pour le dernier cas de test. (Il renvoie 20 sans)Pas vraiment sûr que ce soit un candidat pour le bonus, donc je ne l'ai pas pris en compte. (Je pense que oui, mais je ne suis pas vraiment habitué aux concepts)
Essayez-le ici!
la source
ES6, 108 octets
Fonctionne pour 2²⁵⁷ et 1000000000000000000001, mais pourrait utiliser davantage de golf.
la source
JavaScript ES6,
140142 octetsIl s'agit de véritables mathématiques de précision arbitraire, qui fonctionnent même sur le plus grand cas de test.
Cette fonction supprime récursivement le dernier chiffre de la chaîne, puis soustrait 2 * le dernier chiffre de la chaîne numérique restante en incrémentant de manière itérative le nombre de chiffres à appliquer au minuend jusqu'à ce que la différence soit positive. Ensuite, il ajoute cette différence à la fin de la chaîne avec des
0
s correctement remplis et s'appelle récursivement jusqu'à ce que sa valeur numérique soit inférieure ou égale à9
.la source
1000000000000000000001
.s.replace(/.$/,'-$&*2')
. Je n'ai pas d'idées évidentes pour le reste mais désolé.C #,
111104 octetsla source
Brain-Flak ,
368360 octetsEssayez-le en ligne!
Explication
Pour commencer, tout le code est dans une boucle qui s'exécute jusqu'à ce que le haut de la pile soit inférieur à zéro:
À l'intérieur de la boucle, nous exécutons l'algorithme divisible par sept:
Dupliquez le haut de la pile
Prenez le mod 10 du haut de la pile (dernier chiffre)
C'est un peu compliqué, mais il fait le reste de l'algorithme, je pourrais l'expliquer plus tard, mais je ne me souviens pas entièrement comment cela fonctionne:
la source
C, 56 octets - 75% = 14
Bien que cela ne donne pas exactement les mêmes chiffres que les cas de test, cela satisfait l'esprit de la question (et sans doute plus). Il identifie correctement les multiples exacts de 7 et donne le reste exact pour les autres nombres (car il n'utilise jamais de nombres négatifs).
Il n'y a pas de multiplication ou de division dans l'algorithme, seulement l'addition et la soustraction, et les chiffres sont traités en un seul passage de gauche à droite. Cela fonctionne comme suit, en commençant par 0 dans l'accumulateur:
L'étape "multiplier par trois" est écrite de manière
n-=-n-n
à enregistrer un octet et à éviter l'opérateur multiplier.Lorsque nous atteignons la fin, nous ne soustrayons pas les sept, donc le résultat sera compris entre 0 et 24; si vous voulez un module strict (0-7), remplacez-le
*c
par*c||n>6
dans lafor
condition de boucle.Il se qualifie pour le bonus amélioré, car il
Programme et résultats des tests
Version alternative
En voici une qui se reproduit (vous voudrez activer les optimisations du compilateur pour faire une transformation d'appel de queue ou vous pouvez déborder votre pile; j'ai utilisé
gcc -std=c89 -O3
):Appelez-le avec «0» comme deuxième argument.
Les deux versions calculent le reste-modulo-sept d'un nombre de 60 000 chiffres en moins de 50 millisecondes sur ma machine.
la source
PHP, 50 octets
utilise une sortie alternative; fonctionne jusqu'à
PHP_INT_MAX
version chaîne, fonctionne pour n'importe quel nombre (positif) (64 octets):
la source
Java, 133 octets
Je déteste la verbosité
Integer.parseInt
. Non golfé:la source