Étant donné un nombre premier P
supérieur à 10
, votre programme ou fonction doit comprendre sa règle de divisibilité x
, définie comme l'entier avec la plus petite valeur absolue qui donne un multiple du nombre d'origine lorsqu'il est multiplié par le dernier chiffre du nombre premier et ajouté au reste de l'original premier.
Exemple
Étant donné une entrée 31
, le dernier chiffre est 1
et le reste du nombre est 3
. Ainsi, votre programme doit trouver l'entier x
avec une valeur absolue minimale telle qu'un 1*x + 3
multiple de 31
. Dans ce cas, x=-3
fonctionne, donc le programme ou la fonction reviendrait -3
.
Étant donné une entrée 1000003
, le dernier chiffre est 3
et le reste du nombre est 100000
. Ainsi, votre programme trouverait x=300001
car 3*300001+100000 = 1000003
qui est un multiple de 1000003
.
Contexte mathématique
La valeur de x
peut être utilisée comme test de divisibilité. Si un nombre N
est divisible par P
, alors l'ajout de x
fois le dernier chiffre de N
au reste de N
donnera un multiple de P
si et seulement si N
est divisible par P
en premier lieu.
Pour P=11
, on obtient x=-1
, ce qui équivaut à la règle de divisibilité bien connue pour 11
: un nombre est divisible en 11
alternant la différence de ses chiffres est divisible par 11
.
Règles
- La sortie peut être sous n'importe quelle forme qui code clairement à la fois le signe et la valeur de la sortie.
- L'amorce d'entrée sera comprise entre 10 et 2 ^ 30.
- Vous n'avez pas besoin de gérer si l'entrée n'est pas un nombre premier ou n'est pas dans la plage.
- Vous n'avez pas besoin de gérer si les deux
x
et-x
sont des sorties valides (cela ne devrait pas se produire). - La force brute est autorisée, mais des solutions plus créatives sont appréciées.
- C'est du code-golf , donc le code le plus court dans chaque langue gagne! Ne laissez pas les réponses dans les langues de golf vous décourager de poster dans d'autres langues.
Cas de test
Input Output
11 -1
13 4
17 -5
19 2
23 7
29 3
31 -3
37 -11
41 -4
43 13
47 -14
53 16
59 6
61 -6
67 -20
71 -7
73 22
79 8
83 25
89 9
97 -29
101 -10
103 31
107 -32
109 11
113 34
127 -38
131 -13
1000003 300001
2000003 600001
2999999 300000
9999991 -999999
la source
x
en valeur absolue où10*x-1
est divisible par l'entrée.(3 / (n % 5 * 2 - 5) * n + 1) / 10
et(n % 5 * 2 - 5^2) * n / 10 + 1
sont en mesure de trouver une valeur absolue minimale pour quelque chose comme ça? Ma première intuition aurait été de calculer le plus petit commun multiple en utilisant le plus grand diviseur commun calculé avec l'algorithme d'Euclide.x
, l'ajouter et toujours obtenir un nombre divisible parn
. Si nous multiplions ensuite le nouveau nombre par 10 et soustrayons le nombre d'origine, il reste divisible parn
. Le commentaire de xnor découle alors d'une algèbre. L'étape suivante consiste à réorganiser la formule afin qu'elle donnex
en termes den
: x =(k*n+1)/10
. Nous voulons que le plus petit absoluex
si nous voulons donc le plus petit absoluk
, et cela doit être selon l' une-3
,-1
,1
ou3
(selon len
dernier chiffre de) qui fait exactement la division.Réponses:
JavaScript (ES6),
322523 octets3/(n%5*2-5)
serait écrit9/n(mod -10)
si j'avais accès à une division modulo équilibrée. Edit: sauvé 2 octets grâce à @EgorSkriptunoffla source
n=>((n%10*2%14-3)*n+1)/10
parn=>(3/(n%5*2-5)*n+1)/10
Python 2 , 27 octets
Essayez-le en ligne!
Les opérations se font de gauche à droite:
(((n%5)*2)-5)^2
.J'ai utilisé mon forceur arithmétique pour trouver l'expression
n%5*2-5^2
à exécuter{1:-1,3:3,2:-3,4:1}[k]
, en prenant l'inverse négatif d'un résidu mod 5 dans la plage[-2..2]
.la source
3/(n%5*2-5)
est la même longueur que(n%5*2-5^2)
.)n%5*2-6^3
. Je n'ai regardé que la longueur de l'expression sans parens, alors qu'il3/(n%5*2-5)
y a deux caractères de plus mais économise sur les parens externes en raison de la priorité. La recherche d'expressions de cette longueur devrait prendre un certain temps. Ce cas d'utilisation suggère une option pour trouver uniquement les expressions qui peuvent être utilisées dans un contexte donné via leur opération la plus externe ayant une priorité suffisamment élevée.Gelée ,
dix8 octetsEssayez-le en ligne!
Explications
la source
Brachylog , 14 octets
Essayez-le en ligne!
la source
Python 2 ,
695453 octetsEdit: -15 octets grâce à @ Mr.Xcoder
Modifier: -1 octet en utilisant la récursivité
Essayez-le en ligne!
la source
Python 2 ,
31 2927 octetsEssayez-le en ligne!
la source
Japt ,
169 octetsBeaucoup trop d'octets enregistrés grâce à une observation de @xnor
Testez-le en ligne!Cela peut prendre quelques secondes sur des entrées plus importantes.
Explication
la source
Java 8,
2321 octetsPort de la réponse JavaScrip (ES6) de @Neil , mais -2 octets grâce à @Nevay raison d'un plancher implicite d'entiers.
Essayez-le ici.
la source
n->3/(n%5*2-5)*++n/10
Pyke , 12 octets
Essayez-le ici!
la source
Pyth , 14 octets
Essayez-le ici.
la source
Python 2 ,
4443 octets(44 barré est toujours 44.) Merci à Fireflame241 pour avoir sauvé un octet!
Essayez-le en ligne!
Il y a exactement un nombre entre
0
etP-1
qui est l'inverse de10
. Mais si cet inverseu
se trouve être supérieur àP/2
, il(u-P)
est également un inverse et a une valeur absolue inférieure àu
. Il s'avère donc que nous recherchons vraiment le nombre uniquex
entre-P/2
etP/2
qui est l'inverse de10
.Le code ci-dessus fait exactement cela, en commençant à (l'étage de)
P/2
et en descendant jusqu'à ce qu'un inverse soit atteint. Cela doit se produire pour un certain nombre supérieur à-P/2
tantP
qu'un nombre premier supérieur à10
. Plus précisément, il se terminera si et seulement siP
est coprime à10
.Edit: Il s'avère que cela
x
est garanti entre-P/3
etP/3
, donc la version actuelle commence àP/3
et descend de là. Voir la section intitulée Amélioré lié pour une explication à ce sujet.Explication mathématique
Il n'était pas immédiatement évident pour moi pourquoi le test de divisibilité fonctionnait. Voici une explication, au cas où quelqu'un d'autre se demanderait.
Soit
P
un nombre premier supérieur à10
dont le dernier chiffre estb
. DoncP = 10a + b
où
a > 0
, et0 <= b < 10
. En faitb
est soit1
,3
,7
ou9
, parce qu'une prime supérieure à la10
fin de l' indispensable dans l' un de ces chiffres.Supposons maintenant
bx + a = 0 (mod P)
. alorsa = -bx (mod P)
10a + b = 10(-bx) + b (mod P)
0 = 10(-bx) + b (mod P)
0 = b(1 - 10x) (mod P)
Puisque
P
est premier, les entiersmod P
sont un domaine intégral . Alors soitb = 0 (mod P)
, soit1 - 10x = 0 (mod P)
.Nous savons
0 <= b < 10 < P
, donc sib = 0 (mod P)
alorsb = 0
. Mais nous avons ditb
est soit1
,3
,7
ou9
, il en est ainsi impossible. Donc1 - 10x = 0 (mod P)
, donc10x = 1 (mod P)
. En d'autres termes,x
est l'inverse de10
, moduloP
.Supposons maintenant que
N
c'est un entier non négatif dont le dernier chiffre estd
,N = 10c + d.
Nous avons donc une chaîne d'instructions équivalentes:10c + d = 0 (mod P)
<==> 10xc + dx = 0 (mod P)
<==> c + dx = 0 (mod P)
QED.
Utilité?
Je me demandais également si le test de divisibilité (donné
N = 10c + d
, remplacéN
pardx + c
) serait réellement productif dans la pratique. Ou du moins, est-il remplacé de manière fiableN
par un nombre inférieur àN
(en valeur absolue)?Supposons
N = 10c + d
oùc >= 0
et0 <= d < 10
. Par conséquent10c = N - d <= N
. Par l'inégalité du triangle,|c + dx| <= |c| + |dx| = c + d|x| <= N/10 + d|x|
< N/10 + 10|x| <= N/10 + 10P/2 = N/10 + 5P
Donc si
5P <= 9N/10
, alors|c + dx| < N
.En particulier, si
N >= 6P
, alors|c + dx| < N
. Ainsi, étant donné queP
nous commençons par le calcul2P
,3P
...,6P
ainsi quex
. Ensuite , étant donnéN
, nous courons le test de divisibilité à plusieurs reprises jusqu'à ce qu'on atteigne un nombre inférieur ou égal à6P
, et vérifier si le résultat est l' un des numéros0
,P
,2P
, ...,6P
.(Bien sûr, chaque fois que nous atteignons un nombre négatif, nous le remplaçons par sa valeur absolue, ce qui est bien car
q
est divisible parP
si et seulement si(-q)
est.)Limite améliorée
J'ai remarqué que cela
|x|/P
ne semblait jamais être proche1/2
. En fait, il semblait que c'était toujours moins que1/3
... ou à y regarder de plus près, c'était toujours très proche de l'un1/10
ou de l' autre3/10
. Le plus gros jamais obtenu semblait être4/13
(ce qui arrive quandP=13
etx=4
). Pourquoi serait-ce?Soit
u
un entier et supposons que10u = kP + 1
pour un entierk
, il enu
soit de l'inverse de10
, moduloP
. Ensuite, nous savons également quek
c'est relativement premier10
, cark(-P)
est équivalent à1
modulo10
.Maintenant, nous savons que les inverses de
10
moduloP
diffèrent tous par des multiples deP
, nous pouvons donc prendre l'entieru
et soit ajouter ou soustraire des multiples deP
à volonté, et le résultat sera toujours toujours un inverse de10
moduloP
. Supposons que nous choisissons de soustraireP
deu
: nous obtenons10(u - P) = 10u - 10P = kP + 1 - 10P
10(u - P) = (k - 10)P + 1
En d'autres termes, une diminution (respectivement une augmentation)
u
deP
correspond à une diminution (une augmentation)k
de10
. Nous souhaitons ajouter / soustraire des multiples deP
deu
jusqu'à ce que le côté gauche soit minimisé en valeur absolue; mais le côté gauche est minimisé exactement lorsque le côté droit est minimisé, et nous voulons donc ajouter / soustraire10
dek
jusqu'à ce que le côté droit soit minimisé en valeur absolue.Mais nous savons que cela se produira quand
k
est entre-5
et5
, et donc (depuisk
est relativement premier10
) ce moyenk
est soit-3
,-1
,1
ou3
. (C'est le contenu du commentaire de @ Neil sous le PO. Merci, Neil! )Ainsi , quand
|u|
est réduite au minimum (c. -àu=x
), nous auronsx/P = u/P = k/10 + 1/(10P)
, oùk
est soit-3
,-1
,1
ou3
. Par conséquent|x|/P <= 3/10 + 1/(10P)
. De manière équivalente,|x| <= (3P + 1)/10
.De plus, cette inégalité est stricte chez
P=11
, car chezP=11
nous nous avonsx=-1
etk=-1
. Le plus petitP
pour lequel l'égalité est valable estP=13
(oùx=4
etk=3
).Par conséquent, le plus grand
|x|/P
jamais obtenu est3/10 + 1/(10*13)
, parce queP=13
c'est le premier nombre premier pour lequel nous avonsk=3
, et parmi ceux aveck=3
, le1/(10P)
terme est le plus grand quand ilP
est le plus petit (c'est-à-dire, àP=13
). Par conséquent, pour tousP
, nous avons aussi|x|/P <= 3/10 + 1/130 = 4/13 < 1/3
. Cela explique pourquoi dans le code ci-dessus, nous pouvons initialiser ài = P/3
plutôt que d'avoir à commencer parP/2
.De plus, les limites de la section Utilité ci-dessus peuvent maintenant être améliorées.
Lemme : Soit
N = 10c + d
oùc > 0
et0 <= d <= 9
. Alorsc + d|x| < N/10 + 9(3P + 1)/10
. (Notez l'inégalité stricte.)Preuve de lemme: par cas. Cas I:
d = 0
ouiN = 10c
. Alorsc + d|x| = c = N/10 < N/10 + 9(3P + 1)/10
.Cas II:
0 < d <= 9
. Alors10c = N - d < N
, alorsc < N/10
. Par conséquentc + d|x| < N/10 + d|x| <= N/10 + 9|x| <= N/10 + 9(3P + 1)/10
. QED.Ainsi, si
N > 3P
(etN = 10c + d
comme précédemment), alors3P + 1 <= N
9(3P + 1)/10 <= 9N/10
N/10 + 9(3P + 1)/10 <= N
c + d|x| < N/10 + 9(3P + 1)/10 <= N
Alors, si
N > 3P
alorsc + d|x| < N
.Par conséquent, nous n'avons qu'à trouver
P
,2P
et3P
, avecx
. Étant donnéN > 0
queN > 3P
, nous remplaçonsN
par|c + dx|
, ce qui diminueN
. Finalement, nous auronsN <= 3P
; à ce moment - là nous nous arrêtons et vérifier siN
est égal à l' un des numéros0
,P
,2P
ou3P
.Nous ne pouvons pas faire mieux qu'en
3P
général. Par exemple, supposons queP = 13
etN = 39
ainsix = 4
. Puis remplaçantN
par desdx + c = 9(4) + 3
feuillesN
inchangées.la source
-1
dehors de la parenthèse: 43 octetsEspace , 92 octets
Notez que la syntaxe de ce langage se compose uniquement d'espaces , donc chaque caractère d'espaces a été préfixé ici avec S, T ou L (correspondant respectivement à Space, Tab et Linefeed). Ceux-ci peuvent être supprimés sans perte de fonctionnalité, mais ils sont inclus ici afin de l'afficher correctement.
Essayez-le en ligne!
la source
Japt , 14 octets
Inspiré par la solution de Neil .
Testez-le en ligne!
Explication:
la source
Pyke , 10 octets
Essayez-le ici!
la source
Excel, 27 octets
Peut être entré dans la cellule en tant que
pour 25 octets, mais les mises à jour automatiques d'Excel.
la source