Parfois, lorsque j'essaie paresseusement de prendre en compte le nombre qui apparaît devant moi¹, après un certain temps, je me rends compte que c'est plus facile que je ne le pensais. Prenons 2156
par exemple: il m'est finalement apparu que les deux 21
et 56
sont des multiples de 7
, et donc certainement 2156 = 21 x 100 + 56
aussi un multiple de 7
.
Votre tâche consiste à écrire du code qui identifie les nombres plus faciles à factoriser en raison d'une coïncidence de ce type.
Plus précisément:
Écrivez un programme ou une fonction qui prend n
en entrée un entier positif et renvoie une valeur vraie s'il existe un diviseur d
(supérieur à 1
) tel qu'il n
peut être coupé en deux pour produire deux entiers positifs, chacun étant un multiple de d
; retourner une valeur falsifiée sinon.
- "Coupé en deux" signifie ce que vous pensez: la représentation habituelle en base 10 de
n
partitionnée à un moment donné en une moitié avant et une moitié arrière pour donner deux autres entiers de base 10. Ce n'est pas grave si le deuxième entier a un zéro non significatif (mais notez que ce doit être un entier positif, donc le fractionnement1230
en123
et0
n'est pas valide). - Les valeurs véridiques et fausses peuvent dépendre de l'entrée. Par exemple, si un entier différent de zéro est véridique dans la langue de votre choix, vous pouvez renvoyer le diviseur
d
ou l'un des "morceaux" den
(oun
lui - même d'ailleurs). - Par exemple, tout nombre pair avec au moins deux chiffres dans l'ensemble
{2, 4, 6, 8}
donnera une valeur vraie: il suffit de le diviser après le premier chiffre pair. De même, par exemple, tout nombre premiern
donnera une valeur fausse, tout comme n'importe quel nombre à un chiffre. - Notez qu'il suffit de considérer les diviseurs premiers
d
. - Vous pouvez supposer que l'entrée est valide (c'est-à-dire un entier positif).
Il s'agit de code-golf , donc le code le plus court en octets l'emporte. Mais les solutions dans toutes les langues sont les bienvenues, nous pouvons donc nous efforcer d'obtenir le code le plus court dans chaque langue, et pas seulement le code le plus court dans l'ensemble.
Cas de test
(Vous n'avez qu'à sortir une valeur véridique ou fausse; les annotations ci-dessous sont juste à titre d'explication.) Certaines entrées qui donnent des valeurs véridiques sont:
39 (3 divides both 3 and 9)
64 (2 divides both 6 and 4)
497 (7 divides both 49 and 7)
990 (splitting into 99 and 0 is invalid; but 9 divides both 9 and 90)
2233 (11 divides both 22 and 33)
9156 (3 divides both 9 and 156; or, 7 divides both 91 and 56)
11791 (13 divides both 117 and 91)
91015 (5 divides both 910 and 15)
1912496621 (23 divides both 1912496 and 621; some splittings are multiples of 7 as well)
9372679892 (2473 divides both 937267 and 9892; some splittings are multiples of 2 as well)
Certaines entrées qui donnent des valeurs de falsification sont:
52
61
130 (note that 13 and 0 is not a valid splitting)
691
899
2397
9029
26315
77300 (neither 7730 and 0 nor 773 and 00 are valid splittings)
2242593803
¹ oui je fais vraiment ça
la source
;(11+)+,\1+;
Brachylog (2), 8 octets
Essayez-le en ligne!
Explication
De toute évidence, si le même nombre (supérieur à 1) divise les deux pièces, le même nombre premier divisera les deux. Exiger que le facteur soit premier interdit clairement 1 comme facteur. Il empêche également un littéral d'
0
être choisi comme segment d'un nombre (car il0
n'a pas de factorisation principale et entraînera l'ḋ
échec).Il n'est pas nécessaire de vérifier les zéros internes correspondants; si une scission
x
et0y
est valide,x0
ety
fonctionnera tout aussi bien (et aller dans l'autre sens, six0
ety
travaux, nous avons une solution de travail indépendamment du fait quex
et0y
travaillerions ou non).Un programme complet Brachylog, comme celui-ci, renvoie un booléen;
true.
s'il existe un moyen de l'exécuter sans échec (c'est-à-dire de faire des choix tels qu'aucune erreur ne se produise),false.
si tous les chemins mènent à l'échec. C'est exactement ce que nous voulons ici.la source
Gelée ,
14121110 octetsMerci à @JonathanAllan d'avoir joué au golf sur 1 octet!
Essayez-le en ligne!
Comment ça marche
la source
D
, commemake_digits
c'est le cas pourŒṖ
.Mathematica,
6362 octets(1 octet merci à Greg Martin)
C'est une fonction qui prend un entier en entrée et retourne
True
ouFalse
. Si vous le testez sur un grand nombre, apportez un livre à lire pendant que vous attendez.Explication:
Floor@{Mod[#,t=10^n],#/t}
divise arithmétiquement l'entrée en ses derniersn
chiffres et lesm-n
chiffres restants (oùm
est le nombre total de chiffres).Table[1~Max~#&/@...,{n,#}]
fait cela pour chaquen
jusqu'au numéro d'entrée. (C'est beaucoup trop grand. Nous n'avons besoin que de faire cela jusqu'au nombre de chiffres de l'entrée, mais cette façon économise les octets et donne toujours le résultat correct.) Le1~Max~#&/@
bit se débarrasse des zéros, donc les nombres comme130 -> {13,0}
ne comptent pas commeTrue
.1<Max@@GCD@@@...
trouve le plus grand diviseur commun de chacune de ces paires et vérifie si l'un de ces diviseurs est supérieur à 1. Si tel est le cas, nous avons trouvé un moyen de factoriser le nombre en le divisant.la source
{#~Mod~10^n,#/10^n}
ou{Mod[#,t=10^n],#/t}
.#~Mod~10^n
, mais il semble être placé entre crochets commeMod[#,10]^n
au lieu deMod[#,10^n]
. Mais je n'ai pas pensé à votre deuxième suggestion!Mod[#,10]^n
Haskell , 57 octets
Essayez-le en ligne! Utilisation:,
(#1) 2156
retourneTrue
ouFalse
la source
C,
145142139138 138135 octetsla source
JavaScript (ES6),
747170 octetsPrend l'entrée sous forme de chaîne, ce qui est pratique pour l'extrait de code. Edit: sauvé 3 octets grâce à @ user81655.
la source
(c,i)
->c
,i+1
->++i
,t=''
->i=t=''
, cette astuce est utile chaque fois que vous avez besoin d'utiliser des indices de base 1 et ont un endroit pour initialiseri
à0
.t=''
pourrait également être le cast=0
, car l'ajout de toute façon lec
contraint à une chaîne.i
, donc je n'avais pas besoin d'indices basés sur 1, mais j'ai ensuite joué la première tranche àt+=c
.f=(x,y,z)=>z?x%y?g(y,x%y):y:x?f(x,y,1)>1||f(x.slice(1),~~y+x[0]):0
. J'ai également combiné votre fonction GCDf
. Pourrait probablement être joué au golf plus loin. Dernière suggestion, je vous le promets! : Pgcd
fonction simplifiée à l'extrême ne fonctionne pas quandx=0
, et contourner cela et votre faute de frappe m'a pris à 72 octets, donc j'ai eu la chance de pouvoir ensuite jouer au golf sur 2 octets.Python 3,
133118117 117 octetsCertainement pas le plus court, pourrait probablement être un peu raccourci. Fonctionne dans le
O(n)
temps. L'entrée est prise au format\d+
et la sortie est donnée au format(True|False)
selon la valeur booléenne Python par défaut-3 octets grâce à Dead Possum
-15 octets grâce à ovs
-1 octet grâce à This Guy
la source
from fractions import*
économiserait 3 octetsany
pourall
? Si tel est le cas, vous pouvez modifier toute cette partie pour lai(j[k:])and i(j[:k])
porter à 125 octets. Voici les correctifsany(i(j[k:])*i(j[:k])*~-gcd(i(j[k:]),i(j[:k]))for k in range(1,len(j)))
)) for
QBIC ,
9190 octetsExplication:
la source
Python 3 ,
7069 octetsEssayez-le en ligne!
la source
Perl 5 , 46 octets
43 octets de code + 3 octets pour l'
-p
indicateur.Essayez-le en ligne! ou essayez cette version modifiée permettant plusieurs entrées.
Vous ne voudrez probablement pas essayer ceci sur la plus grande entrée, car cela pourrait prendre un (très long) temps.
Explications:
Nous parcourons chaque position du mot avec
s~~~g
, en$`
contenant les nombres avant et$'
les nombres après. Si$`*$'
est vrai (cela signifie qu'aucun n'est vide et aucun n'est0
), alors nous vérifions si un nombre entre 2 et les$`
divisons tous les deux (avec legrep!(...),2..$`
). Si oui,$\|=..
définira$\
sur une valeur non nulle, qui est implicitement imprimée à la fin grâce à-p
flag.la source
$<backquote>
démarque en SE, je vous serais reconnaissant de me dire comment.<code>
…</code>
(plutôt que`
…`
), puis en échappant aux backquotes comme\`
. De plus, ce commentaire a été pénible à écrire, car il doit être à double échappement (et les deux ensembles de règles d'échappement sont différents!).Python 2 , 69 octets
Utilise la récursivité au lieu des fonctions intégrées GCD.
Essayez-le en ligne!
Comment ça marche
Lorsque f est appelé avec un à trois arguments ( d par défaut est 10 , k à 2 ), il vérifie d'abord la valeur de l'expression
k<d<n
. Si les inégalités k <d et d <n sont toutes deux valides, l'expression suivanteand
est exécutée et sa valeur est renvoyée; sinon, f retournera simplement False .Dans le premier cas, nous commençons par évaluer l'expression
n/d%k+n%d%k<1<n%d
.d sera toujours une puissance de dix, donc
n/d
etn%d
divisez efficacement les chiffres décimaux de n en deux tranches. Ces tranches sont à la fois divisibles par k si et seulement si estn/d%k+n%d%k
évalué à 0 , ce qui est testé en comparant le résultat avec 1 .Puisqu'une partie des exigences est que les deux tranches doivent représenter des entiers positifs, la valeur de
n%d
est également comparée à 1 . Notez que 1 n'a pas de diviseurs premiers, donc la comparaison plus chère avec 0 n'est pas requise. Notez également que d <n garantit déjà quen/d
sera évalué à un entier positif.Enfin, il récursivement tous
f(n,d,k+1)
(en essayant le diviseur commun potentiel suivant) etf(n,10*d)
(en essayant le fractionnement) et renvoie le OU logique des trois résultats. Cela signifie que f renverra True si (et seulement si) k est un diviseur commun de n / d et n% d ou la même chose est vraie pour une plus grande valeur de k et / ou une puissance plus élevée de dix d .la source