Às vezes, quando estou ociosamente tentando fatorar qualquer número que aparece na minha frente after, depois de um tempo percebo que é mais fácil do que eu pensava. Tome 2156
por exemplo: que, eventualmente, ocorre-me que tanto 21
e 56
são múltiplos de 7
e assim certamente 2156 = 21 x 100 + 56
também é um múltiplo de 7
.
Sua tarefa é escrever um código que identifique números mais fáceis de fatorar devido a uma coincidência desse tipo.
Mais precisamente:
Escreva um programa ou função que use um número inteiro positivo n
como entrada e retorne um valor verdadeiro se existir um divisor d
(maior que 1
) que n
possa ser dividido em dois para gerar dois números inteiros positivos, cada um dos quais é múltiplo d
; retorne um valor falso se não.
- "Dividido em dois" significa o que você pensa: a representação usual da base 10
n
particionada em algum momento em uma metade da frente e uma metade traseira para produzir dois outros números inteiros da base 10. Tudo bem se o segundo inteiro tem um zero à esquerda (mas nota que ele deve ser um inteiro positivo, então a divisão1230
em123
e0
não é válido). - Os valores de verdade e falsidade podem depender da entrada. Por exemplo, se qualquer número inteiro diferente de zero é verdadeiro no seu idioma de escolha, você pode devolver o divisor
d
ou uma das "partes" den
(oun
ela mesma nesse caso). - Por exemplo, qualquer número par com pelo menos dois dígitos no conjunto
{2, 4, 6, 8}
produzirá um valor verdadeiro: basta dividi-lo após o primeiro dígito par. Também, por exemplo, qualquer número primon
produzirá um valor falso, assim como qualquer número de um dígito. - Observe que basta considerar os divisores principais
d
. - Você pode assumir que a entrada é válida (ou seja, um número inteiro positivo).
Isso é código-golfe , então o código mais curto em bytes vence. Porém, soluções em todos os idiomas são bem-vindas, para que possamos buscar o código mais curto em cada idioma, não apenas o código mais curto em geral.
Casos de teste
(Você só precisa emitir um valor verdadeiro ou falso; as anotações abaixo são apenas uma explicação). Algumas entradas que produzem valores verdadeiros são:
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)
Algumas entradas que geram valores falsos são:
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
¹ sim, eu realmente faço isso
fonte
;(11+)+,\1+;
Braquilog (2), 8 bytes
Experimente online!
Explicação
Claramente, se o mesmo número (maior que 1) dividir as duas partes, o mesmo número primo dividirá as duas. Exigir que o fator seja primo desaprova ordenadamente 1 como um fator. Também impede que um literal
0
seja escolhido como um segmento de um número (porque0
não possui fatoração primária e causaráḋ
falha).Não há necessidade de verificar se há zeros internos correspondentes; se uma divisão de
x
e0y
é válido,x0
ey
vai funcionar tão bem (e indo para o outro lado, sex0
ey
obras, então temos uma solução de trabalho, independentemente dex
e0y
iria funcionar ou não).Um programa completo do Brachylog, como este, retorna um booleano;
true.
se houver alguma maneira de executá-lo sem falha (por exemplo, para fazer escolhas que não ocorram erros),false.
se todos os caminhos levarem à falha. É exatamente o que queremos aqui.fonte
Geléia ,
14121110 bytesGraças a @ JonathanAllan por jogar fora um byte!
Experimente online!
Como funciona
fonte
D
, comomake_digits
está em vigor paraŒṖ
.Mathematica,
6362 bytes(1 byte graças a Greg Martin)
É uma função que recebe um número inteiro como entrada e retorna
True
ouFalse
. Se você testá-lo em um número grande, leve um livro para ler enquanto espera.Explicação:
Floor@{Mod[#,t=10^n],#/t}
divide aritmeticamente a entrada nos seus últimosn
dígitos e nosm-n
dígitos restantes (ondem
é o número total de dígitos).Table[1~Max~#&/@...,{n,#}]
faz isso para todosn
os números de entrada. (Isso é muito grande. Só precisamos fazer isso até o número de dígitos da entrada, mas dessa maneira economiza bytes e ainda dá o resultado correto.) O1~Max~#&/@
bit se livra de zeros, portanto, números como130 -> {13,0}
não contam comoTrue
.1<Max@@GCD@@@...
encontra o maior divisor comum de cada um desses pares e verifica se algum desses divisores é maior que 1. Se forem, encontramos uma maneira de fatorar o número dividindo-o.fonte
{#~Mod~10^n,#/10^n}
ou{Mod[#,t=10^n],#/t}
.#~Mod~10^n
, mas parece que está entre colchetes emMod[#,10]^n
vez deMod[#,10^n]
. Mas não pensei na sua segunda sugestão!Mod[#,10]^n
Haskell , 57 bytes
Experimente online! Uso:
(#1) 2156
retornosTrue
ouFalse
fonte
C,
145142139138135 bytesfonte
JavaScript (ES6),
747170 bytesRecebe a entrada como uma sequência, o que é útil para o snippet. Editar: salvou 3 bytes graças a @ user81655.
fonte
(c,i)
->c
,i+1
->++i
,t=''
->i=t=''
, este truque é útil a qualquer momento você precisa usar índices baseados-1 e ter um lugar para inicializari
a0
.t=''
poderia sert=0
, já que adicionarc
coerção a uma string de qualquer maneira.i
, então não precisava de índices baseados em 1, mas depois joguei a primeira fatia not+=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
. Combinei sua função GCDf
também. Provavelmente poderia ser jogado ainda mais. Última sugestão, eu prometo! : Pgcd
função simplificada demais não funciona quandox=0
, e, contornando isso, seu erro de digitação me levou a 72 bytes, por isso, foi uma sorte que eu fosse capaz de desviar 2 bytes.Python 3,
133118117 bytesCertamente não é o mais curto, provavelmente poderia ser reduzido um pouco. Funciona a
O(n)
tempo. A entrada é\d+
recebida no formato e a saída é fornecida no formato(True|False)
como valor booleano padrão do Python-3 bytes, graças ao Dead Possum
-15 bytes, graças ao ovs
-1 byte, graças a Esse cara
fonte
from fractions import*
salvaria 3 bytesany
paraall
? Se for esse o caso, você pode alterar toda essa parte parai(j[k:])and i(j[:k])
elevar tudo para 125 bytes. Aqui estão as correções #any(i(j[k:])*i(j[:k])*~-gcd(i(j[k:]),i(j[:k]))for k in range(1,len(j)))
)) for
QBIC ,
9190 bytesExplicação:
fonte
Python 3 ,
7069 bytesExperimente online!
fonte
Perl 5 , 46 bytes
43 bytes de código + 3 bytes para
-p
sinalizador.Experimente online! ou tente esta versão modificada, permitindo várias entradas.
Você provavelmente não deseja tentar isso com a maior entrada, pois pode levar um tempo (muito longo).
Explicações:
Nós iteramos através de cada posição na palavra com
s~~~g
,$`
contendo os números antes e$'
depois. Se$`*$'
for verdadeiro (significa que nenhum está vazio e nenhum está0
), então verificamos se um número entre 2 e$`
divide os dois (com ogrep!(...),2..$`
). Nesse caso,$\|=..
será definido$\
como um valor diferente de zero, que é implicitamente impresso no final graças ao-p
sinalizador.fonte
$<backquote>
remarcação no SE, ficaria grato se você me disser como.<code>
…</code>
(em vez de`
…`
) e depois escapando das aspas como\`
. Além disso, esse comentário foi difícil de escrever, porque precisa ser de escape duplo (e os dois conjuntos de regras de escape são diferentes!).Python 2 , 69 bytes
Usa recursão em vez de incorporados ao GCD.
Experimente online!
Como funciona
Quando f é chamado com um a três argumentos ( d assume o padrão de 10 , k a 2 ), ele primeiro verifica o valor da expressão
k<d<n
. Se as desigualdades k <d e d <n forem mantidas, a expressão a seguirand
será executada e seu valor será retornado; caso contrário, f retornará False .No primeiro caso, começamos avaliando a expressão
n/d%k+n%d%k<1<n%d
.d sempre será uma potência de dez, portanto,
n/d
en%d
efetivamente divida os dígitos decimais em n em duas fatias. Essas fatias são divisíveis por k se e somente se foremn/d%k+n%d%k
avaliadas como 0 , o que é testado comparando o resultado com 1 .Como parte dos requisitos é que ambas as fatias devem representar números inteiros positivos, o valor de
n%d
também é comparado com 1 . Observe que 1 não possui divisores principais, portanto, a comparação mais cara com 0 não é necessária. Além disso, observe que d <n já garante quen/d
será avaliado como um número inteiro positivo.Finalmente, recursivamente tudo
f(n,d,k+1)
(tentando o próximo divisor comum em potencial) ef(n,10*d)
(tentando a divisão) e retorna o OR lógico dos três resultados. Este meio f retornará verdadeiro se (e somente se) k é um divisor comum de n / d e n d% ou o mesmo é verdadeiro para um valor maior de k e / ou uma maior potência de dez d .fonte