A veces, cuando intento ociosamente factorizar cualquier número que aparezca delante de mí¹, después de un tiempo me doy cuenta de que es más fácil de lo que pensaba. Tomemos 2156
por ejemplo: eventualmente se me ocurre que ambos 21
y 56
son múltiplos de 7
, y ciertamente 2156 = 21 x 100 + 56
también es un múltiplo de 7
.
Su tarea es escribir un código que identifique números que sean más fáciles de factorizar debido a una coincidencia de este tipo.
Más precisamente:
Escriba un programa o función que tome un número entero positivo n
como entrada y devuelva un valor verdadero si existe un divisor d
(mayor que 1
) tal que n
pueda cortarse en dos para obtener dos números enteros positivos, cada uno de los cuales es un múltiplo de d
; devuelve un valor falso si no.
- "Picado en dos" significa lo que piensas: la representación habitual de base 10 de
n
particionado en algún momento en una mitad frontal y una mitad posterior para producir otros dos enteros de base 10. Está bien si el segundo entero tiene un cero a la izquierda (pero tenga en cuenta que debe ser un entero positivo, por lo que dividirse1230
en123
y0
no es válido). - Los valores de verdad y falsedad pueden depender de la entrada. Por ejemplo, si cualquier número entero distinto de cero es verdadero en el idioma de su elección, puede devolver el divisor
d
o una de las "piezas" den
(o enn
sí mismo). - Por ejemplo, cualquier número par con al menos dos dígitos en el conjunto
{2, 4, 6, 8}
arrojará un valor verdadero: simplemente divídalo después del primer dígito par. También, por ejemplo, cualquier número primon
arrojará un valor falso, al igual que cualquier número de un dígito. - Tenga en cuenta que es suficiente considerar divisores primos
d
. - Puede suponer que la entrada es válida (es decir, un entero positivo).
Este es el código de golf , por lo que gana el código más corto en bytes. Pero las soluciones en todos los idiomas son bienvenidas, por lo que podemos luchar por el código más corto en cada idioma, no solo el código más corto en general.
Casos de prueba
(Solo tiene que generar un valor verdadero o falso; las anotaciones a continuación son solo a modo de explicación). Algunas entradas que producen valores verdaderos son:
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)
Algunas entradas que producen valores falsos son:
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
¹ sí, realmente hago esto
fuente
;(11+)+,\1+;
Brachylog (2), 8 bytes
Pruébalo en línea!
Explicación
Claramente, si el mismo número (mayor que 1) divide ambas piezas, el mismo número primo dividirá ambas. Requerir que el factor sea primo claramente deshabilita 1 como factor. También evita que
0
se elija un literal como segmento de un número (porque0
no tiene factorización prima y provocaráḋ
un error).No hay necesidad de verificar contra ceros internos coincidentes; Si una fracción de
x
y0y
es válida,x0
yy
funcionará igual de bien (y en la otra dirección, six0
yy
obras, ya que tenemos una solución de trabajo, independientemente de six
y0y
funcionaría o no).Un programa completo de Brachylog, como este, devuelve un booleano;
true.
si hay alguna forma de ejecutarlo sin fallas (es decir, hacer elecciones para que no ocurra ningún error),false.
si todas las rutas conducen a fallas. Eso es exactamente lo que queremos aquí.fuente
Jalea ,
14121110 bytes¡Gracias a @JonathanAllan por jugar golf en 1 byte!
Pruébalo en línea!
Cómo funciona
fuente
D
, comomake_digits
está vigente paraŒṖ
.Mathematica,
6362 bytes(1 byte gracias a Greg Martin)
Es una función que toma un entero como entrada y devuelve
True
oFalse
. Si lo prueba en un número grande, traiga un libro para leer mientras espera.Explicación:
Floor@{Mod[#,t=10^n],#/t}
divide aritméticamente la entrada en sus últimosn
dígitos y losm-n
dígitos restantes (dondem
es el número total de dígitos).Table[1~Max~#&/@...,{n,#}]
hace esto para cadan
hasta el número de entrada. (Esto es demasiado grande. Solo necesitamos hacer esto hasta el número de dígitos de la entrada, pero de esta manera ahorra bytes y aún así da el resultado correcto). El1~Max~#&/@
bit elimina los ceros, por lo que números como130 -> {13,0}
no cuentan comoTrue
.1<Max@@GCD@@@...
encuentra el máximo común divisor de cada uno de estos pares y comprueba si alguno de estos divisores es mayor que 1. Si lo son, hemos encontrado una manera de factorizar el número dividiéndolo.fuente
{#~Mod~10^n,#/10^n}
o{Mod[#,t=10^n],#/t}
.#~Mod~10^n
, pero parece estar entre corchetes como enMod[#,10]^n
lugar deMod[#,10^n]
. ¡Sin embargo, no pensé en tu segunda sugerencia!Mod[#,10]^n
Haskell , 57 bytes
Pruébalo en línea! Uso:
(#1) 2156
devolucionesTrue
oFalse
fuente
C,
145,142,139,138,135 bytesfuente
JavaScript (ES6),
747170 bytesToma la entrada como una cadena, que es útil para el fragmento. Editar: Guardado 3 bytes gracias a @ user81655.
fuente
(c,i)
->c
,i+1
->++i
,t=''
->i=t=''
, este truco es útil siempre es necesario utilizar índices basados-1 y tener un lugar para inicializari
a0
.t=''
podría serlot=0
, ya que agregarlo loc
obliga a una cadena de todos modos.i
, por lo que no necesitaba índices basados en 1, pero luego jugué el primer cortet+=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
. También combiné tu función GCDf
. Probablemente podría jugar más golf. Última sugerencia, lo prometo! : Pgcd
función simplificada en exceso no funciona cuandox=0
, y solucionar eso y su error tipográfico me llevó a 72 bytes, por lo que tuve la suerte de poder jugar 2 bytes.Python 3,
133118117 bytesCiertamente no es el más corto, probablemente podría acortarse un poco. Funciona a
O(n)
tiempo. La entrada se toma en formato\d+
y la salida se da en formato(True|False)
por defecto Valor booleano de Python-3 bytes gracias a Dead Possum
-15 bytes gracias a ovs
-1 byte gracias a This Guy
fuente
from fractions import*
ahorraría 3 bytesany
aall
? Si ese es el caso, puede cambiar toda esa parte parai(j[k:])and i(j[:k])
llevarla a 125 bytes. Aquí hay solucionesany(i(j[k:])*i(j[:k])*~-gcd(i(j[k:]),i(j[:k]))for k in range(1,len(j)))
)) for
QBIC ,
9190 bytesExplicación:
fuente
Python 3 ,
7069 bytesPruébalo en línea!
fuente
Perl 5 , 46 bytes
43 bytes de código + 3 bytes para
-p
bandera.Pruébalo en línea! o pruebe esta versión modificada que permite múltiples entradas.
Probablemente no desee probar esto en la entrada más grande, ya que puede llevar un tiempo (muy largo).
Explicaciones:
iteramos a través de cada posición en la palabra con
s~~~g
,$`
conteniendo los números antes y$'
los números después. Si$`*$'
es verdadero (significa que ninguno está vacío y ninguno lo está0
), entonces verificamos si un número entre 2 y los$`
divide a ambos (con elgrep!(...),2..$`
). Si es así,$\|=..
se establecerá$\
en un valor distinto de cero, que se imprime implícitamente al final gracias a la-p
marca.fuente
$<backquote>
rebaja en SE, le agradecería que me dijera cómo.<code>
...</code>
(en lugar de`
...`
), y luego escapar de las comillas inversas como\`
. Además, este comentario fue difícil de escribir, porque tiene que ser de doble escape (¡y los dos conjuntos de reglas de escape son diferentes!).Python 2 , 69 bytes
Utiliza la recursividad en lugar de los elementos integrados de GCD.
Pruébalo en línea!
Cómo funciona
Cuando se llama f con uno a tres argumentos ( d por defecto es 10 , k a 2 ), primero verifica el valor de la expresión
k<d<n
. Si las desigualdades k <d y d <n se mantienen, la siguiente expresiónand
se ejecuta y se devuelve su valor; de lo contrario, f simplemente devolverá False .En el primer caso, comenzamos evaluando la expresión
n/d%k+n%d%k<1<n%d
.d será siempre una potencia de diez, de modo
n/d
yn%d
efectivamente divide los dígitos decimales en n en dos rebanadas. Estas divisiones son divisibles por k si y solo si sen/d%k+n%d%k
evalúa a 0 , que se prueba comparando el resultado con 1 .Como parte de los requisitos es que ambos segmentos deben representar enteros positivos, el valor de
n%d
también se compara con 1 . Tenga en cuenta que 1 no tiene divisores primos, por lo que no se requiere la comparación más cara con 0 . Además, tenga en cuenta que d <n ya garantiza quen/d
se evaluará a un entero positivo.Finalmente, recursivamente todo
f(n,d,k+1)
(intentando el siguiente divisor común potencial) yf(n,10*d)
(intentando la división) y devuelve el OR lógico de los tres resultados. Este medio f devolverá verdadero si (y solo si) k es un divisor común de n / d y n% d o el mismo es cierto para un valor mayor de k y / o un poder superior de diez d .fuente