Um número abundante é qualquer número em que a soma de seus divisores adequados seja maior que o número original. Por exemplo, os divisores adequados de 12 são:
1, 2, 3, 4, 6
E somando esses resultados em 16. Como 16 é maior que 12, 12 é abundante. Observe que isso não inclui "Números perfeitos", por exemplo, números iguais à soma de seus divisores adequados, como 6 e 28.
Sua tarefa para hoje é escrever um programa ou função que determine se um número é abundante ou não. Seu programa deve usar um único inteiro como entrada e gerar um valor de verdade / falsidade, dependendo de ser abundante ou não. Você pode assumir que a entrada sempre será válida e maior que 0; portanto, para entradas ruins, o comportamento indefinido é bom.
Você pode levar sua entrada e saída em qualquer formato razoável, por exemplo, STDIN / STDOUT, arquivos ou argumentos / valores de retorno seriam aceitáveis.
Para referência, aqui estão os números abundantes de até 100:
12,
18,
20,
24,
30,
36,
40,
42,
48,
54,
56,
60,
66,
70,
72,
78,
80,
84,
88,
90,
96,
100
E muito mais pode ser encontrado no A005101
Como se trata de código-golfe , as brechas padrão são negadas e tente escrever o código mais curto possível no idioma que você escolher!
fonte
Respostas:
ECMAScript Regex,
1085855597536511508504 bytesCombinar números abundantes no regex ECMAScript é um animal totalmente diferente do que em praticamente qualquer outro sabor de regex. A falta de referências ou recursões avançadas / aninhadas significa que é impossível contar diretamente ou manter um total em execução de qualquer coisa. A falta de atenção faz com que muitas vezes seja um desafio ter espaço suficiente para trabalhar.
Muitos problemas devem ser abordados de uma perspectiva totalmente diferente, e você se perguntará se eles são solucionáveis. Obriga você a lançar uma rede muito mais ampla para descobrir quais propriedades matemáticas dos números com os quais você está trabalhando podem ser usadas para tornar um problema específico solucionável.
De março a abril de 2014, construí uma solução para esse problema no regex ECMAScript. No começo, eu tinha todos os motivos para suspeitar que o problema era completamente impossível, mas, em seguida, o matemático teukon esboçou uma idéia que fazia um argumento encorajador para torná-lo solucionável, afinal - mas ele deixou claro que não tinha intenção de construir o regex (ele havia competido / cooperado com o meu na construção / regexes anteriores de golfe, mas atingiu seu limite nesse ponto e estava contente em restringir suas contribuições adicionais à teorização).
Como no meu regex publicado há alguns dias, darei um aviso: eu recomendo aprender como resolver problemas matemáticos unários no regex ECMAScript. Foi uma jornada fascinante para mim, e não quero estragá-la para quem potencialmente queira experimentá-la, especialmente aqueles interessados na teoria dos números. Consulte essa publicação para obter uma lista de problemas recomendados consecutivamente identificados por spoilers para resolver um por um.
Portanto , não leia mais se não quiser que você estrague uma mágica profunda e uniforme de regex . Meu post anterior foi apenas um gostinho. Se você quiser tentar descobrir essa mágica, eu recomendo começar resolvendo alguns problemas no regex ECMAScript, conforme descrito no post acima.
Antes de postar a minha regex ECMAScript, eu pensei que seria interessante analisar de Martin Ender solução pura regex .NET ,
^(?!(1(?<=(?=(?(\3+$)((?>\2?)\3)))^(1+)))*1$)
. É muito simples entender esse regex e é elegante em sua simplicidade. Para demonstrar o contraste entre nossas soluções, aqui está uma versão comentada e bem impressa (mas não modificada) de seu regex:Experimente o regex .NET online
Agora, de volta ao meu regex ECMAScript. Primeiro, aqui está no formato bruto, sem espaço em branco e sem comentários:
^(?=(((?=(xx+?)\3+$)(x+)\4*(?=\4$))+(?!\3+$)(?=(xx(x*?))\5*$)x)(x+))(?=\1(x(x*))(?=\8*$)\6\9+$)(?=(.*)((?=\8*$)\5\9+$))(?=(x*?)(?=(x\11)+$)(?=\12\10|(x))(x(x*))(?=\15*$)(?=\11+$)\11\16+$)(?=(x(x*))(?=\17*$)\7\18+$)((?=(x*?(?=\17+$)(?=\17+?(?=((xx(x*))(?=\18+$)\22*$))(x+).*(?=\17$)\24*(?=\24$)(?!(xx+)\25*(?!\22+$)\25$)\22+$)((?=(x\7)+$)\15{2}\14|)))(?=.*(?=\24)x(x(x*))(?=\28*$)\23\29*$)(?=.*(x((?=\28*$)\22\29+$)))(.*(?!\30)\20|(?=.*?(?!x\20)(?=\30*$)(x(x*))(?=\33*$)(?=\31+$)\31\34+$).*(?=\33\21$)))+$
(mudança
\14
para\14?
a compatibilidade com PCRE, .NET, e praticamente todos os outros sabores regex que não é ECMAScript)Experimente online!
Experimente online! (versão mais rápida, 537 bytes da regex)
E agora um breve resumo da história por trás disso.
No começo, era muito óbvio, pelo menos para mim, que era até possível igualar primos no caso geral. E depois de resolver isso, o mesmo se aplicava às potências de 2. E depois às potências dos números compostos. E depois quadrados perfeitos. E mesmo depois de resolver isso, fazer multiplicação generalizada parecia impossível a princípio.
Em um loop ECMAScript, você pode acompanhar apenas um número alterado; esse número não pode exceder a entrada e deve diminuir a cada passo. Meu primeiro regex de trabalho para combinar as instruções de multiplicação corretas A * B = C tinha 913 bytes e trabalhei fatorando A, B e C em suas potências primárias - para cada fator primo, divida repetidamente o par de fatores de potência primos de A e C por sua base principal até que a correspondente a A atinja 1; o correspondente a C é então comparado ao fator de potência principal de B. Essas duas potências do mesmo primo foram "multiplexadas" em um único número adicionando-as; isso sempre seria inequivocamente separável em cada iteração subsequente do loop, pela mesma razão que os sistemas numéricos posicionais funcionam.
Reduzimos a multiplicação para 50 bytes usando um algoritmo completamente diferente (que teukon e eu conseguimos chegar de forma independente, embora ele tenha levado apenas algumas horas e ele foi direto para ela, enquanto levei alguns dias mesmo depois de trouxe à minha atenção que existia um método curto): para A≥B, A * B = C, se houver, apenas se C for o menor número que satisfaça C0 mod A e C mod B A-1. (Convenientemente, a exceção de A = 1 não precisa de tratamento especial na regex, em que 0% 0 = 0 gera uma correspondência.) Simplesmente não consigo entender o quão interessante é que existe uma maneira tão elegante de fazer multiplicação em um sabor mínimo de regex. (E o requisito de A≥B pode ser substituído pelo requisito de que A e B sejam potências primárias da mesma potência. No caso de A≥B, isso pode ser comprovado usando o teorema do restante chinês.)
Se houvesse um algoritmo mais simples para multiplicação, o número abundante de regex provavelmente seria da ordem de dez mil bytes (mais ainda, considerando que eu joguei o algoritmo de 913 bytes em até 651 bytes). Ele faz muita multiplicação e divisão, e o regex ECMAScript não possui sub-rotinas.
Comecei a trabalhar tangencialmente no abundante número de problemas em 23 de março de 2014, construindo uma solução para o que parecia ser um subproblema: Identificar o fator primordial da maior multiplicidade, para que pudesse ser dividido entre N no início, deixando espaço para fazer alguns cálculos necessários. Naquele momento, parecia ser um caminho promissor a seguir. (Minha solução inicial acabou sendo bastante grande em 326 bytes, depois diminuiu para 185 bytes.) Mas o resto do método que o teukon esboçou teria sido extremamente complicado, então, como se viu, tomei uma rota bastante diferente. Provou ser suficiente dividir o maior fator de potência principal de N correspondente ao maior fator de potência primária de N; fazer isso para o primeiro da multiplicidade mais alta teria adicionado complexidade e comprimento desnecessários ao regex.
O que ficou foi tratar a soma dos divisores como um produto de somas, em vez de uma soma direta. Conforme explicado por teukon em 14 de março de 2014:
Fiquei impressionado ao ver isso. Eu nunca tinha pensado em fatorar a soma da alíquota dessa maneira, e foi essa fórmula mais do que qualquer outra coisa que tornou plausível a resolubilidade da correspondência abundante de números no regex ECMAScript.
No final, em vez de testar um resultado de adição ou multiplicação superior a N ou testar se esse resultado pré-dividido por M excede N / M, fui testando se o resultado da divisão é menor que 1. Cheguei a a primeira versão de trabalho em 7 de abril de 2014.
A história completa das minhas otimizações de golfe desse regex está no github. Em um certo ponto, uma otimização acabou tornando o regex muito mais lento; portanto, a partir desse momento, mantive duas versões. Eles são:
regex para combinar números abundantes.txt
regex para combinar números abundantes - shortest.txt
Essas regexes são totalmente compatíveis com o ECMAScript e o PCRE, mas uma otimização recente envolveu o uso de um grupo de captura potencialmente não participante
\14
; portanto, ao abandonar a compatibilidade do PCRE e mudar\14?
para\14
ambos, é possível reduzir em 1 byte.Aqui está a versão menor, com essa otimização aplicada (tornando-o apenas ECMAScript), reformatada para caber em um bloco de código StackExchange sem (principalmente) nenhuma rolagem horizontal necessária:
fonte
Python 2 ,
4140 bytesA saída é via código de saída , então 0 é verdadeiro e 1 é falso.
Experimente online!
Como funciona
Após o ajuste de todos n , k , e j para a entrada de STDIN, que introduza o enquanto loop. O referido loop quebrará assim que -k - 1 = ~ k ≥ 0 , ou seja, k ≤ -1 / k <0 .
Em cada iteração, primeiro decrementamos j para considerar apenas os divisores apropriados de n . Se j é um divisor de n ,
n%j
produz 0 e j >> n% j * n = j / 2 0 = j é subtraído de k . No entanto, se j se não dividir n ,n%j
é positiva, entãon%j*n
é, pelo menos, n> log 2 j e j >> n% j * n = j / 2 n% j * n = 0 é subtraído a partir de k .Para números abundantes, k atingirá um valor negativo antes ou quando j se tornar 1 , uma vez que a soma dos divisores adequados de n é estritamente maior que n . Neste caso, nós sair da enquanto loop e o programa termina normalmente.
No entanto, se n não for abundante, j chegará a 0 . Nesse caso,
n%j
lança um ZeroDivisionError e o programa sai com um erro.fonte
~k<0
é chique, mas acho que-1<k
também faz o truque;)Braquilog , 5 bytes
Experimente online!
Explicação
fonte
Gelatina , 3 bytes
Experimente online!
Como funciona
fonte
Python , 44 bytes
Experimente online!
fonte
range(n)
. Esse módulo irritante por zeroMathematica, 17 bytes
Explicação
fonte
AbundantNumberQ
, por isso seria salvar um casal bytes :)05AB1E ,
54 bytes-1 bytes graças ao scottinet
Experimente online! ou Tente de 0 a 100
fonte
Retina ,
5045 bytesEntrada unária , saída
1
para números abundantes,0
caso contrário.Não há nada específico da Retina sobre esta solução. O acima é um regex .NET puro que corresponde apenas a números abundantes.
Experimente online! (Conjunto de testes que filtra a entrada decimal com o regex acima.)
fonte
Retina , 34 bytes
A contagem de bytes assume a codificação ISO 8859-1.
Entrada unária , saída
1
para números abundantes,0
caso contrário.Experimente online!
Explicação
Começamos obtendo todos os divisores da entrada. Para fazer isso, retornamos (
!
) todas as correspondências sobrepostas (&
) (M
) da expressão regular(1+)$(?<=^\1+)
. A regex corresponde a algum sufixo da entrada, desde que toda a entrada seja um múltiplo desse sufixo (o que garantimos ao tentar chegar ao início da string usando apenas cópias do sufixo). Devido à maneira como o mecanismo regex procura correspondências, isso resultará em uma lista de divisores em ordem decrescente (separados por feeds de linha).O estágio em si simplesmente corresponde a linefeeds (
¶
) e os remove. No entanto,1>
é um limite, que pula a primeira partida. Portanto, isso efetivamente adiciona todos os divisores, exceto a entrada em si. Terminamos com a entrada na primeira linha e a soma de todos os divisores apropriados na segunda linha.Finalmente, tentamos igualar pelo menos mais um
1
na segunda linha do que na primeira linha. Se for esse o caso, a soma dos divisores apropriados excede a entrada. A retina conta o número de correspondências desse regex, que será1
para números abundantes e0
outros fatores.fonte
8086 Assembly,
2328.2524 bytesDesmontado:
Exemplo de programa de teste, testando N = [12..1000]:
Saída [2..1000]
Saída [12500..12700]
Saída [25100..25300]
Atualizações:
fonte
JLE
porJBE
para dobrar o intervalo de números que isso pode testar antes que os estouros comecem a causar falsos negativos. Em vez de começar a falhar em 12600 (soma da alíquota 35760), começará a falhar em 25200 (soma da alíquota 74744). Melhor ainda seria detectar também o sinalizador de transporte e tratá-lo como um número abundante sem precisar calcular a soma real> 16 bits.JC
ouJNC
agir sobre se o número é abundante ou não.Na verdade , 5 bytes
Experimente online!
fonte
05AB1E , 4 bytes
Experimente online!
Como funciona
Desculpe postar em uma pergunta antiga, eu estava apenas passando por postagens antigas para praticar e percebi que minha solução era mais curta que a próxima melhor solução 05AB1E.
fonte
Sorry to post in old question
Não se preocupe com isso! Sempre fico feliz em ver respostas sobre meus velhos desafios, e isso é realmente incentivado por aqui . :)PARI / GP , 15 bytes
n->sigma(n,-1)>2
Infelizmente, a variante é mais longa.fonte
Java 8, 53 bytes (muito mais se você incluir o código cerimonial)
Experimente online
Explicação:
fonte
return
se não me engano, por isso será ainda mais curto:n->IntStream.range(1,n).filter(e->n%e<1).sum()>n
(não 100% se isso estiver correto, eu quase nunca programa no Java 8). Bem-vindo ao PPCG!n->java.util.stream.IntStream.range(1,n).filter(e->n%e<1).sum()>n
de 65 bytes (supondo que eu tenha tirado o pacote da cabeça)Powershell,
5149 bytesEu gostaria de poder remover alguns suportes.
-2 graças ao AdmBorkBork, em vez de não contar a entrada no intervalo inicial, apenas a levamos em consideração na verificação final.
Loop através de gama de
1..
ao$i
nput, menos 1, encontrar onde (?
) o modulo inverso da entrada pelo número atual é$true
(aka apenas 0) - então-join
todos os números com a+
eiex
a cadeia resultante para calculá-lo, em seguida, ver se o A soma dessas partes é maior que a entrada.fonte
param($i)((1..$i|?{!($i%$_)})-join"+"|iex)-gt2*$i
MATL, 6 bytes
Saídas 1 para números abundantes, 0 caso contrário.
Como funciona
fonte
QBIC , 22 bytes
Esta é uma adaptação ao teste de primalidade QBIC . Em vez de contar os divisores e verificar se é menor que três, isso soma os divisores apropriados. Isso é executado apenas em metade
1 to n
, onde o teste de primalidade é executado1 to n
completamente.Explicação:
fonte
JavaScript (ES6), 33 bytes
fonte
Japonês ,
9 76 bytesEconomizou 2 bytes graças ao ETHproductions. Guardado 1 byte graças a obarakon.
Experimente online!
fonte
â
é 1 byte, em pelo menos unicode (0xE2).â
há um único byte.â
for fornecido um argumento de verdade, ele removerá o número real da lista restante, para que você possaâ1 x >U
salvar alguns bytes :-)<Uâ1 x
para salvar um byte. Japt adiciona oU
na frente do programa.Cubix , 38 bytes
Experimente aqui
0I:
- configura a pilha com 0, n, n (s, n, d)^
- início do loop)?
- diminui de 0 para 0. 0 sai do loop%?
- mod contra ne test. 0 causa;rrw+s;rU
que gira s para cima e adiciona d, gira s para baixo e volta ao loop;<
- Limpe e volte ao loop.Ao sair do loop
;<
- Remova d da pilha e redirecione-?
- Remova n de se teste, 0LOU@
vira à esquerda, sai e sai, negativos0O@
pressiona zero, sai e sai. positivos;O
removem diferença e resultados n. O caminho passa à esquerda, que redireciona para a@
saídafonte
Pure Bash, 37 bytes
Agradecemos ao @Dennis por reorganizar o código - economizando 6 bytes e eliminando a saída incidental para o stderr.
A entrada é passada como argumento.
A saída é retornada no código de saída: 0 para abundante, 1 para não abundante.
A saída para stderr deve ser ignorada.
Execuções de teste:
fonte
RProgN , 8 bytes
Explicado
Experimente online!
fonte
Lote, 84 bytes
Saídas
-1
para um número abundante,0
caso contrário. Funciona subtraindo todos os fatores de2n
e depois deslocando o resultado 31 lugares para extrair o bit do sinal. Formulação alternativa, também 84 bytes:Saídas
1
para um número abundante. Funciona subtraindo todos os fatores den
e comparando o resultado a para-n
. (set/a
é a única maneira do Batch fazer aritmética, então não posso ajustar facilmente o loop.)fonte
Perl 6,
7224 bytes1..a
.a
.a
.Graças a @ b2gills.
fonte
$^a
após a primeira pode ser reduzida para apenas$a
. mas é ainda mais curto se você escrevê-lo como{$_ <sum grep $_%%*,^$_}
também a olhar para uma versão anterior,[+](LIST)
obras (sem espaços)J, 19 bytes
Agradecimentos a Conor O'Brien por reduzi-lo a 19 bytes!
<[:+/i.#~i.e.]%2+i.
Anterior: (34 bytes)
f=:3 :'(+/((i.y)e.y%2+i.y)#i.y)>y'
Retorna 1 se for abundante e 0 se não for.
Saída:
fonte
f=:
como parte da sua contagem de bytes. Além disso, você pode chegar a 19 convertendo para um verbo tácito:<[:+/i.#~i.e.]%2+i.
(f g h) y' is the same as
(fy) g (hy). When
f` é um limite,([: g h) y
é aproximadamente o mesmo queg h y
. Quanto a~
isso, alterna os argumentos esquerdo e direito. É importante saber que~
não é um verbo, mas na verdade é um advérbio. Modifica um verbo. Por exemplo, poderíamos ter algo parecido2 %~ 8
. Aqui,~
modifica%
para alternar seus argumentos, para que a expressão seja equivalente a8 % 2
.#~
é avaliada após os verbos à sua direita são executados, por isso é argumento esquerda torna-se o resultado à direitaPitão, 11 bytes
Velho:
Não posso usar
!%
como pfn para#
, porque são duas funções. Deixa-me triste :(.fonte
>sPf!%QTS
k ,
19 1615 bytesRetorna
1
para true e0
para false.Experimente online!
fonte
PowerShell , 43 bytes
Experimente online!
fonte
Lisp comum, 63 bytes
Experimente online!
fonte
F #, 51 bytes
Experimente online!
Filtra todos os números que não se dividem uniformemente
n
e depois os soma e os comparan
.fonte