Un nombre est-il divisible par chacun de ses chiffres?


47

Mon ami et moi travaillions sur un laboratoire dans notre classe AP Computer Science et avons décidé de coder le golf comme l’un des problèmes étant donné que nous avions encore la moitié de la classe libre après avoir terminé. Voici la question:

Soit un nombre n, n est-il divisible par chacun de ses chiffres?

Par exemple, 128 réussira ce test - il est divisible par 1,2 et 8. Tout nombre avec un zéro le disqualifie automatiquement. Bien que vous puissiez utiliser d'autres langages et proposer des solutions avec eux si vous le souhaitez, nous sommes particulièrement intéressés par la capacité des personnes compactes à créer le programme en Java, car c'est le langage que nous utilisons dans la classe. Jusqu'ici, nous avons tous les deux 51. Voici mon code actuel:

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.

Exigences

La signature de la méthode peut être celle que vous souhaitiez. Il suffit de compter le corps de la fonction. Assurez-vous cependant que la méthode retourne une valeur booléenne et ne transmet qu'un paramètre numérique (pas une chaîne).

Le code doit pouvoir passer tous ces cas (pour rester conforme aux indications de la question d'origine, seules les valeurs booléennes vraies et fausses sont prises en compte si la langue prend en charge les valeurs booléennes. Si et seulement si votre langue n'a pas de variables booléennes peut représenter faux avec 0 et vrai avec n'importe quel entier non nul (de préférence 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

De plus, nous ne comptons pas les espaces, alors n'hésitez pas à faire de même, à moins que les espaces ne soient essentiels au fonctionnement du programme (les nouvelles lignes en Java ne comptent pas, mais un seul espace sépare intet x=1compte.) Bonne chance !


18
Bienvenue chez PPCG! Quelques suggestions: 1. Ne pas compter les espaces blancs fonctionnels est une mauvaise idée. Toute réponse écrite en caractères blancs gagnera automatiquement. 2. Notre soumission doit-elle imprimer / retourner trueet / ou les valeurs vérité / falsificationfalse sont- elles également acceptables? 3. La javabalise ne s'applique pas vraiment ici, car le défi lui-même n'est pas lié à Java.
Dennis

D'accord. désolé pour les problèmes. Pour clarifier les choses, considéreriez-vous que l'espace dans 'int p = n' est fonctionnel, parce que je ne l'avais pas précédemment. Je vais régler les autres problèmes que vous avez signalés.
Mathew Kirschbaum

5
Tous les espaces nécessaires au fonctionnement du code sont fonctionnels.
FryAmTheEggman

Ok, merci pour la réponse!
Mathew Kirschbaum

1
@RickyDemer: étant donné que 0 constituerait une entrée exceptionnelle dans ce cas (c'est le seul nombre avec des 0chiffres qui soit un multiple de chacun d'eux), j'imagine que la plupart des réponses s'allongeraient simplement d'une manière inintéressante pour inclure un chèque. J'aime donc mieux le problème posé par le titre (divisible par ses chiffres, plutôt que d'être un multiple de ses chiffres, ce qui exclut 0).
Jeroen Mostert

Réponses:


23

Perl 6, 13

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

Utilise la variable implicite $_- $_ %% .comb.allest équivalent à $_ %% all($_.comb). %%est l'opérateur "est divisible" et combsans argument supplémentaire, retourne une liste des caractères d'une chaîne. Par exemple, si l'argument est 123, alors la fonction évalue

123 %% all(123.comb)

lequel est

123 %% all(1, 2, 3)

lecture automatique de jonction rend

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

lequel est

all(True, False, True)

ce qui est faux dans un contexte booléen car c'est une jonction "tout" et il est évident que tous ses éléments ne sont pas vrais.

Il devrait être possible de contraindre la valeur renvoyée Boolet de masquer la jonction aux appelants en donnant la signature de fonction sub golf($_ --> Bool()), mais les contraintes dans les signatures de fonction ne fonctionnent pas encore dans Rakudo. La valeur de retour est toujours correctement true ou false, ce n'est tout simplement pas Trueou False.


Si vous voulez le faire retourner, Boolajoutez simplement soau début du code so$_%%.comb.all.
Brad Gilbert b2gills

21

C # et System.Linq - 26/40

Selon les règles, sans compter la déclaration de méthode elle-même.

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

Cela prouve une fois de plus que C # est le meilleur choix lorsque Java est envisagé ... Je gamine, je gamine!

Malheureusement, cette fonction (et de nombreuses autres réponses) ne produira pas des résultats corrects pour une entrée négative. Nous pouvons y remédier, mais la solution perd beaucoup de son charme (et passe à 46 caractères):

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

Edit : rasé un personnage avec la suggestion de Tim.

Edit : avec l’introduction de membres à corps d’ expression en C # 6, nous pouvons réduire cela davantage en supprimant return:

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

pour un total de 26 caractères (à mon avis, le =>ne devrait pas être inclus, pas plus que les accolades). La version gérant les nombres négatifs peut être raccourcie de la même manière.


Pourquoi .0? Il n'y a pas besoin de rien d'autre que du module entier.
Peter Taylor

3
@PeterTaylor: Il y en a si vous voulez le programme le plus court - i % 0avec iun entier donne un DivideByZeroException.
Jeroen Mostert

2
Et avec un double ça donne NaN! Agréable!
Peter Taylor

2
48dest le même que 48.0, mais un caractère de moins (d pour double).
Tim S.

1
@StuartLC: les lambdas ne sont pas des méthodes; leur portée est différente, alors je pense que cela enfreint trop les règles. Mais depuis le n ° 6 (auquel cette réponse est antérieure), nous avons des membres avec une expression, ce qui nous permet de raccourcir la définition. Pour le cas négatif, nous ne pouvons pas utiliser &, précisément parce &que ne court-circuite pas - vous obtiendrez une exception de division par zéro le %. Nous pouvons résoudre ce problème en en faisant un double (avec d), mais nous avons encore perdu un caractère.
Jeroen Mostert

18

APL ( 13 11)

(apparemment les crochets ne comptent pas)

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

Explication:

  • ⍎¨⍕⍵: évalue chaque caractère dans la représentation sous forme de chaîne de
  • ⍵|⍨: pour chacun de ceux-ci, trouver le modulo de celui-ci et
  • 0∧.=: voir si tous sont égaux à 0

Testcases:

      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 peut faire X%0? sans jeter?
Optimiseur

@Optimizer: oui. 0|Xdonne X.
marinus

Sucré. De plus, votre réponse est 11 octets, pas 13
Optimizer

9
Seul APL ne donnerait pas d'erreur sur modulo de 0, et se bloquerait sur l'évaluation d'un non bool comme bool;)
FryAmTheEggman

3
Un personnage plus court avec un train au lieu de dfn:(0∧.=⍎¨∘⍕|⊢)
ngn

14

Python 2: 43 caractères

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

Vérifie si le nombre a des restes non nuls, modulo ses chiffres, et en affiche la négation. Zéro chiffre est traité étrangement: puisque le calcul %0provoque une erreur, les chiffres de 0sont remplacés par .3, ce qui semble toujours donner un résultat différent de zéro à cause des inexactitudes en virgule flottante.

Le corps de la fonction est composé de 32 caractères.


14

Perl - 27 octets

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

Sans compter la signature de la fonction, comme indiqué.

Exemple d'utilisation:

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);
}

Exemple de sortie:

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

Réponse à la spécification du problème: "Seules les valeurs booléennes vraies et fausses comptent. Les valeurs Truthy / Falsey ne comptent pas ."

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

Les sorties:

1
""

'True' et 'False' sont définis comme 1et "".

Erratum:
Comme Brad Gilbert l'a fait remarquer à juste titre , perl définit true comme un scalaire qui est à la fois l'entier 1et la chaîne "1", et false comme un scalaire qui est à la fois l'entier 0et la chaîne "".


Cela peut être raccourci par ne pas utiliser $_: pop=~s///ger<1. Je ne sais pas si le PO en conviendra 1et ce ""sont des résultats valables. Sinon, il peut être corrigé avec deux octets supplémentaires: il suffit d'ajouter |0.
hvd

perl -pe'$_=s/./!$&||$_%$&/ger<1|0'est de 26 octets, y compris le drapeau |0et -p. Vous n'êtes pas obligé d'utiliser une fonction.
hmatt1

1
En réalité, les valeurs True et False ressemblent davantage à dualvar(1,'1')and dualvar(0,'').
Brad Gilbert b2gills

1
@ BradGilbert C'est intéressant. Je connais assez bien Perlguts, mais je ne savais pas que vrai et faux étaient des cas spéciaux. Ce sont en fait des "triples scalaires", marqués comme SVIV(int), SVNV(double) et SVPV(chaîne).
Primo

1
En fait, la première fois que vous utilisez une chaîne en tant que nombre ou un nombre en tant que chaîne, la variable est modifiée pour contenir ces données supplémentaires. C'est pourquoi vous ne recevez un avertissement que la première fois que vous utilisez 'abc'un nombre (en supposant que vous ayez use warnings;activé la fonction.)
Brad Gilbert b2gills

13

CJam, 11 à 10 octets

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

Ceci définit une fonction nommée Fet supprime le bloc de la pile.

Essayez-le en ligne.

Cas de test

$ 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]

Comment ça fonctionne

_      " 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.                                        ";

CJam avait-il les fonctionnalités que vous aviez utilisées pour la solution à 10 octets lors de la rédaction de la question?
lirtosiast

@ThomasKwa: Oui, c'est bien ça. J'ai testé le code dans la version 0.6.2, parue en juillet 2014.
Dennis

12

JavaScript ES6, 39 32 28 octets

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

Merci core1024 pour la suggestion de remplacer (""+v).split("")par [...""+v], et openorclose pour suggérer l'utilisation de la everyfonction.

La réponse actuellement ne contient pas un bit de mon code: O

Solution précédente

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

==""n'est pas un moyen valable pour vérifier si un tableau est vide, puisque les [""]==""retourstrue , mais il est garanti que le tableau contiendra une chaîne non vide, donc cela fonctionne ici.

Le reste est une conversion de type sténographie tout à fait standard en JavaScript.


1
Vous pouvez sauvegarder certaines caractéristiques en remplaçant (""+v).split("")par [...""+v].
core1024

1
Pourquoi ne pas utiliser la everyméthode? v=>[...""+v].every(x=>v%x<1);
Ouvert ou fermé

@openorclose: Merci. Jamais eu l'occasion de l'utiliser dans JS, donc je n'ai jamais pensé à rechercher une telle fonction.
nh̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

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

@ l4m2 Depuis v%0renvoie NaNet NaN == false, ainsi, dans votre cas, les numéros contenant 0, tels que 10, peuvent être renvoyés true.
Shieru Asakoto

9

Java 8, 46 octets (corps de la méthode)

Utiliser la conversion de Jeroen Mostert en double tour.

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

8

Pyth, 12 octets

!f|!vT%vzvTz

Ceci filtre les caractères de la chaîne pour qu’ils soient zéro ( !vT) ou ne divisent pas l’entrée (%vzvT ), puis prend le pas logique de la liste résultante.

Essayez-le ici.


Non, ça va si une fonction n'est pas utilisée. Je voulais simplement signaler à quiconque utilisait des fonctions qu'il n'était pas nécessaire qu'il compte la déclaration, mais uniquement le code qu'il contenait.
Mathew Kirschbaum

8

Ruby, 44 octets (corps de la fonction: 37)

A probablement le potentiel d'être joué au golf plus loin.

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

Entrée prise par la fonction f. Exemple d'utilisation:

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

1
Vous pouvez changer .to_ien .hex, puisque les nombres à un chiffre sont les mêmes en base 16 et peuvent changer ==0en <1.
Histocrat

8

Python - 59 50 49 47 octets

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

Je suis sûr qu'il y a un moyen plus rapide ... ah bon.

Edit - Merci à FryAmTheEggman pour les astuces de golf.

Edit 2 - FryAmTheEggman peut aussi bien avoir écrit ceci à ce stade, oups

Edit 3 - Mains levées si vous ne saviez même pas que genexps était une chose. ...Juste moi?


Oh merci beaucoup! Je n'arrête pas d'oublier toutes ces choses. (Je ne savais pas non plus que vous pouviez moins que des personnages de cette façon.)
Kasran

Oh, renversant la logique semble aussi raccourcir un peu: f=lambda n:all([c>'0'and 0==n%int(c)for c in`n`]). Et pas de problème :)
FryAmTheEggman

Oh, je ne savais pas là , même était une allméthode.
Kasran

Serait 1>n%int(c)travailler?
Sp3000

3
Pourquoi une liste-compréhension? Utiliser un genexp: all(c>'0'and 0==n%int(c)for c in`n`)fait exactement la même chose, avec 2 caractères de moins et même en sauvegardant l’allocation de la liste.
Bakuriu

8

Pyth 11

!f%Q|vT.3`Q

Ceci combine les réponses de @ isaacg et de @ xnor . Il filtre les chiffres de l'entrée en vérifiant la valeur de input % (eval(current_digit) or .3). Ensuite, il vérifie si la chaîne résultante est vide ou non.

Entré dans une autre paire de variantes de même longueur:

!f%Q|T.3jQT
!f|!T%QTjQT

Essayez-le en ligne.


5

Bash + coreutils, 44 octets

La définition complète de la fonction est:

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

Je ne suis pas sûr de savoir comment marquer cela car normalement les fonctions shell utilisent un seul ensemble {}ou ()contiennent le corps de la fonction. J'ai trouvé ici que je pourrais aussi utiliser double (())pour contenir le corps de la fonction, ce qui provoque une expansion arithmétique, ce dont j'ai besoin ici. Donc, pour l'instant, je ne compte qu'une paire de ces crochets. Nous vous invitons à en discuter davantage.

Sortie:

$ 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 $
$

Euh - ce n'est pas clair pour moi si les 1 et les 0 sont acceptables ou si je dois imprimer true/ false?
Digital Trauma

4

J - 14 caractères

Le corps de fonction est la partie après le =:. Si nous voulons minimiser le nombre de caractères pour l'ensemble de la fonction, il s'agit du 15 caractères */@(0=,.&.":|]).

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

,.&.":est le moyen le plus court en J pour développer un nombre dans une liste de chiffres décimaux: convertir en chaîne, séparer les chiffres et reconvertir chaque chiffre en un nombre. ,.&.":|]prend le nombre d'entrée ( ]) modulo ( |) ces chiffres. 0*/@:=renvoie vrai si tous les résultats étaient 0, sinon donne un faux.

   f 162
1
   f every 204 212 213
0 1 0

3

Java - 121 102 97 79 78 octets

Je sais juste que ça va se tasser plus tard. Tant pis.

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;}

Je reviendrai.


1
Vous pouvez maintenant nommer votre fonction comme vous le souhaitez. J'ai changé les règles pour que vous ne comptiez que les calculs à l'intérieur de la fonction réelle, mais la fonction doit renvoyer un type booléen. Donc, cela fait actuellement 86 caractères.
Mathew Kirschbaum

3

Haskell - 100 54 38

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

Toujours en train d'apprendre, critiques appréciées


J'avais un commentaire ici, mais je l'ai accidentellement effacé en quelque sorte ... Quoi qu'il en soit, quelques suggestions: 1) Supprimez les lengths, ils sont inutiles. 2) Remplacer tpar sa définition. 3) elem y sest inutile. 4) /='0'peut être déplacé vers le filtre de gauche, à la place de elem y s. 5) Dans ce cas, /='0'est équivalent à >'0', puisque chaque lettre est un chiffre. 6) Mettre moden backticks, il devient infixe. 7) Mettez tout sur une seule ligne.
Zgarb

1 et 3 datent de l'époque où j'essayais de le faire différemment et de récupérer du code. Merci pour les conseils.
Globby

1
mes suggestions: au lieu d'utiliser, s==filter(...)svous devriez utiliser all(...)s. maintenant, comme elle sn'apparaît qu'une fois dans l'expression, vous pouvez la remplacer par sa définition et la supprimer where. aussi, au lieu de ==0vous pourriez utiliser <1.
fier haskeller

grande amélioration par rapport à la première version!
fier haskeller

Je pense que vous pouvez toujours perdre un octet si vous remplacez all(\y->...)$show xpar and[...|y<-show x].
Zgarb

2

CJam, 15 octets

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

C'est un bloc, l'élément le plus proche d'une fonction dans CJam. Je ne compte que le corps (c'est-à-dire en omettant les accolades). Vous pouvez l'utiliser comme suit:

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

Ou si vous voulez tester une série d'entrées, vous pouvez faire

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

Le bloc laisse 0(fausseté) ou 1(vérité) sur la pile pour indiquer le résultat. (CJam n'a pas de type booléen.)

Testez-le ici.

Explication:

_               "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.";

Alternative, aussi 15 octets

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

Explication

: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 octets

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

{}est la chose la plus proche d'une fonction dans CJam. Je ne fais que compter le corps de la fonction

Utilisez-le comme ceci:

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

Pour obtenir soit 1(si le nombre est divisible) ou 0(si le nombre n'est pas divisible par ses chiffres).

Essayez-le en ligne ici

Explication

_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";

Il se peut que je manque quelque chose, mais après une lecture rapide de CJam, certaines choses ne semblent pas avoir de sens: comment Abscinder les chiffres? Il semble simplement le convertir en base 10. De plus, comment% sait-il modifier le nombre, et pas seulement le chiffre suivant, puisqu'il semble que le prochain chiffre serait le suivant sur la pile?
Mathew Kirschbaum

Répondre à toutes vos questions sera délicat. Ce serait super facile à apprendre en mettant ed après chaque caractère du code. Essayez de courir128{ed_edAedbedf{ed_ed{ed%ed}1ed?ed}ed1edbed!ed}~
Optimizer

1
Réponses à des questions particulières: la base 10 donne un tableau de nombres convertis en base 10, qui sont les chiffres eux-mêmes dans ce cas. %prenez simplement les deux derniers chiffres (dans ce cas) et calculez le mod. Les deux derniers chiffres représentent le nombre et le chiffre réels (toujours)
Optimiseur

D'accord. Merci pour le conseil!
Mathew Kirschbaum

2

C89, 43 octets

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

C89 n'a pas de type booléen. J'espère que ça marche. De plus, j'ai utilisé un deuxième paramètre pour transmettre une copie du numéro d'origine à travers la pile, mais la définition peut être n'importe quoi. Pour obtenir le résultat correct, il vous suffit d'appeler la fonction avec la même valeur pour les deux paramètres ( d(128, 128)).

MODIFIER: modifications suggérées appliquées par un utilisateur anonyme


Jetez un coup d'oeil à codegolf.stackexchange.com/review/suggested-edits/17160 , quelqu'un vous a donné quelques suggestions pour jouer au golf
Justin

Spécifiquement contre les règles. Un paramètre.
Edc65

Eh oui, cet article est en fait la raison pour laquelle j'ai décidé de faire cette règle, car il ne semblait pas normal que l'utilisateur fasse la duplication à la place du programme.
Mathew Kirschbaum

Je suppose que je vais devoir ajouter une fonction wrapper. La déclaration de cette fonction ajoute-t-elle au nombre d'octets?
MarcDefiant

2

C11 - 44 octets dans le corps de la fonction

Une autre version C, non récursive et sans exception en virgule flottante.

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

Cela fonctionnera également en C ++, Java et la plupart des autres langages de type C.

Édité pour inclure l'amélioration du commentaire de primo.


1
Une version compilée en Java (1.7.0_45-b18):, int n=i;for(;i%10>0&&n%(i%10)<1;i/=10);return i<1;un octet plus court que le code de l'OP.
Primo

2

Julia 32 25 23

Amélioré en utilisant des chiffres

Corrige aussi le problème avec les nombres négatifs

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

Ancienne méthode

Tous les chiffres se divisent si la somme de tous les restes est 0. Comme les autres, il y a un problème avec les nombres négatifs.

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

Sortie

[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

La méthode améliorée gère également BigInt

selfDivides(BigInt(11111111111111111111111111111111111111112))
true

pourtant

selfDivides(BigInt(11111111111111111111111111111111111111113))
false

parce que

BigInt(11111111111111111111111111111111111111113) %3
1

2

C / C ++, 58 octets (44 dans le corps)

Invoque un comportement non défini (voir les commentaires)

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

trueet false sont 1 et 0, mais n'hésitez pas à ajouter un caractère à la signature pour renvoyer un bool.

Et pour le plaisir, une version récursive qui est plus petite si vous autorisez les appels de la forme r(128,128)

Edit : Désactivé par les règles:

C / C ++, 53 octets (33 dans le corps)

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


2
# 1 meurt avec une exception de virgule flottante pour les nombres contenant un 0 parce que j% (i% 10) sera illégal pour i% 10 = 0.
SBI

Une exception en virgule flottante ? Bizarre. Cela fonctionne parfaitement sur mon compilateur mais vous avez raison, c'est un comportement indéfini. Vous ne savez pas quelle est la position générale du responsable sur UB dépendant du compilateur.
etheranger

Qu'est-ce qu'un "UB dépendant du compilateur"? C'est UB ou ce n'est pas (et la division par zéro, ou plutôt le modulo zéro, est bien UB). UB ne devrait pas être autorisé, car littéralement, tout pourrait arriver. Nous pouvons supposer que votre programme fonctionnera sur une machine qui va exploser et tuer tout le monde autour de lui quand une division par zéro se produira. Maintenant, je suis sûr que vous voulez que nous vivions tous ... C a un concept de comportement défini par la mise en œuvre, mais diviser par zéro ne relève pas de cela.
Jeroen Mostert

2
@etheranger: La division par 0 est appelée exception de virgule flottante pour une raison historique: stackoverflow.com/questions/16928942/…
nh̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

2
@JeroenMostert: Je dirais que plus de 90% de toutes les réponses C sur ce site invoquent UB. Tant que cela fonctionne avec un compilateur sur une machine, la réponse est considérée comme valide.
Dennis

2

R: 72 67 65

La fonction

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

Merci à @AlexA et @plannapus pour les économies réalisées

Essai

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

Je compte actuellement 70 octets dans votre corps de fonction, pas 72. Mais vous pouvez le réduire à 67 en utilisant d=as.double(strsplit(toString(a),"")[[1]]);!(anyNA(a%%d)|sum(a%%d)). :)
Alex A.

@Alexa. Merci. Une de mes premières tentatives avec R. reviendra certainement :)
MickyT

@MickyT paste(a)au lieu de toString(a)donne le même résultat.
plannapus

@ Plannapus Merci, chouette petite astuce. Doit se rappeler que
MickyT

1

GNU Awk: 53 caractères

La partie comptée:

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

La fonction entière:

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

    return ! r
}

Comme Awk n'a pas de valeur booléenne, retourne 1 pour vrai et 0 pour faux.


1

JavaScript (ES6) 30

Fonction avec un paramètre numérique. En utilisant% et soustraction, inutile de mettre le cas spécial '0' car 0% 0 est NaN en JavaScript.

Éditer sauvegardé 1 caractère DocMax

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

Juste pour le plaisir, abusant de la règle de ne pas compter la signature de fonction, 4

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

Tester dans la console FireFox / FireBug

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

Sortie

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

Je vais dire non à la saisie d'une chaîne.
Mathew Kirschbaum

1
La console Firefox est satisfaite du remplacement de of(t=n+'')par juste of t=n+''pour économiser 1.
DocMax

1

PHP: 85 octets (64 octets sur le corps)

Pour que cette fonction fonctionne, il suffit de passer une chaîne ou un nombre.

0 retournera correctement false.

Le code:

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

S'il vous plaît, NE PAS DÉFINIR LE 2ÈME PARAMÈTRE!

Javascript: 76 octets (61 octets sur le corps)

Ceci est une réécriture de la fonction précédente.

Pas beaucoup changé entre les deux versions.

Voici le code:

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

Polyglot: Javascript + PHP 187 217 octets (76 84 octets sans passe-partout):

Pourquoi je l'ai fait?

À cause de la raison et peut-être parce que je peux!

Ignorez simplement l'erreur sur PHP: cela fonctionne quand même!
Plus nécessaire, cela a été corrigé en supprimant 3 octets.

Voici le chef d'oeuvre:

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);}

Vous pouvez exécuter ce code à la fois sur votre console et sur un interpréteur PHP!


Ancienne version:

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);}

"et passe seulement dans un paramètre numérique". Sans cela, vous pouvez évaluer ($ x) et transmettre le code entier dans $ x
abc667

@ abc667 Désolé, mais je ne comprends pas.
Ismael Miguel

1

Octave, 33 (39 avec configuration des fonctions)

Utilisation de la conversion numérique en matrice:

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

Divisez le nombre élément par élément de la matrice X, où X est obtenu en convertissant un nombre en chaîne et en soustrayant 48 pour passer de nouveau des valeurs ASCII à des nombres. Prenez modulo 1 pour obtenir la partie décimale de chaque division, confirmez que toutes ces valeurs sont égales à zéro (le cas échéant, NaN en raison de / 0, la somme sera NaN et donc non nulle).

Exemple de saisie avec 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

Sortie:

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

Comment pouvons-nous tester cela?
Ismael Miguel

octave-online.net - entrez la définition du code ci-dessus, puis (par exemple) f (128). Ajoutera une sortie
Jørgen

J'avais trouvé le compilateur et l'avais essayé avant de demander. Mais cela semble bien fonctionner (sauf pour f(123)ce qui est divisible par 1, 2 et 3). Mais cela fonctionne pour les cas de test fournis.
Ismael Miguel

1

MATLAB - 39 caractères

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

1

BASH - 117 caractères

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));}

tests

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 caractères

Golfé:

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

Moins golfé:

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

Résultats de test:

(Code)

$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; }

(Sortie)

128 -> True
12 -> True
120 -> False
122 -> True
13 -> False
32 -> True
22 -> True
42 -> True
212 -> True
213 -> True
162 -> False
204 -> False
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.