Um número é divisível por cada um de seus dígitos?


47

Meu amigo e eu estávamos trabalhando em um laboratório em nossa aula de Ciência da Computação da AP e decidimos codificar um dos problemas, já que ainda tínhamos metade da aula livre depois que terminamos. Aqui está a pergunta:

Dado um número n, n é divisível por cada um de seus dígitos?

Por exemplo, 128 será aprovado neste teste - é divisível por 1,2 e 8. Quaisquer números com zero desqualificam automaticamente o número. Embora você possa usar outras linguagens e publicar soluções com elas, se quiser, estamos mais interessados ​​em ver como pessoas compactas podem criar o programa em Java, pois essa é a linguagem que usamos na classe. Até agora, nós dois temos 51. Aqui está o meu código atual:

public boolean dividesSelf(int n){for(int p=n;n%10>0;)n/=p%(n%10)>0?.1:10;return n<1;}
// 51 characters

// Breakdown:
// for(int p=n;         Saves one semicolon to put declaration into for loop
// n%10>0;)             Basic check-for-zero
// n/=                  Pretty simple, discarding one number off of n at a time
// p%(n%10)>0?          If p (the given value) is not divisible by n%10 (the current digit)...
// .1:10;               Divide by .1 (multiply by 10) so it fails the check next iteration. If it is divisible, divide by 10 to truncate the last digit
// return n<1           If the number was fully divisible, every digit would be truncated, and n would be 0. Else, there would still be non-zero digits.

Exigências

A assinatura do método pode ser o que você quiser. Apenas conte o corpo da função. Certifique-se, no entanto, de que o método retorne um valor booleano e passe apenas em um parâmetro numérico (não em uma string).

O código deve ser capaz de passar todos esses casos (para permanecer fiel às instruções da pergunta original, somente valores booleanos verdadeiros e falsos contam se o idioma suportar booleanos. Se e somente se o seu idioma não tiver variáveis ​​booleanas, você pode representar false com 0 e true com qualquer número inteiro diferente de zero (de preferência 1 ou -1):

128 -> true
 12 -> true
120 -> false
122 -> true
 13 -> false
 32 -> false
 22 -> true
 42 -> false
212 -> true
213 -> false
162 -> true
204 -> false

Além disso, não contamos o espaço em branco, portanto, sinta-se à vontade para fazer o mesmo, a menos que o espaço em branco seja essencial para o funcionamento do programa (para que as novas linhas em Java não sejam contadas, mas um único espaço entre inte x=1conte). Boa sorte !


18
Bem-vindo ao PPCG! Algumas sugestões: 1. Não contar com espaço em branco funcional é uma má idéia. Qualquer resposta escrita em espaço em branco vencerá automaticamente. 2. Se o nosso print envio / retorno truee falseou são truthy / Falsas valores OK bem? 3. A javatag não se aplica aqui, pois o desafio em si não está relacionado ao Java.
Dennis

OK. desculpe pelos problemas. Apenas para esclarecer, você consideraria o espaço em 'int p = n' funcional, porque não o fiz anteriormente. Vou corrigir os outros problemas que você apontou.
Mathew Kirschbaum

5
Todo o espaço em branco necessário para o código funcionar é funcional.
FryAmTheEggman

Ok, obrigado pela resposta!
Mathew Kirschbaum

1
@RickyDemer: como 0 seria uma entrada excepcional nesse caso (é o único número com 0dígitos que é um múltiplo de cada um deles), imagino que a maioria das respostas demoraria mais de uma maneira desinteressante para incluir uma verificação. Então, eu gosto mais do problema apresentado pelo título (divisível por seus dígitos, em vez de ser um múltiplo de seus dígitos, que exclui 0).
Jeroen Mostert

Respostas:


23

Perl 6, 13

sub golf($_) {
   $_%%.comb.all
}

Usa a variável implícita $_- $_ %% .comb.allé equivalente a $_ %% all($_.comb). %%é o operador "é divisível" e, combsem argumento adicional, retorna uma lista dos caracteres em uma sequência. Como exemplo, se o argumento for 123, a função avaliará

123 %% all(123.comb)

qual é

123 %% all(1, 2, 3)

autothreading de junção torna

all(123 %% 1, 123 %% 2, 123 %% 3)

qual é

all(True, False, True)

o que é falso no contexto booleano porque é uma junção "todos" e claramente nem todos os seus elementos são verdadeiros.

Deve ser possível coagir o valor de retorno Boole ocultar a junção dos chamadores fazendo a assinatura da função sub golf($_ --> Bool()), mas as coerções nas assinaturas das funções ainda não funcionam no Rakudo. O valor de retorno ainda é corretamente verdadeiro ou falso, apenas não é Trueou False.


Se você quiser fazê-lo retornar, Boolbasta adicionar souma parte da frente do código so$_%%.comb.all.
Brad Gilbert b2gills

21

C # e System.Linq - 26/40

Pelas regras, sem contar a própria declaração do método.

bool dividesSelf(int i) { 
    return(i+"").All(d=>i%(d-48d)<1);
}

Mostrando que mais uma vez, o C # é a escolha superior quando o Java está sendo considerado ... Brincadeira, brincadeira!

Infelizmente, esta função (e muitas outras respostas) não produzirá resultados corretos para dados negativos. Podemos corrigir isso, mas a solução perde muito de seu charme (e cresce para 46 caracteres):

return(i+"").All(d=>d>48&&i%(d-48)==0||d==45);

Edit : raspou um personagem com a sugestão de Tim.

Edit : com a introdução de membros com expressão no C # 6, podemos reduzir isso ainda mais cortando o return:

bool dividesSelf(int i) =>
    (i+"").All(d=>i%(d-48d)<1);

para um total de 26 caracteres (na minha opinião, =>não deve ser incluído mais do que chaves). A versão que manipula números negativos pode ser reduzida de forma semelhante.


Por que .0? Não há necessidade de nada além de módulo inteiro.
Peter Taylor

3
@ PeterTaylor: Existe, se você quiser o programa mais curto - i % 0com ium número inteiro dá a DivideByZeroException.
Jeroen Mostert

2
E com um duplo, dá NaN! Agradável!
Peter Taylor

2
48dé o mesmo que 48.0, mas um caractere a menos (d para o dobro).
Tim S.

1
@StuartLC: lambdas não são métodos; seu escopo é diferente, então acho que isso está distorcendo as regras demais. Mas desde C # 6 (que essa resposta antecede), temos membros com expressão corporal, o que nos permite encurtar a definição. Para o caso negativo, não podemos usar &, precisamente porque &não provoca um curto-circuito - você receberá uma exceção de divisão por zero no %. Podemos consertar isso fazendo um duplo (com d), mas perdemos um caractere novamente.
Jeroen Mostert

18

APL ( 13 11)

(aparentemente os colchetes não contam)

{0∧.=⍵|⍨⍎¨⍕⍵}

Explicação:

  • ⍎¨⍕⍵: avalie cada caractere na representação de sequência de
  • ⍵|⍨: para cada um deles, encontre o módulo e
  • 0∧.=: veja se todos são iguais a 0

Casos de teste:

      N,[.5] {0∧.=⍵|⍨⍎¨⍕⍵} ¨ N←128 12 120 122 13 32 22 42 212 213 162 204
128 12 120 122 13 32 22 42 212 213 162 204
  1  1   0   1  0  0  1  0   1   0   1   0

APL pode fazer X%0? sem jogar?
Otimizador

@ Otimizador: sim. 0|XX.
Marinus #

Doce. Além disso, sua resposta é 11 bytes, não 13
Otimizador

9
Apenas APL não daria um erro no módulo de 0, e bater na avaliação de um não-bool como um bool;)
FryAmTheEggman

3
Um caractere mais curto com um trem em vez de dfn:(0∧.=⍎¨∘⍕|⊢)
ngn 30/12/14

14

Caracteres Python 2: 43

f=lambda n:any(n%(int(d)or.3)for d in`n`)<1

Verifica se o número tem algum resto diferente de zero, modula seus dígitos e gera a negação disso. Os dígitos zero são tratados de maneira estranha: como a computação %0causa um erro, os dígitos de 0são substituídos por .3, o que parece sempre fornecer um resultado diferente de zero devido às imprecisões dos pontos flutuantes.

O corpo da função é de 32 caracteres.


14

Perl - 27 bytes

sub dividesSelf{
    $_=pop;s/./!$&||$_%$&/ger<1
}

Não contando a assinatura da função, conforme as instruções.

Uso da amostra:

use Data::Dump qw(dump);
for $i (128, 12, 120, 122, 13, 32, 22, 42, 212, 213, 162, 204) {
  printf "%3d -> %s\n", $i, dump(dividesSelf $i);
}

Saída de amostra:

128 -> 1
 12 -> 1
120 -> ""
122 -> 1
 13 -> ""
 32 -> ""
 22 -> 1
 42 -> ""
212 -> 1
213 -> ""
162 -> 1
204 -> ""

Dirigindo-se à especificação do problema: "Somente valores booleanos verdadeiros e falsos contam. Valores truthy / falsey não contam."

use Data::Dump qw(dump);
dump(1 == 1);
dump(0 == 1);

Saídas:

1
""

'True' e 'False' são definidos como 1e "".

Errata:
Como Brad Gilbert aponta corretamente , o perl define verdadeiro como um escalar que é simultaneamente o número inteiro 1e a sequência "1"e falso como um escalar que é o número inteiro 0e a sequência ""simultaneamente.


Isso pode ser encurtado por não usar $_: pop=~s///ger<1. Não sei se o OP concordará com isso 1e ""são resultados válidos. Caso contrário, pode ser corrigido com mais dois bytes: basta adicionar |0.
hvd 26/11

perl -pe'$_=s/./!$&||$_%$&/ger<1|0'tem 26 bytes, incluindo o sinalizador |0e -p. Você não precisa usar uma função.
hmatt1

1
Na verdade, os valores Verdadeiro e Falso são mais parecidos com dualvar(1,'1')e dualvar(0,'').
Brad Gilbert b2gills

1
@BradGilbert Isso é interessante. Estou razoavelmente familiarizado com os perlguts, mas não sabia que verdadeiro e falso eram casos especiais. Na verdade, são 'escalares triplos', marcados como SVIV(int), SVNV(duplo) e SVPV(string).
primo

1
Na verdade, na primeira vez em que você usa uma string como número ou um número como string, a variável é modificada para armazenar esses dados adicionais. É por isso que você só tem um aviso a primeira vez que você usar 'abc'como um número (supondo que você tenha use warnings;habilitado.)
Brad Gilbert b2gills

13

CJam, 11 10 bytes

{
    _Ab:df%:+!
}:F;

Isso define uma função nomeada Fe descarta o bloco da pilha.

Experimente online.

Casos de teste

$ cjam <(echo '{_Ab:df%:+!}:F;[128 12 120 122 13 32 22 42 212 213 162 204]{F}%p')
[1 1 0 1 0 0 1 0 1 0 1 0]

Como funciona

_      " Copy the integer on the stack.                                          ";
Ab     " Push the array of its digits in base 10.                                ";
:d     " Cast each digit to Double.                                              ";
f%     " Take the integer on the stack modulus each of its digits.               ";
:+     " Add the results.                                                        ";
!      " Push the logical NOT of the sum.                                        ";

O CJam tinha os recursos que você usou para a solução de 10 bytes quando a pergunta foi escrita?
lirtosiast

@ThomasKwa: Sim, sim. Testei o código na versão 0.6.2, lançada em julho de 2014.
Dennis

12

JavaScript ES6, 39 32 28 bytes

v=>[...""+v].every(x=>v%x<1)

Obrigado core1024 pela sugestão de substituição (""+v).split("")por [...""+v], e abra ou feche por sugerir o uso da everyfunção.

A resposta atualmente não contém um pouco do meu código: O

Solução anterior

v=>[...""+v].filter(x=>v%x|!+x)==""

==""não é uma maneira válida de verificar se uma matriz está vazia, pois [""]==""retorna true, mas a matriz tem garantia de conter uma seqüência de caracteres não vazia, por isso funciona aqui.

O restante são conversões de tipo abreviado bastante padrão em JavaScript.


1
Você pode salvar alguns caracteres substituindo (""+v).split("")por [...""+v].
core1024

1
Por que não usar o everymétodo? v=>[...""+v].every(x=>v%x<1);
Openorclose

@openorclose: Obrigado. Nunca tive a chance de usá-lo em JS, então nunca pensei em procurar por essa função.
N

v=>![...""+v].some(x=>v%x)
l4m2

@ l4m2 Como v%0retorna NaNe NaN == false, no seu caso, números que contêm 0, como 10, podem retornar true.
Shieru Asakoto

9

Java 8, 46 bytes (corpo do método)

Usando a conversão de Jeroen Mostert para truque duplo.

public static boolean dividesSelf(int n) {
    return(""+n).chars().allMatch(x->n%(x-48d)<1);
}

8

Pitão, 12 bytes

!f|!vT%vzvTz

Isso filtra os caracteres na cadeia de caracteres como sendo zero ( !vT) ou não dividindo a entrada ( %vzvT) e, em seguida, assume o não lógico da lista resultante.

Experimente aqui.


Não, eu estou bem se uma função não for usada. Eu só queria apontar para alguém que estava usando funções que eles não precisam contar a declaração e apenas o código.
Mathew Kirschbaum

8

Ruby, 44 bytes (corpo da função: 37)

Provavelmente tem potencial para ser jogado mais.

f=->n{n.to_s.chars.all?{|x|x>?0&&n%x.hex<1}}

Entrada obtida através da função f. Exemplo de uso:

f[128] # => true
f[12]  # => true
f[120] # => false
...

1
Você pode mudar .to_ipara .hex, pois os números de um dígito são iguais na base 16 e pode mudar ==0para <1.
histocrat

8

Python - 59 50 49 47 bytes

f=lambda n:all(c>'0'and 0==n%int(c)for c in`n`)

Tenho certeza de que há uma maneira mais rápida ... tudo bem.

Editar - Obrigado a FryAmTheEggman pelas dicas de golfe.

Edit 2 - FryAmTheEggman pode muito bem ter escrito isso neste momento, oops

Edit 3 - Hands up, se você nem sabia que genexps eram uma coisa. ...Apenas eu?


Oh, muito obrigado! Eu continuo esquecendo todas essas coisas. (Eu também não sabia que você podia menos do que caracteres dessa maneira.)
Kasran

Oh, lançando a lógica também parece reduzi-lo um pouco: f=lambda n:all([c>'0'and 0==n%int(c)for c in`n`]). E não há problema :)
FryAmTheEggman

Ah, eu não sabia que havia um allmétodo.
Kasran

Funcionaria 1>n%int(c)?
SP3000

3
Por que uma lista de compreensão? Usar um genexp: all(c>'0'and 0==n%int(c)for c in`n`)faz exatamente o mesmo, com 2 caracteres a menos e até mesmo salvar a alocação da lista.
26414 Bakuriu


5

Bash + coreutils, 44 bytes

A definição completa da função é:

f()((`tr 0-9 \10<<<$1``sed "s/./||$1%&/g"<<<$1`))

Não sei como pontuar isso, pois normalmente as funções de shell usam um único conjunto de {}ou ()para conter o corpo da função. Eu descobri aqui que eu também poderia usar double (())para conter o corpo da função que causa uma expansão aritmética, que é o que eu preciso aqui. Por enquanto, estou contando apenas um par desses colchetes - uma discussão mais aprofundada sobre isso é bem-vinda.

Resultado:

$ for i in 128 12 120 122 13 32 22 42 212 213 162 204; do f $i; printf "%d " $?; done
1 1 0 1 0 0 1 0 1 0 1 0 $
$

Não está claro para mim se 1s e 0s são aceitáveis ​​ou se eu tenho que imprimir true/ false?
Digital Trauma

4

J - 14 car

O corpo da função é a parte após o =:. Se queremos minimizar a contagem de caracteres para toda a função, esse é o valor de 15 caracteres */@(0=,.&.":|]).

f=:0*/@:=,.&.":|]

,.&.":é o caminho mais curto em J para expandir como número em uma lista de seus dígitos decimais: converter em sequência, separar os dígitos e converter cada dígito novamente em um número. ,.&.":|]pega o número da entrada ( ]) modulo ( |) esses dígitos. 0*/@:=retorna true se todos os resultados forem 0, caso contrário, fornece um false.

   f 162
1
   f every 204 212 213
0 1 0

3

Java - 121 102 97 79 78 bytes

Eu só sei que isso será derrotado mais tarde. Ah bem.

boolean b(int a){int m=10,j,t=1;for(;m<a*10;m*=10){j=10*(a%m)/m;if(j==0||a%j>0)t=0;}return t>0;}

Eu voltarei.


1
Agora você pode nomear sua função como desejar. Alterei as regras para que você conte apenas os cálculos dentro da função real, mas a função deve retornar um tipo booleano. Atualmente, esse número tem 86 caracteres.
Mathew Kirschbaum

3

Haskell - 100 54 38

f x=all(\y->y>'0'&&x`mod`read[y]<1)$show x

Ainda aprendendo, críticas apreciadas


Eu tinha um comentário aqui, mas acidentalmente o apaguei de alguma forma ... De qualquer forma, algumas sugestões: 1) Largue os lengths, eles são desnecessários. 2) Substitua tpor sua definição. 3) elem y sé desnecessário. 4) /='0'pode ser movido para o filtro esquerdo, no lugar de elem y s. 5) Nesse caso, /='0'é equivalente a >'0', uma vez que cada letra é um dígito. 6) Coloque as modcostas, para que se torne infix. 7) Coloque tudo em uma única linha.
Zgarb

1 e 3 eram de quando eu estava tentando fazer isso de uma maneira diferente e com um código recuperado. Obrigado pelas dicas.
globby

1
minhas sugestões: em vez de usar, s==filter(...)svocê deve usar all(...)s. agora, como saparece apenas uma vez na expressão, você pode substituí-lo por sua definição e descarte where. Além disso, em vez de ==0você poderia usar <1.
haskeller orgulhoso

grande melhoria desde a primeira versão!
haskeller orgulhoso

Eu acho que você ainda pode perder um byte se substituir all(\y->...)$show xpor and[...|y<-show x].
Zgarb

2

CJam, 15 bytes

{_Abf{_g{%}*}:|!}

Este é um bloco, a coisa mais próxima de uma função no CJam. Estou apenas contando o corpo (ou seja, omitindo o aparelho). Você pode usá-lo da seguinte maneira:

128{_Abf{_g{%}*}:|!}~

Ou, se você quiser testar uma série de entradas, pode fazer

[128 12 120 122 13 32 22 42 212 213 162 204]{{_Abf{_g{%}*}:|!}~}%

O bloco deixa 0(falsy) ou 1(truth) na pilha para indicar o resultado. (CJam não tem um tipo booleano.)

Teste aqui.

Explicação:

_               "Duplicate input.";
 Ab             "Get base-10 digits.";
   f{      }    "This maps the block onto the list of digits, supplying the input each time.";
     _g         "Duplicate digit, get signum S (0 or 1).";
       { }*     "Repeat this block S times.";
        %       "Take input modulo digit.";
                "This leaves an array of zeroes for divisible digits, non-zeroes
                 for non-divisible digits, and non-zero junk for zeroes.";
            :|  "Fold OR onto this list. One could also sum the list with :+";
              ! "Logical NOT. Turns 0 into 1, and non-zero values into 0.";

Alternativa, também 15 bytes

{:XAb{X\_X)?%},!}

Explicação

:X              "Store input in X.";
  Ab            "Get base-10 digits.";
    {       },  "Filter this list by the result of the block.";
     X\         "Push another copy of X, swap with digit.";
       _        "Duplicate digit.";
        X)      "Push X+1.";
          ?     "Select digit itself or X+1, depending on whether digit is 0 or not.";
           %    "Take modulo. X%(X+1) will always be nonzero for positive integers.";
              ! "Logical NOT. Turns an empty list into 1 and a non-empty list into 0.";

2

CJam, 15 bytes

{_Abf{_{%}1?}1b!}

{}é a coisa mais próxima de uma função no CJam. Estou apenas contando o corpo da função

Use-o assim:

128{_Abf{_{%}1?}1b!}~

Para obter 1(se o número é divisível) ou 0(se o número não é divisível por seus dígitos).

Experimente online aqui

Explicação

_Ab                "Copy the number and split it to its digits";
   f{      }       "For each digit, run this code block on the number";
     _{%}1?        "If the digit is 0, put 1, otherwise perform number modulus digit";
            1b     "We now have an array of modulus corresponding to each digit. Sum it up";
              !    "Negate the sum. If all digits were divisible, sum of modules will be"
                   "0, thus answer should be 1 and vice versa";

Talvez eu esteja perdendo alguma coisa, mas depois de ler rapidamente no CJam, algumas coisas parecem não fazer sentido: como Abdivide os dígitos? Parece apenas convertê-lo para a base 10. Além disso, como% sabe modificar pelo número e não apenas pelo próximo dígito, pois parece que o próximo dígito seria o próximo na pilha?
Mathew Kirschbaum

Responder a todas as suas perguntas será complicado. Seria super fácil de aprender colocando ed após cada caractere no código. Tente executar128{ed_edAedbedf{ed_ed{ed%ed}1ed?ed}ed1edbed!ed}~
Optimizer

1
Respostas a perguntas específicas: fazer a base 10 fornece uma matriz de números convertidos da base 10, que são os próprios dígitos nesse caso. %basta pegar os dois últimos números (neste caso) e calcular o mod. Os últimos dois números aqui são o número e o dígito reais (sempre)
Otimizador

Ok, obrigado pelo conselho!
Mathew Kirschbaum

2

C89, 43 bytes

unsigned char d(int n, int c) {
        int a=n%10;return!n||a&&!(c%a)&&d(n/10,c);
}

C89 não tem um tipo booleano. Espero que funcione. Também usei um segundo parâmetro para passar uma cópia do número original pela pilha, mas a definição pode ser qualquer coisa. Para obter o resultado correto, basta chamar a função com o mesmo valor para os dois parâmetros ( d(128, 128)).

EDIT: edições sugeridas aplicadas por um usuário anônimo


Dê uma olhada em codegolf.stackexchange.com/review/suggested-edits/17160 , alguém deu-lhe algumas sugestões de golfe
Justin

Especificamente contra as regras. Um parâmetro
edc65

Sim, este post é realmente o motivo pelo qual decidi fazer essa regra, pois não parecia certo que o usuário fizesse a duplicação em vez do programa.
Mathew Kirschbaum

Acho que vou ter que adicionar uma função de wrapper. A declaração dessa função é adicionada à contagem de bytes?
MarcDefiant

2

C11 - 44 bytes no corpo da função

Outra versão C, não recursiva e sem uma exceção de ponto flutuante.

bool digit_multiple(int i)
{
    for(int n=i;i%10&&n%(i%10)<1;i/=10);return!i;
}

Isso também funcionará em C ++, Java e na maioria das outras linguagens C.

Editado para incluir a melhoria do comentário do primo.


1
Uma versão que compila em Java (1.7.0_45-b18):, int n=i;for(;i%10>0&&n%(i%10)<1;i/=10);return i<1;um byte menor que o código do OP.
primo

2

Julia 32 25 23

Melhorado usando dígitos

Também corrige o problema com números negativos

selfDivides(x)=sum(x%digits(x).^1.)==0

Método antigo

Todos os dígitos se dividem se a soma de todos os demais for 0. Como outros, tem um problema com números negativos.

selfDivides(x)=sum(x.%(Float64["$x"...]-48))==0

Resultado

[selfDivides(x) for x in [128,12,120,122,13,32,22,42,212,213,162,204]]
12-element Array{Any,1}:
  true
  true
 false
  true
 false
 false
  true
 false
  true
 false
  true
 false

O método aprimorado também lida com o BigInt

selfDivides(BigInt(11111111111111111111111111111111111111112))
true

Contudo

selfDivides(BigInt(11111111111111111111111111111111111111113))
false

Porque

BigInt(11111111111111111111111111111111111111113) %3
1

2

C / C ++, 58 bytes (44 no corpo)

Invoca comportamento indefinido (ver comentários)

int d(int i){int j=i;while(i&&!(j%(i%10)))i/=10;return!i;}

truee false são 1 e 0, mas fique à vontade para adicionar um caractere à assinatura para retornar a bool.

E por diversão, uma versão recursiva que é menor se você permitir chamadas do formulário r(128,128)

Edit : Agora não permitido pelas regras:

C / C ++, 53 bytes (33 no corpo)

int r(int i,int j){return!i||!(j%(i%10))&&r(i/10,j);}


2
O número 1 morre com uma exceção de ponto flutuante para números que contêm 0, porque j% (i% 10) será ilegal para i% 10 = 0.
SBI

Uma exceção de ponto flutuante ? Esquisito. Funciona perfeitamente no meu compilador, mas você está certo, é um comportamento indefinido. Não tenho certeza de qual é a posição geral do PCG no UB dependente do compilador.
etheranger

O que é "UB dependente do compilador"? Ou é UB ou não é (e a divisão por zero, ou melhor, módulo zero, é de fato UB). UB não deve ser permitido, porque literalmente tudo pode acontecer. Podemos assumir que seu programa será executado em uma máquina que explodirá e matará todos ao seu redor quando uma divisão por zero acontecer. Agora, tenho certeza que você deseja que todos vivamos ... C tem um conceito de comportamento definido pela implementação, mas dividir por zero não se enquadra nisso.
Jeroen Mostert

2
@etheranger: A divisão por 0 é chamada de exceção de ponto flutuante por motivos históricos: stackoverflow.com/questions/16928942/…
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

2
@JeroenMostert: Eu diria que mais de 90% de todas as respostas C neste site invocam o UB. Desde que funcione com algum compilador em alguma máquina, a resposta é considerada válida.
Dennis

2

R: 72 67 65

A função

f<-function(a)!(anyNA(a%%(d=as.double(strsplit(paste0(a),"")[[1]])))|sum(a%%d))

Agradecemos a @AlexA e @plannapus pela economia

Execução de teste

i=c(128,12,120,122,13,32,22,42,212,213,162,204)
for(a in i){print(f(a))}
[1] TRUE
[1] TRUE
[1] FALSE
[1] TRUE
[1] FALSE
[1] FALSE
[1] TRUE
[1] FALSE
[1] TRUE
[1] FALSE
[1] TRUE
[1] FALSE

Eu conto atualmente 70 bytes no seu corpo de função, não 72. Mas você pode reduzi-lo a 67 usando d=as.double(strsplit(toString(a),"")[[1]]);!(anyNA(a%%d)|sum(a%%d)). :)
Alex A.

@AlexA. Obrigado. Uma das minhas primeiras tentativas wih R. Will definitivamente voltar :)
MickyT

@MickyT em paste(a)vez de fornecer toString(a)o mesmo resultado.
plannapus

@ Plannapus Obrigado, pequeno truque. Deve lembrar-se de que
MickyT

1

GNU Awk: 53 caracteres

A parte contada:

for(;++i<=split($1,a,//);)r=r||!a[i]||v%a[i];return!r

Toda a função:

function self_divisible(v, i, r)
{
    for (; ++i <= split($1, a, //); )
        r = r || ! a[i] || v % a[i]

    return ! r
}

Como o Awk não possui valores booleanos, retorna 1 para true e 0 para false.


1

JavaScript (ES6) 30

Função com um parâmetro numérico. Usando% e subtração, não é necessário o caso especial '0' porque 0% 0 é NaN em JavaScript.

Editar salvos 1 char thx DocMax

F=n=>[for(d of t=n+'')t-=n%d]&&t==n 

Apenas por diversão, abusando da regra de não contar a assinatura da função, 4

Check=(n,t=n+'',q=[for(d of t)n-=t%d])=>t==n

Teste no console do FireFox / FireBug

console.log([128, 12, 120, 122, 13, 32, 22, 42, 212, 213, 162, 204]
.map(x=>+x + ' -> ' + F(x)).join('\n'))

Resultado

128 -> true
12 -> true
120 -> false
122 -> true
13 -> false
32 -> false
22 -> true
42 -> false
212 -> true
213 -> false
162 -> true
204 -> false

Vou dizer não para inserir uma string.
Mathew Kirschbaum

1
O console Firefox está feliz com a substituição de of(t=n+'')com apenas of t=n+''para salvar 1.
DocMax

1

PHP: 85 bytes (64 bytes no corpo)

Para que essa função funcione, basta passar uma string ou um número.

0 retornará corretamente false.

O código:

function f($n,$i=0){for($n.='';$n[$i]&&$t=!($n%$n[$i++]););return$t&&$i==strlen($n);}

Por favor, NÃO AJUSTE O 2º PARÂMETRO!

Javascript: 76 bytes (61 bytes no corpo)

Esta é uma reescrita da função anterior.

Não mudou muito entre as duas versões.

Aqui está o código:

function f(n){for(i=0,n+='';n[i]/1&&(t=!(n%n[i++])););return t&&i==n.length}

Poliglota: Javascript + PHP 187 217 bytes (76 84 bytes sem clichê):

Por que eu fiz isso?

Por causa da razão e talvez porque eu possa!

Apenas ignore o erro no PHP: ele funciona de qualquer maneira!
Não é mais necessário, isso foi corrigido com a remoção de 3 bytes.

Aqui está a obra-prima:

if('\0'=="\0"){function strlen($s){return $s['length'];}}
function toString(){return'';}
function f($n){for($i=0,$n=$n.toString();$n[$i]/1&&($t=!($n%$n[$i++])););return $t&&$i==strlen($n);}

Você pode executar esse código no console e em um intérprete PHP!


Versão antiga:

if('\0'=="\0"){function strlen($s){return $s['length'];}}
function s($s){return('\0'=="\0")?$s+'':str_replace('','',$s);}
function f($n,$i){for($i=0,$n=s($n);$n[$i]/1&&($t=!($n%$n[$i++])););return $t&&$i==strlen($n);}

"e passa apenas em um parâmetro numérico". Sem isso, você pode eval ($ x) e passar o código inteiro em $ x
abc667

@ abc667 Desculpe, mas não entendi.
Ismael Miguel

1

Oitava, 33 (39 incluindo configuração de função)

Usando a conversão numérica em matriz:

f=@(a)sum(mod(a./(num2str(a)-48),1))==0

Divida o número elemento a elemento pela matriz X, em que X é feito convertendo o número em sequência e subtraindo 48 para passar dos valores ASCII para números novamente. Tome o módulo 1 para obter a parte decimal de cada divisão, confirme que tudo isso é zero (se houver NaN por causa de / 0, a soma será NaN e, portanto, não é zero).

Exemplo de entrada usando www.octave-online.net:

f=@(a)sum(mod(a./(num2str(a)-48),1))==0
for j=[128,12,120,122,13,32,22,42,212,213,162,204]
f(j)
end

Resultado:

ans =  1
ans =  1
ans = 0
ans =  1
ans = 0
ans = 0
ans =  1
ans = 0
ans =  1
ans = 0
ans =  1
ans = 0

Como podemos testar isso?
Ismael Miguel

octave-online.net - digite a definição de código acima e depois (por exemplo) f (128). Adicionará saída
Jørgen 28/11

Eu tinha encontrado o compilador e tentei antes de perguntar. Mas parece funcionar bem (exceto f(123), que é divisível por 1, 2 e 3). Mas funciona para os casos de teste fornecidos.
Ismael Miguel

1

MATLAB - 39 caracteres

function [b] = dividesSelf(i)
b=all(~mod(i,sscanf(num2str(i),'%1d')))
end

1

BASH - 117 caracteres

f(){ [[ $1 =~ 0 ]]&& return 0 || r=;n=$1;for((i=0;i<${#n};i++));do r=$(($r+${n}%${n:$i:1}));done;return $(($r==0));}

testes

for N in 128 12 120 122 13 32 22 42 212 213 162 204; do
  f $N
  echo "${N} ->  $?"
done

128 ->  1
12 ->  1
120 ->  0
122 ->  1
13 ->  0
32 ->  0
22 ->  1
42 ->  0
212 ->  1
213 ->  0
162 ->  1
204 ->  0

1

PHP - 74 71 64 caracteres

Golfe:

function t($n){while($n>1){if(!($b=$n%10)||($n%$b)){return 0;}$n/=10;}return 1;}

Menos Golfe:

function t($n){
    while($n>1){
        if( !($b=$n%10) || ($n%$b) )
            { return 0; }
        $n/=10;
    }
    return 1;
}

Resultado dos testes:

(Código)

$ans = array(128,12,120,122,13,32,22,42,212,213,162,204);
foreach($ans as $a)
{ echo "$a -> ".(t($a)?"True":"False").PHP_EOL; }

(Resultado)

128 -> True
12 -> True
120 -> False
122 -> True
13 -> False
32 -> True
22 -> True
42 -> True
212 -> True
213 -> True
162 -> False
204 -> False
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.