Para verificar se um número decimal é divisível por 7:
Apague o último dígito. Multiplique por 2 e subtraia o que resta. Se o resultado é divisível por 7, o número original é divisível por 7.
(também descrito, por exemplo, aqui )
Esta regra é boa para verificação de divisibilidade manual. Por exemplo:
2016 é divisível por 7?
Subtrair
6*2
de 201; temos 189. Isso é divisível por 7? Para verificar, vamos aplicar a regra novamente.Subtraia
9*2
de 18; temos 0. Portanto, 2016 é divisível por 7.
Nesse desafio, você deve aplicar esta regra até que o status de divisibilidade seja óbvio , ou seja, o número não seja maior que 70 (no entanto, veja detalhes abaixo). Faça uma função ou um programa completo.
Entrada : um número inteiro positivo; seu código deve suportar entradas de até 32767 (o suporte a números inteiros de precisão arbitrária é um bônus; veja abaixo).
Saída : um número inteiro (possivelmente negativo), não superior a 70, resultante da aplicação da regra da divisibilidade por 7 a zero ou mais vezes.
Casos de teste:
Input Output Alternative output
1 1
10 10 1
100 10 1
13 13 -5
42 42 0
2016 0
9 9
99 -9
9999 -3
12345 3
32767 28 -14
---------- Values below are only relevant for the bonus
700168844221 70 7
36893488147419103232 32 -1
231584178474632390847141970017375815706539969331281128078915168015826259279872 8
Onde duas saídas possíveis são especificadas, qualquer um dos resultados está correto: o segundo corresponde à aplicação da regra mais uma vez. É proibido aplicar a regra em um número de um dígito: se você apagar o dígito, não resta nada (não 0).
Bônus : se o seu algoritmo
- Suporta números inteiros de precisão arbitrária
- Executa apenas uma passagem na entrada
- Tem complexidade de espaço
o(n)
(ou seja, menor queO(n)
); e - Tem complexidade de tempo
O(n)
,
onde n
é o número de dígitos decimais:
Subtraia 50% da contagem de bytes do seu código.
Bônus real :
Além disso, se o seu algoritmo lê a entrada na direção normal, começando pelo dígito mais significativo, subtraia 50% mais uma vez - sua pontuação é de 25% da sua contagem de bytes (parece possível, mas não tenho certeza).
fonte
1000000000000000000001
.long long
s ou algum tipo equivalente incorporado?Respostas:
Golfscript,
2722 bytesVocê pode usá-lo desta maneira:
Explicação
5 bytes salvos graças ao Dennis!
fonte
@wizzwizz4
(@
então meu nome de usuário) no início (ou em qualquer lugar) de um comentário.{...}{}if
peça como{...}*
, que aplicará apenas o bloco de código zero uma vez, dependendo do valor pressionado>
. Além disso, temos permissão para realizar mais uma iteração (substituindo70
por9
salva um byte) e não acho que você precise abrir o bloco;
.Haskell, 35 bytes
Exemplo de uso:
until(<71)(\n->div n 10-2*mod n 10) 36893488147419103232
->32
.Nada a explicar, é uma implementação direta do algoritmo.
fonte
Gelatina, 11 bytes
Experimente online!
Como funciona
fonte
Python 2, 38 bytes
Experimente aqui !
Abordagem recursiva simples. Imprime x se <70 aplica a regra de divisibilidade e chama a si mesma com o resultado.
fonte
)
f=lambda x:x*(x<70)or f(x/10-x%10*2)
x*(x<70) != 0
ser a condição final. Se x chegar a 0 - como acontece em 2016 - a condição final nunca acontece.Pitão, 13 bytes
Experimente on-line: Demonstration or Test Suite
Isso imprimirá todas as respostas alternativas.
Explicação:
fonte
Julia,
2726 bytesEsta é uma função recursiva que aceita um número inteiro e retorna a
BigInt
. Se a entrada for um número grande, como no último exemplo, Julia a analisa como umaBigInt
, portanto, nenhuma conversão manual é necessária.A abordagem é apenas uma implementação direta do algoritmo. Ele produzirá as saídas alternativas. Tomar o módulo ao dividir por 10 gera o último dígito e o quociente da divisão inteira por 10 gera tudo, menos o último dígito.
Guardado um byte graças a Dennis!
fonte
70
por9
salva um byte.Pitão, 17 bytes
Experimente aqui!
A mesma abordagem recursiva da minha resposta em python . Define um lambda
y
que é chamado assim:y12345
.O contador de bytes no intérprete online mostra 19 bytes porque adicionei a chamada lambda a ele, para que você possa experimentá-lo pressionando o botão de execução.
Explicação
fonte
CJam - 19 bytes
Versão do while:
Experimente on-line ou Enquanto versão nº 1:
Experimente online ou Enquanto a versão 2:
Experimente online .
fonte
Oracle SQL 11.2, 116 bytes
Sem golfe
fonte
Haskell,
157192184 184167159147138 + 5 bytes - 50% = 71,5 bytesO (1) espaço, O (n) tempo, passagem única!
Use como
0![6,1,0,2]
para aplicar a regra a 2016, ou seja, passe um número em forma de fluxo com o número menos significativo primeiro. Dessa maneira, ele passará o número dígito por dígito, aplicando a regra com complexidade de espaço O (1).O código não destruído está aqui:
A essência de como isso funciona é que ele implementa um algoritmo de subtração dígito por dígito , mas tira proveito do fato de que cada número a ser subtraído tem no máximo 2 dígitos e, portanto, podemos subtrair uma quantidade arbitrária desses números. ou números de 2 dígitos do principal (além de comer os dígitos menos significativos).
O algoritmo de subtração é O (1) e armazena apenas o valor atual de 'empréstimo'. Alterei isso para adicionar o dígito extra (0 ou 1), e notamos que esse valor de empréstimo é limitado (dentro do intervalo [-2,2], portanto, precisamos apenas de 3 bits para armazenar isso).
Os outros valores armazenados na memória são variáveis temporárias que representam o número atual de 2 dígitos a ser adicionado, uma única olhada no fluxo e a aplicação de uma etapa do algoritmo de subtração (ou seja, são necessários dois dígitos e um valor emprestado e retorna um dígito e um novo valor emprestado).
Finalmente, no final, processa os dois últimos dígitos no fluxo de uma só vez para retornar um número de um dígito em vez de uma lista de dígitos.
NB A
sev
função na versão não-golfada funcionará em umInteger
, convertendo-a na forma de fluxo invertido.fonte
Mod[18 - Quotient[n, 10] - 2*n, 21] - 18 + Quotient[n, 10]
funciona empiricamente para n entre 10 e 99, mas fica mais complicado quanto mais dígitos tiver n ...0
ao chamar!
também, por exemplo, como uma seção(0!)
(+ uma nova linha), ou seja, +5 bytes. Por outro lado, você pode reduzir o primeiro a padronizar correspondências de!
parap![d]=
ep![d,e]=
. Além disso, o uso padrão de guarda em vez dolet
:p!(d:e:f)|(b,a)<-quotRem(2*d)10,(q,r)<-h$e-a-p=(b+q)!(r:f)
.(0!)
sobre uma linha própria.(0!)
é a função que você dá como resposta. A0
é necessária, mas não tem nada a ver com a entrada, para que você não pode terceirizar para o chamador. Claro que você também pode usarf x=0!x
, mas isso é mais longo.GNU dc,
2015 bytesIsso define minha primeira (sempre) função dc
F
,. Ele recebe entrada no topo da pilha e deixa sua saída no topo da pilha. Exemplo de uso:fonte
Mathematica,
4744 bytesAbordagem recursiva simples. Provavelmente poderia ser jogado ainda mais.
fonte
#0[{1,-2}.QuotientRemainder[#,10]]
salva um byte.R, 43 bytes
Explicação:
Amostras de execuções:
fonte
JavaScript ES6, 38 bytesFalha com
36893488147419103232
e usando~~(1/10)
também falhará700168844221
Teste:
fonte
Fail
s ... 70 e 32 #f=n=>n>70?f((n-n%10*21)/10):n
é uma versão mais curta, mas ainda funciona apenas até2**56
.Mathematica, 33 bytes
Caso de teste
fonte
Perl 5,
4746 bytesTeve que usar
bigint
para o último caso de teste. (Retorna 20 sem)Não tenho certeza se é um candidato ao bônus, então não o levei em consideração. (Acho que sim, mas não estou realmente acostumado aos conceitos)
Experimente aqui!
fonte
ES6, 108 bytes
Funciona para 2²⁵⁷ e 1000000000000000000001001, mas pode usar mais golfe.
fonte
JavaScript ES6,
140142 bytesEssa é a verdadeira matemática de precisão arbitrária, funciona até no maior caso de teste.
Essa função remove recursivamente o último dígito da sequência e subtrai 2 * o último dígito da sequência numérica restante, incrementando iterativamente a quantidade de dígitos a serem aplicados ao minuendo até que a diferença seja positiva. Em seguida, acrescenta essa diferença ao final da string com se preenchido adequadamente
0
e se chama recursivamente até que seu valor numérico seja menor ou igual a9
.fonte
1000000000000000000001
.s.replace(/.$/,'-$&*2')
. Eu não tenho nenhuma idéia óbvia para o resto, desculpe.C #,
111104 bytesfonte
Brain-Flak ,
368360 bytesExperimente Online!
Explicação
Para começar, todo o código está em um loop que é executado até que o topo da pilha seja menor que zero:
Dentro do loop, executamos o divisível por sete algoritmos:
Duplique a parte superior da pilha
Pegue o mod 10 do topo da pilha (último dígito)
Isso é um pouco confuso, mas faz o resto do algoritmo que eu poderia explicar mais tarde, mas não me lembro completamente como ele funciona:
fonte
C, 56 bytes - 75% = 14
Embora isso não dê exatamente os mesmos números que os casos de teste, satisfaz o espírito da pergunta (e sem dúvida mais). Ele identifica corretamente os múltiplos exatos de 7 e fornece o restante exato para outros números (já que nunca usa números negativos).
Não há multiplicação ou divisão no algoritmo, apenas adição e subtração, e os dígitos são processados em uma única passagem da esquerda para a direita. Funciona da seguinte forma, começando com 0 no acumulador:
A etapa "multiplicar por três" é escrita
n-=-n-n
para salvar um byte e evitar o operador de multiplicação.Quando chegamos ao final, não subtraímos setes, portanto o resultado estará no intervalo de 0 a 24; se você quiser um módulo estrito (0-7), substitua
*c
por*c||n>6
nofor
condição de loop.Ele se qualifica para o bônus aprimorado, porque
Programa de teste e resultados
Versão alternativa
Aqui está um que se repete (você desejará permitir que as otimizações do compilador façam a transformação da chamada de cauda ou poderá sobrecarregar sua pilha; eu usei
gcc -std=c89 -O3
):Chame-o com '0' como o segundo argumento.
Ambas as versões calculam o módulo restante sete de um número de 60.000 dígitos em menos de 50 milissegundos na minha máquina.
fonte
PHP, 50 bytes
usa saída alternativa; trabalha até
PHP_INT_MAX
versão string, funciona para qualquer número (positivo) (64 bytes):
fonte
Java, 133 bytes
Eu odeio o quão detalhado
Integer.parseInt
é. Ungolfed:fonte