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

-1
\$\begingroup\$

Java 7, Score = 96 76

Since I can't compete with your number based method, I used a character based method instead. a has the input integer in it.

int c=0;for(char e:(""+a).toCharArray())c+=(e-=-48)<1||a%e>0?1:0;return c<1;

Here it is golfed indented with structure code:

public class T{

    public static void main(String[] args){
        System.out.println(new T().test(Integer.parseInt(args[0])));
    }

    boolean test(int a){
        int c=0;
        for(char e:(""+a).toCharArray())
            c+=(e-=-48)<1||a%e>0?1:0;
        return c<1;
    }

}

Here it is completely expanded:

public class Test{

    public static void main(String[] args){
        System.out.println(new Test().test(Integer.parseInt(args[0])));
    }

    boolean test(int number){
        String numberString = "" + number;
        int failed = 0;
        for (int a = 0; a < numberString.length(); a++){
            int charAt = numberString.charAt(a) - '0';
            if (charAt == 0 || number % charAt != 0){
                failed++;
            }
        }
        return failed < 1;
    }

}

Edit: Used Mathew Kirschbaum's suggestions to shorten code size.

\$\endgroup\$
  • \$\begingroup\$ On first glance, I see a few places where you can shorten this by relatively large amounts. First, you can change for(;d<b.length();d++) to for(char d:b). That form of for is essentially a foreach loop. That will also shorten b.charAt(d) to just d, as well as remove the declaration of d in your second statement. Since b isn't used anywhere in the code other than the for condition anymore, you can get rid of it entirely and just replace the previously changed for(char d:b) to for(char d:a+""). That brings you to 62 or so. \$\endgroup\$ – Mathew Kirschbaum Nov 27 '14 at 2:56
  • 1
    \$\begingroup\$ According to docs.oracle.com/javase/specs/jls/se7/html/…, you cannot use a for each loop to iterate over a string. You can only iterate over collections and arrays. I'll try to find something that is similar, though. \$\endgroup\$ – TheNumberOne Nov 27 '14 at 22:19
-1
\$\begingroup\$

Mathematica - 93ish characters

Robert G Wilson v gives us the following for Mathematica:

Function definition:

fQ[n_] :=
  Block[{id = Union[IntegerDigits[n]]},
   Union[IntegerQ[#] & /@ (n/id)] == {True}];

To call:

Select[Range[487], fQ[#] &]

Output (ignoring divide by zero complaints):

{1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 22, 24, 33, 36, 44, 48, 55, 
66, 77, 88, 99, 111, 112, 115, 122, 124, 126, 128, 132, 135, 144, 
155, 162, 168, 175, 184, 212, 216, 222, 224, 244, 248, 264, 288, 312, 
315, 324, 333, 336, 366, 384, 396, 412, 424, 432, 444, 448}
\$\endgroup\$
  • 3
    \$\begingroup\$ How can you have -ish on a character count? \$\endgroup\$ – Beta Decay Dec 3 '14 at 19:26
  • \$\begingroup\$ Converting to Community Wiki, as this is not your own work. \$\endgroup\$ – Doorknob Jul 8 '15 at 11:43
  • \$\begingroup\$ Oh, dear, the hallway monitor police are out. I gave full full credit, but I've broken some mysterious "rule" and so get castigated. This is precisely why I've given up even trying to contribute to StackExchange: aside from the privileged core who got in early, they just look down their noses at anyone new. Thanks for the -1. \$\endgroup\$ – Slaughterteddy May 2 at 8:54
-1
\$\begingroup\$

Scala (56 chars: 21 for header and 35 for body)

def f(n:Int):Boolean=n==0||n%10!=0&&n%(n%10)==0&&f(n/10)

Old (81):

def f(n:Int):Boolean=if(n==0)true else if(n%10==0)false else n%(n%10)==0&&f(n/10)
\$\endgroup\$
  • \$\begingroup\$ error: recursive method f needs result type \$\endgroup\$ – Jacob Dec 3 '14 at 19:00

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.