47
\$\begingroup\$

My friend and I were working on a lab in our AP Computer Science class and decided to code golf one one the problems since we still had half the class free after we finished. Here is the question:

Given a number n, is n divisible by each of its digits?

For example, 128 will pass this test- it is divisible by 1,2, and 8. Any numbers with a zero automatically disqualify the number. While you may use other languages and post solutions with them if you like, we are most interested in seeing how compact people can make the program in Java, as that is the language we use in the class. So far, we both have 51. Here is my current code:

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.

Requirements

The method signature can be whatever you want. Just count the function body. Make sure, though, that the method returns a boolean value and only passes in one numeric parameter (not a string).

The code must be able to pass all of these cases (in order to stay true to the directions of the original question, only boolean true and false values count if the language supports booleans. If and only if your language does not have boolean variables you may represent false with 0 and true with any nonzero integer (preferably 1 or -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

Also, we didn't count whitespace, so feel free to do the same, unless the whitespace is essential to the working of the program (so newlines in Java don't count, but a single space between int and x=1 does count.) Good luck!

\$\endgroup\$
  • 18
    \$\begingroup\$ Welcome to PPCG! A few suggestions: 1. Not counting functional whitespace is a bad idea. Any answer written in Whitespace will automatically win. 2. Should our submission print/return true and false or are truthy/falsy values OK as well? 3. The java tag doesn't really apply here, as the challenge itself is unrelated to Java. \$\endgroup\$ – Dennis Nov 26 '14 at 3:37
  • \$\begingroup\$ Okay. sorry for the issues. Just to clear it up, would you consider the space in 'int p=n' to be functional, because I did not previously. I will fix the other issues you pointed out. \$\endgroup\$ – Mathew Kirschbaum Nov 26 '14 at 3:41
  • 5
    \$\begingroup\$ All whitespace required for the code to work is functional. \$\endgroup\$ – FryAmTheEggman Nov 26 '14 at 3:42
  • \$\begingroup\$ Okay, thanks for the response! \$\endgroup\$ – Mathew Kirschbaum Nov 26 '14 at 3:47
  • 1
    \$\begingroup\$ @RickyDemer: since 0 would be an exceptional input in that case (it's the only number with 0 digits that is a multiple of each of them), I imagine most answers would just get longer in an uninteresting way to include a check for it. So I like the problem as posed by the title better (divisible by its digits, rather than being a multiple of its digits, which excludes 0). \$\endgroup\$ – Jeroen Mostert Nov 26 '14 at 22:07

63 Answers 63

23
\$\begingroup\$

Perl 6, 13

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

Uses the implicit variable $_$_ %% .comb.all is equivalent to $_ %% all($_.comb). %% is the "is divisible" operator, and comb with no additional argument returns a list of the characters in a string. As an example, if the argument is 123, then the function evaluates

123 %% all(123.comb)

which is

123 %% all(1, 2, 3)

junction autothreading makes it

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

which is

all(True, False, True)

which is false in boolean context because it's an "all" junction and clearly not all of its elements are true.

It should be possible to coerce the return value to Bool and hide the junction-ness from callers by making the function signature sub golf($_ --> Bool()), but coercions in function signatures don't work yet in Rakudo. The return value is still correctly true or false, it's just not True or False.

\$\endgroup\$
  • \$\begingroup\$ If you want to make it return a Bool just add so to the front of the code so$_%%.comb.all. \$\endgroup\$ – Brad Gilbert b2gills Nov 28 '14 at 13:44
21
\$\begingroup\$

C# and System.Linq - 26 / 40

Per the rules, not counting the method declaration itself.

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

Showing that once again, C# is the superior choice when Java is under consideration... I kid, I kid!

Unfortunately, this function (and many in other answers) will not produce correct results for negative input. We can fix this, but the solution loses a lot of its charm (and grows to 46 characters in length):

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

Edit: shaved off one character with Tim's suggestion.

Edit: with the introduction of expression-bodied members in C# 6, we can pare this down further by cutting out the return:

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

for a total of 26 characters (in my opinion, the => should not be included any more than braces would be). The version handling negative numbers can be similarly shortened.

\$\endgroup\$
  • \$\begingroup\$ Why .0? There's no need for anything other than integer modulus. \$\endgroup\$ – Peter Taylor Nov 26 '14 at 9:34
  • 3
    \$\begingroup\$ @PeterTaylor: There is if you want the shortest program -- i % 0 with i an integer gives a DivideByZeroException. \$\endgroup\$ – Jeroen Mostert Nov 26 '14 at 9:36
  • 2
    \$\begingroup\$ And with a double it gives NaN! Nice! \$\endgroup\$ – Peter Taylor Nov 26 '14 at 9:39
  • 2
    \$\begingroup\$ 48d is the same as 48.0, but one less character (d for double). \$\endgroup\$ – Tim S. Nov 26 '14 at 21:10
  • 1
    \$\begingroup\$ @StuartLC: lambdas aren't methods; their scope is different, so I think that's bending the rules too far. But since C# 6 (which this answer predates), we have expression-bodied members, which do allow us to shorten the definition. For the negative case, we can't use &, precisely because & doesn't short-circuit -- you'll get a divide by zero exception on the %. We can fix that by making it a double (with d), but then we've lost one character again. \$\endgroup\$ – Jeroen Mostert Nov 17 '17 at 11:25
18
\$\begingroup\$

APL (13 11)

(apparently the brackets don't count)

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

Explanation:

  • ⍎¨⍕⍵: evaluate each character in the string representation of
  • ⍵|⍨: for each of those, find the modulo of it and
  • 0∧.=: see whether all of those are equal to 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
\$\endgroup\$
  • \$\begingroup\$ APL can do X%0 ? without throwing ? \$\endgroup\$ – Optimizer Nov 26 '14 at 11:43
  • \$\begingroup\$ @Optimizer: yes. 0|X gives X. \$\endgroup\$ – marinus Nov 26 '14 at 11:46
  • \$\begingroup\$ Sweet. Also your answer is 11 bytes, not 13 \$\endgroup\$ – Optimizer Nov 26 '14 at 11:47
  • 9
    \$\begingroup\$ Only APL would not give an error on modulo by 0, and crash on evaluating a non-bool as a bool ;) \$\endgroup\$ – FryAmTheEggman Nov 26 '14 at 13:59
  • 3
    \$\begingroup\$ One character shorter with a train instead of dfn: (0∧.=⍎¨∘⍕|⊢) \$\endgroup\$ – ngn Dec 30 '14 at 1:48
14
\$\begingroup\$

Python 2: 43 chars

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

Checks whether the number has any nonzero remainders modulo its digits, and outputs the negation of that. Zero digits are handled strangely: since computing %0 causes an error, digits of 0 are replaced with .3, which seems to always give a nonzero result due to floating point inaccuracies.

The function body is 32 chars.

\$\endgroup\$
14
\$\begingroup\$

Perl - 27 bytes

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

Not counting the function signature, as instructed.

Sample Usage:

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

Sample Output:

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

Addressing the problem specification: "Only boolean true and false values count. Truthy/falsey values do not count."

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

Outputs:

1
""

'True' and 'False' are defined as 1 and "".

Erratum:
As Brad Gilbert rightly points out, perl defines true as a scalar which is both the integer 1 and the string "1" simultaneously, and false as a scalar which is both the integer 0 and the string "" simultaneously.

\$\endgroup\$
  • \$\begingroup\$ This can be shortened by not using $_: pop=~s///ger<1. I don't know whether the OP will agree that 1 and "" are valid results. If not, then it can be fixed with two more bytes: just add |0. \$\endgroup\$ – hvd Nov 26 '14 at 14:08
  • \$\begingroup\$ perl -pe'$_=s/./!$&||$_%$&/ger<1|0' is 26 bytes including the |0 and -p flag. You don't have to use a function. \$\endgroup\$ – hmatt1 Nov 26 '14 at 15:38
  • 1
    \$\begingroup\$ Actually the True and False values are more like dualvar(1,'1') and dualvar(0,''). \$\endgroup\$ – Brad Gilbert b2gills Nov 28 '14 at 13:48
  • 1
    \$\begingroup\$ @BradGilbert That is interesting. I am reasonably familiar with perlguts, but I wasn't aware that true and false were special cased. They're actually 'triple scalars', marked as SVIV (int), SVNV (double), and SVPV (string). \$\endgroup\$ – primo Nov 28 '14 at 14:59
  • 1
    \$\begingroup\$ Actually the first time you use a string as a number or a number as a string, the variable gets modified to hold that additional data. That is why you only get a warning the first time you use 'abc' as a number (assuming you have use warnings; enabled. ) \$\endgroup\$ – Brad Gilbert b2gills Nov 28 '14 at 15:43
13
\$\begingroup\$

CJam, 11 10 bytes

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

This defines a function named F and discards the block from the stack.

Try it online.

Test cases

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

How it works

_      " 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.                                        ";
\$\endgroup\$
  • \$\begingroup\$ Did CJam have the features you used for the 10-byte solution when the question was written? \$\endgroup\$ – lirtosiast Jul 8 '15 at 1:40
  • \$\begingroup\$ @ThomasKwa: Yes it did. I've tested the code in version 0.6.2, which was released in July 2014. \$\endgroup\$ – Dennis Jul 8 '15 at 2:34
12
\$\begingroup\$

JavaScript ES6, 39 32 28 bytes

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

Thanks core1024 for the suggestion to replace (""+v).split("") with [...""+v], and openorclose for suggesting the use of every function.

The answer currently doesn't contain one bit of my code :O

Previous solution

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

=="" is not a valid way to check if an array is empty, since [""]=="" returns true, but the array is guarantee to contain non-empty string, so it works here.

The rest are quite standard shorthand type conversion in JavaScript.

\$\endgroup\$
  • 1
    \$\begingroup\$ You can save some characteras by replacing (""+v).split("") with [...""+v]. \$\endgroup\$ – core1024 Nov 26 '14 at 11:53
  • 1
    \$\begingroup\$ Why not use the every method? v=>[...""+v].every(x=>v%x<1); \$\endgroup\$ – openorclose Nov 27 '14 at 2:24
  • \$\begingroup\$ @openorclose: Thanks. Never had a chance to use it in JS, so I never thought of searching for such function. \$\endgroup\$ – n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Nov 27 '14 at 2:35
  • \$\begingroup\$ v=>![...""+v].some(x=>v%x) \$\endgroup\$ – l4m2 Dec 17 '17 at 21:45
  • \$\begingroup\$ @l4m2 Since v%0 returns NaN and NaN == false, so in your case numbers that contains 0, such as 10, may return true. \$\endgroup\$ – Shieru Asakoto Dec 18 '17 at 4:26
9
\$\begingroup\$

Java 8, 46 Bytes (method body)

Using Jeroen Mostert's converting to double trick.

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

Pyth, 12 bytes

!f|!vT%vzvTz

This filters the characters in the string for being either zero (!vT) or not dividing the input (%vzvT), then takes the logical not of the resulting list.

Try it here.

\$\endgroup\$
  • \$\begingroup\$ No, I'm fine if a function is not used. I just wanted to point out to anybody that was using functions that they do not need to count the declaration, and only the code inside. \$\endgroup\$ – Mathew Kirschbaum Nov 26 '14 at 13:24
8
\$\begingroup\$

Ruby, 44 bytes (function body: 37)

Probably has potential to be golfed further.

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

Input taken through function f. Example usage:

f[128] # => true
f[12]  # => true
f[120] # => false
...
\$\endgroup\$
  • 1
    \$\begingroup\$ You can change .to_i to .hex, since single-digit numbers are the same in base 16, and can change ==0 to <1. \$\endgroup\$ – histocrat Nov 26 '14 at 16:12
8
\$\begingroup\$

Python - 59 50 49 47 bytes

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

I'm sure there's a faster way... oh well.

Edit - Thanks to FryAmTheEggman for the golfing tips.

Edit 2 - FryAmTheEggman may as well have written this at this point, oops

Edit 3 - Hands up if you didn't even know genexps were a thing. ...Just me?

\$\endgroup\$
  • \$\begingroup\$ Oh, thanks a lot! I keep forgetting about all those things. (I also didn't realize you could less-than chars in that way.) \$\endgroup\$ – Kasran Nov 26 '14 at 5:06
  • \$\begingroup\$ Oh, flipping the logic also seems to shorten it a bit: f=lambda n:all([c>'0'and 0==n%int(c)for c in`n`]). And no problem :) \$\endgroup\$ – FryAmTheEggman Nov 26 '14 at 5:11
  • \$\begingroup\$ Oh, I didn't realize there even was an all method. \$\endgroup\$ – Kasran Nov 26 '14 at 5:12
  • \$\begingroup\$ Would 1>n%int(c) work? \$\endgroup\$ – Sp3000 Nov 26 '14 at 8:36
  • 3
    \$\begingroup\$ Why a list-comprehension? Using a genexp: all(c>'0'and 0==n%int(c)for c in`n`) does exactly the same, with 2 char less and even saving the allocation of the list. \$\endgroup\$ – Bakuriu Nov 26 '14 at 10:33
8
\$\begingroup\$

Pyth 11

!f%Q|vT.3`Q

This combines @isaacg's and @xnor's answers. It filters out digits from the input by checking the value of input % (eval(current_digit) or .3). Then it checks if the resulting string is empty or not.

Came across another couple same-length variants:

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

Try it online.

\$\endgroup\$
5
\$\begingroup\$

Bash + coreutils, 44 bytes

The full function definition is:

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

I'm not sure how to score this as normally shell functions use a single set of {} or () to contain the function body. I found here I could also use double (()) to contain the function body which causes an arithmetic expansion which is what I need here. So for now I am counting just one pair of those brackets - further discussion of this is welcome.

Output:

$ 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 $
$
\$\endgroup\$
  • \$\begingroup\$ Uh - its not clear to me whether 1s and 0s are acceptable or if I have to print true/false? \$\endgroup\$ – Digital Trauma Nov 26 '14 at 5:21
4
\$\begingroup\$

J - 14 char

The function body is the portion after the =:. If we want to minimize the character count for the whole function, that's the 15 char */@(0=,.&.":|]).

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

,.&.": is the shortest way in J to expand as number into a list of its decimal digits: convert to string, separate the digits, and convert each digit back into a number. ,.&.":|] takes the input number (]) modulo (|) those digits. 0*/@:= returns true if all the results were 0, else gives a false.

   f 162
1
   f every 204 212 213
0 1 0
\$\endgroup\$
3
\$\begingroup\$

Java - 121 102 97 79 78 bytes

I just know this will get clobbered later. Oh well.

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

I'll be back.

\$\endgroup\$
  • 1
    \$\begingroup\$ You can now name your function whatever you want. I changed the rules so you only count the calculations inside the actual function, but the function must return a boolean type. So that is currently at 86 characters. \$\endgroup\$ – Mathew Kirschbaum Nov 26 '14 at 4:00
3
\$\begingroup\$

Haskell - 100 54 38

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

Still learning, critiques appreciated

\$\endgroup\$
  • \$\begingroup\$ I had a comment here, but I accidentally deleted it somehow... Anyway, some suggestions: 1) Drop the lengths, they are unnecessary. 2) Replace t by its definition. 3) elem y s is unnecessary. 4) /='0' can be moved to the left filter, in place of elem y s. 5) In this case, /='0' is equivalent to >'0', since every letter is a digit. 6) Put mod in backticks, so it becomes infix. 7) Put everything on a single line. \$\endgroup\$ – Zgarb Nov 26 '14 at 17:31
  • \$\begingroup\$ 1 and 3 were from when I was trying to do it a different way and salvaged code. Thanks for the tips. \$\endgroup\$ – globby Nov 27 '14 at 5:37
  • 1
    \$\begingroup\$ my suggestions: instead of using s==filter(...)s you should use all(...)s. now, because s only appears once in the expression, you can replace it with it's definition and drop where. also, instead of ==0 you could use <1. \$\endgroup\$ – proud haskeller Nov 28 '14 at 16:23
  • \$\begingroup\$ great improvement from the first version! \$\endgroup\$ – proud haskeller Nov 28 '14 at 16:27
  • \$\begingroup\$ I think you can still lose one byte if you replace all(\y->...)$show x by and[...|y<-show x]. \$\endgroup\$ – Zgarb Dec 1 '14 at 13:02
2
\$\begingroup\$

CJam, 15 bytes

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

This is a block, the closest thing to a function in CJam. I'm only counting the body (i.e. omitting the braces). You can use it as follows:

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

Or if you want to test a series of inputs, you can do

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

The block leaves 0 (falsy) or 1 (truthy) on the stack to indicate the result. (CJam doesn't have a Boolean type.)

Test it here.

Explanation:

_               "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, also 15 bytes

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

Explanation

: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.";
\$\endgroup\$
2
\$\begingroup\$

CJam, 15 bytes

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

{} is the closest thing to a function in CJam. I am just counting the body of the function

Use it like this:

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

To get either 1 (if the number is divisible) or 0 (if the number is not divisible by its digits).

Try it online here

Explanation

_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";
\$\endgroup\$
  • \$\begingroup\$ I might be missing something, but after quickly reading up on CJam, some things seems to not make sense: how does Ab split the digits? It seems to just convert it to base 10. Also, how does % know to mod by the number, and not just the next digit, since it seems that the next digit would be next on the stack? \$\endgroup\$ – Mathew Kirschbaum Nov 26 '14 at 13:54
  • \$\begingroup\$ Answering all your question will be tricky. It would be super easy to learn by putting ed after each character in the code. Try running 128{ed_edAedbedf{ed_ed{ed%ed}1ed?ed}ed1edbed!ed}~ \$\endgroup\$ – Optimizer Nov 26 '14 at 14:19
  • 1
    \$\begingroup\$ Answers to particular questions : doing base 10 gives an array of base 10 converted numbers, which are the digits themselves in this case. % simply take the last two numbers (in this case) and calculate the mod. Last two numbers here are the actual number and digit (always) \$\endgroup\$ – Optimizer Nov 26 '14 at 14:23
  • \$\begingroup\$ Okay, thanks for the advice! \$\endgroup\$ – Mathew Kirschbaum Nov 26 '14 at 14:23
2
\$\begingroup\$

C89, 43 bytes

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

C89 doesn't have a boolean type. Hope that works. Also I used a second parameter to pass a copy of the original number through the stack, but the definition can be anything. To get the correct result you just have to call the function with the same value for both parameters (d(128, 128)).

EDIT: Applied suggested edits by an anonymous user

\$\endgroup\$
  • \$\begingroup\$ Take a look at codegolf.stackexchange.com/review/suggested-edits/17160 , someone gave you some golfing suggestions \$\endgroup\$ – Justin Nov 26 '14 at 11:31
  • \$\begingroup\$ Specifically against the rules. One parameter. \$\endgroup\$ – edc65 Nov 26 '14 at 17:07
  • \$\begingroup\$ Yup, this post is actually why I decided to make that rule, as it didn't seem right that the user should do the duplication instead of the program. \$\endgroup\$ – Mathew Kirschbaum Nov 27 '14 at 2:59
  • \$\begingroup\$ I guess I'll have to add a wrapper function. Does the declaration of that function add to the byte count? \$\endgroup\$ – MarcDefiant Dec 1 '14 at 8:00
2
\$\begingroup\$

C11 - 44 Bytes in function body

Another C version, non recursive and without a floating point exception.

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

This will also work in C++, Java, and most other C-like languages.

Edited to include the improvement of primo's comment.

\$\endgroup\$
  • 1
    \$\begingroup\$ A version that compiles in Java (1.7.0_45-b18): int n=i;for(;i%10>0&&n%(i%10)<1;i/=10);return i<1;, one byte shorter than the OP's code. \$\endgroup\$ – primo Nov 27 '14 at 8:25
2
\$\begingroup\$

Julia 32 25 23

Improved using digits

Also fixes problem with negative numbers

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

Old method

All digits divide if the sum of all the remainders is 0. Like others, has a problem with negative numbers.

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

Output

[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

Improved method also handles BigInt

selfDivides(BigInt(11111111111111111111111111111111111111112))
true

however

selfDivides(BigInt(11111111111111111111111111111111111111113))
false

because

BigInt(11111111111111111111111111111111111111113) %3
1
\$\endgroup\$
2
\$\begingroup\$

C / C++, 58 bytes (44 in body)

Invokes Undefined Behaviour (see comments)

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

true and false are 1 and 0, but feel free to add one character to the signature to return a bool.

And for fun, a recursive version which is smaller if you allow calls of the form r(128,128)

Edit: Now disallowed by the rules:

C / C++, 53 bytes (33 in body)

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

\$\endgroup\$
  • 2
    \$\begingroup\$ #1 dies with a floating point exception for numbers containing a 0 because j%(i%10) will be illegal for i%10 = 0. \$\endgroup\$ – SBI Nov 26 '14 at 10:03
  • \$\begingroup\$ A floating point exception? Weird. It works perfectly on my compiler but you're right, it's undefined behaviour. Not sure what the general PCG stance on compiler-dependent UB is. \$\endgroup\$ – etheranger Nov 26 '14 at 23:33
  • \$\begingroup\$ What's "compiler-dependent UB"? Either it's UB or it isn't (and division by zero, or rather modulo zero, is indeed UB). UB shouldn't be allowed because literally anything could happen. We may assume your program will run on a machine that will blow up and kill everyone around it when a division by zero happens. Now, I'm sure you want us all to live... C does have a concept of implementation-defined behavior, but dividing by zero doesn't fall under that. \$\endgroup\$ – Jeroen Mostert Nov 27 '14 at 11:57
  • 2
    \$\begingroup\$ @etheranger: Division by 0 is called floating point exception for historical reason: stackoverflow.com/questions/16928942/… \$\endgroup\$ – n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Nov 27 '14 at 16:29
  • 2
    \$\begingroup\$ @JeroenMostert: I'd say over 90 % of all C answers on this site invoke UB. As long as it works with some compiler on some machine, the answer is considered valid. \$\endgroup\$ – Dennis Nov 28 '14 at 13:53
2
\$\begingroup\$

R: 72 67 65

The function

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

Thanks to @AlexA and @plannapus for the savings

Test run

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
\$\endgroup\$
  • \$\begingroup\$ I count 70 bytes in your function body currently, not 72. But you can get it down to 67 using d=as.double(strsplit(toString(a),"")[[1]]);!(anyNA(a%%d)|sum(a%%d)). :) \$\endgroup\$ – Alex A. Jul 7 '15 at 20:07
  • \$\begingroup\$ @AlexA. Thanks. One of my first attempts wih R. Will definitely revisit:) \$\endgroup\$ – MickyT Jul 7 '15 at 21:09
  • \$\begingroup\$ @MickyT paste(a) instead of toString(a) gives the same result. \$\endgroup\$ – plannapus Jul 9 '15 at 14:03
  • \$\begingroup\$ @plannapus Thanks, neat little trick. Must remember that \$\endgroup\$ – MickyT Jul 9 '15 at 22:24
1
\$\begingroup\$

GNU Awk: 53 characters

The counted part:

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

The entire function:

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

    return ! r
}

As Awk has no boolean values, returns 1 tor true and 0 for false.

\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6) 30

Function with one numeric parameter. Using % and subtraction, no need to special case '0' because 0%0 is NaN in JavaScript.

Edit Saved 1 char thx DocMax

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

Just for fun, abusing the rule about not counting function signature, 4

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

Test In FireFox/FireBug console

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

Output

128 -> true
12 -> true
120 -> false
122 -> true
13 -> false
32 -> false
22 -> true
42 -> false
212 -> true
213 -> false
162 -> true
204 -> false
\$\endgroup\$
  • \$\begingroup\$ I'm going to say no to inputting a string. \$\endgroup\$ – Mathew Kirschbaum Nov 26 '14 at 17:44
  • 1
    \$\begingroup\$ The Firefox console is happy with the replacement of of(t=n+'') with just of t=n+'' to save 1. \$\endgroup\$ – DocMax Nov 26 '14 at 22:05
1
\$\begingroup\$

PHP: 85 bytes (64 bytes on the body)

For this function to work, simply pass a string or a number.

0 will correctly return false.

The code:

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

Please, DO NOT SET THE 2ND PARAMETER!

Javascript: 76 bytes (61 bytes on the body)

This is a rewrite of the previous function.

Not much changed between both versions.

Here is the 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 bytes (76 84 bytes without boilerplate):

Why I made it?

Because of reason and maybe because I can!

Just ignore the error on PHP: it works anyway!
No longer needed, this was fixed by removing 3 bytes.

Here is the masterpiece:

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

You can run this code both on your console and on a PHP interpreter!


Old 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);}
\$\endgroup\$
  • \$\begingroup\$ "and only passes in one numeric parameter". Without this you can eval($x) and pass whole code in $x \$\endgroup\$ – abc667 Jan 1 '15 at 11:35
  • \$\begingroup\$ @abc667 Sorry, but I don't get it. \$\endgroup\$ – Ismael Miguel Jan 1 '15 at 14:11
1
\$\begingroup\$

Octave, 33 (39 including function setup)

Using numeric-to-matrix conversion:

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

Divide number elementwise by matrix X, where X is made by converting number to string and subtracting 48 to go from ASCII values to numbers again. Take modulo 1 to get decimal part of each division, confirm that all of these are zero (if any are NaN because of /0, the sum will be NaN and hence not zero).

Sample input using 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

Output:

ans =  1
ans =  1
ans = 0
ans =  1
ans = 0
ans = 0
ans =  1
ans = 0
ans =  1
ans = 0
ans =  1
ans = 0
\$\endgroup\$
  • \$\begingroup\$ How can we test this? \$\endgroup\$ – Ismael Miguel Nov 28 '14 at 13:40
  • \$\begingroup\$ octave-online.net - enter the code definition from above and then (for example) f(128). Will add output \$\endgroup\$ – Jørgen Nov 28 '14 at 13:55
  • \$\begingroup\$ I had found the compiler and tried it before asking. But it seems to work fine (except for f(123), which is divisible by 1, 2 and 3). But it does work for the test-cases provided. \$\endgroup\$ – Ismael Miguel Nov 28 '14 at 14:12
1
\$\begingroup\$

MATLAB - 39 characters

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

BASH - 117 characters

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
\$\endgroup\$
1
\$\begingroup\$

PHP - 74 71 64 Characters

Golfed:

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

Less Golfed:

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

Test Results:

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

(Output)

128 -> True
12 -> True
120 -> False
122 -> True
13 -> False
32 -> True
22 -> True
42 -> True
212 -> True
213 -> True
162 -> False
204 -> False
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.