42
\$\begingroup\$

Given a positive integer as input, your task is to output a truthy value if the number is divisible by the double of the sum of its digits, and a falsy value otherwise (OEIS A134516). In other words:

(sum_of_digits)*2 | number
  • Instead of truthy / falsy values for the true and false cases, you may instead specify any finite set of values for the true/false case, and their complement the other values. For a simple example, you may use 0 for the true case and all other numbers for the false case (or vice versa, if you like).

  • Standard input and output rules apply. Default Loopholes also apply.

  • You can take input as an integer or as the string representation of that integer.

  • This is , hence the shortest code in bytes wins!

  • I am new to PPCG, so I would like you to post an explanation if it's possible.


Test Cases

Input - Output - (Reason)

80  - Truthy - (16 divides 80)
100 - Truthy - (2 divides 100)
60  - Truthy - (12 divides 60)
18 - Truthy - (18 divides 18)
12 - Truthy - (6 divides 12)

4 - Falsy - (8 does not divide 4)
8 - Falsy - (16 does not divide 8)
16  - Falsy  - (14 does not divide 16)
21 - Falsy - (6 does not divide 21)
78  - Falsy  - (30 does not divide 78)
110 - Falsy - (4 does not dide 110)
111 - Falsy - (6 does not divide 111)
390 - Falsy  - (24 does not divide 390)
\$\endgroup\$
11
  • \$\begingroup\$ Good challenge, welcome to PPCG! \$\endgroup\$
    – Mayube
    Commented Jul 3, 2017 at 13:59
  • \$\begingroup\$ @Mayube Thanks, it is my second challenge, but the first one got closed :P \$\endgroup\$
    – user70974
    Commented Jul 3, 2017 at 14:00
  • \$\begingroup\$ Are we allowed to take digits as a list of Integers? \$\endgroup\$
    – Henry
    Commented Jul 3, 2017 at 14:32
  • 5
    \$\begingroup\$ @Henry No, that would be way too trivial \$\endgroup\$
    – user70974
    Commented Jul 3, 2017 at 14:34
  • 1
    \$\begingroup\$ Indeed, the two sentences of "Instead of truthy / falsy values for the true and false cases, you may instead specify any finite set of values for the true case, and their complement for the falsy ones. For a simple example, you may use 0 for the true case and all other numbers for the false case (or vice versa, if you like)" seem to contradict each other (in particular, the "finite" and the "or vice versa"). \$\endgroup\$ Commented Jul 4, 2017 at 2:52

82 Answers 82

15
\$\begingroup\$

JavaScript (ES6), 31 29 27 bytes

Takes input as a string. Returns zero for truthy and non-zero for falsy.

n=>n%eval([...n+n].join`+`)

Commented

n => n % eval([...n + n].join`+`)
n =>                                   // take input string n  -> e.g. "80"
                  n + n                // double the input     -> "8080"
              [...     ]               // split                -> ["8", "0", "8", "0"]
                        .join`+`       // join with '+'        -> "8+0+8+0"
         eval(                  )      // evaluate as JS       -> 16
     n %                               // compute n % result   -> 80 % 16 -> 0

Test cases

let f =

n=>n%eval([...n+n].join`+`)

console.log('[Truthy]');
console.log(f("80"))
console.log(f("100"))
console.log(f("60"))
console.log(f("18"))
console.log(f("12"))

console.log('[Falsy]');
console.log(f("4"))
console.log(f("8"))
console.log(f("16"))
console.log(f("21"))
console.log(f("78"))
console.log(f("110"))
console.log(f("111"))
console.log(f("390"))

\$\endgroup\$
2
  • \$\begingroup\$ I've never seen the [...x] method of splitting before, is there a name for this specifically? \$\endgroup\$
    – user65631
    Commented Nov 23, 2017 at 19:02
  • \$\begingroup\$ @JacobPersi This is the spread operator. \$\endgroup\$
    – Arnauld
    Commented Nov 23, 2017 at 20:07
9
\$\begingroup\$

Neim, 3 bytes

𝐬ᚫ𝕞

Explanation:

𝐬      Implicitly convert to int array and sum the digits
 ᚫ     Double
  𝕞   Is it a divisor of the input?

Try it online!

Detailed version

\$\endgroup\$
5
  • \$\begingroup\$ Umm...you should check if the input is a multiple of double the sum of the digits, not vice versa. \$\endgroup\$ Commented Jul 3, 2017 at 13:31
  • \$\begingroup\$ @EriktheOutgolfer What do you mean? I do check if the input is a multiple of double the sum of the digits. Perhaps I did not explain it correctly. \$\endgroup\$
    – Okx
    Commented Jul 3, 2017 at 13:32
  • 4
    \$\begingroup\$ Neim needs to get even golfier - when submissions get too long, my browser starts to lag. \$\endgroup\$ Commented Jul 8, 2017 at 18:12
  • 3
    \$\begingroup\$ @Challenger5 I sincerely apologise for the lack of golfiness. I will try again next time. Again, sorry about that. \$\endgroup\$
    – Okx
    Commented Jul 8, 2017 at 19:59
  • \$\begingroup\$ @Okx And I sincerely apologize for being too lazy to find a Neim answer that was a better demonstration of what I was talking about. \$\endgroup\$ Commented Jul 8, 2017 at 21:48
7
\$\begingroup\$

C#, 46 bytes

using System.Linq;n=>n%(n+"").Sum(c=>c-48)*2<1

Full/Formatted version:

using System;
using System.Linq;

class P
{
    static void Main()
    {
        Func<int, bool> f = n => n % (n + "").Sum(c => c - 48) * 2 < 1;

        Console.WriteLine(f(80));
        Console.WriteLine(f(100));
        Console.WriteLine(f(60));

        Console.WriteLine();

        Console.WriteLine(f(16));
        Console.WriteLine(f(78));
        Console.WriteLine(f(390));

        Console.ReadLine();
    }
}
\$\endgroup\$
5
\$\begingroup\$

Retina, 38 27 bytes

-11 bytes and fixed an error with the code thanks to @MartinEnder

$
$_¶$_
.+$|.
$*
^(.+)¶\1+$

Try it online!

Prints 1 if divisible, 0 otherwise

Explanation (hope I got this right)

$
$_¶$_

Appends the entire input, plus a newline, plus the input again

.+$|.
$*

Converts each match to unary (either the entire second line which is the original input, or each digit in the first line)

^(.+)¶\1+$

Check if the first line (the doubled digit sum) is a divisor of the second line

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

x86-64 Machine Code, 24 bytes

6A 0A 5E 31 C9 89 F8 99 F7 F6 01 D1 85 C0 75 F7 8D 04 09 99 F7 F7 92 C3

The above code defines a function in 64-bit x86 machine code that determines whether the input value is divisible by double the sum of its digits. The function conforms to the System V AMD64 calling convention, so that it is callable from virtually any language, just as if it were a C function.

It takes a single parameter as input via the EDI register, as per the calling convention, which is the integer to test. (This is assumed to be a positive integer, consistent with the challenge rules, and is required for the CDQ instruction we use to work correctly.)

It returns its result in the EAX register, again, as per the calling convention. The result will be 0 if the input value was divisible by the sum of its digits, and non-zero otherwise. (Basically, an inverse Boolean, exactly like the example given in the challenge rules.)

Its C prototype would be:

int DivisibleByDoubleSumOfDigits(int value);

Here are the ungolfed assembly language instructions, annotated with a brief explanation of the purpose of each instruction:

; EDI == input value
DivisibleByDoubleSumOfDigits:
   push 10
   pop  rsi             ; ESI <= 10
   xor  ecx, ecx        ; ECX <= 0
   mov  eax, edi        ; EAX <= EDI (make copy of input)

SumDigits:
   cdq                  ; EDX <= 0
   div  esi             ; EDX:EAX / 10
   add  ecx, edx        ; ECX += remainder (EDX)
   test eax, eax
   jnz  SumDigits       ; loop while EAX != 0
   
   lea  eax, [rcx+rcx]  ; EAX <= (ECX * 2)
   cdq                  ; EDX <= 0
   div  edi             ; EDX:EAX / input
   xchg edx, eax        ; put remainder (EDX) in EAX
   ret                  ; return, with result in EAX

In the first block, we do some preliminary initialization of registers:

  • PUSH+POP instructions are used as a slow but short way to initialize ESI to 10. This is necessary because the DIV instruction on x86 requires a register operand. (There is no form that divides by an immediate value of, say, 10.)
  • XOR is used as a short and fast way to clear the ECX register. This register will serve as the "accumulator" inside of the upcoming loop.
  • Finally, a copy of the input value (from EDI) is made, and stored in EAX, which will be clobbered as we go through the loop.

Then, we start looping and summing the digits in the input value. This is based on the x86 DIV instruction, which divides EDX:EAX by its operand, and returns the quotient in EAX and the remainder in EDX. What we'll do here is divide the input value by 10, such that the remainder is the digit in the last place (which we'll add to our accumulator register, ECX), and the quotient is the remaining digits.

  • The CDQ instruction is a short way of setting EDX to 0. It actually sign-extends the value in EAX to EDX:EAX, which is what DIV uses as the dividend. We don't actually need sign-extension here, because the input value is unsigned, but CDQ is 1 byte, as opposed to using XOR to clear EDX, which would be 2 bytes.
  • Then we DIVide EDX:EAX by ESI (10).
  • The remainder (EDX) is added to the accumulator (ECX).
  • The EAX register (the quotient) is tested to see if it is equal to 0. If so, we have made it through all of the digits and we fall through. If not, we still have more digits to sum, so we go back to the top of the loop.

Finally, after the loop is finished, we implement number % ((sum_of_digits)*2):

  • The LEA instruction is used as a short way to multiply ECX by 2 (or, equivalently, add ECX to itself), and store the result in a different register (in this case, EAX).

    (We could also have done add ecx, ecx+xchg ecx, eax; both are 3 bytes, but the LEA instruction is faster and more typical.)

  • Then, we do a CDQ again to prepare for division. Because EAX will be positive (i.e., unsigned), this has the effect of zeroing EDX, just as before.

  • Next is the division, this time dividing EDX:EAX by the input value (an unmolested copy of which still resides in EDI). This is equivalent to modulo, with the remainder in EDX. (The quotient is also put in EAX, but we don't need it.)

  • Finally, we XCHG (exchange) the contents of EAX and EDX. Normally, you would do a MOV here, but XCHG is only 1 byte (albeit slower). Because EDX contains the remainder after the division, it will be 0 if the value was evenly divisible or non-zero otherwise. Thus, when we RETurn, EAX (the result) is 0 if the input value was divisible by double the sum of its digits, or non-zero otherwise.

Hopefully that suffices for an explanation.
This isn't the shortest entry, but hey, it looks like it beats almost all of the non-golfing languages! :-)

\$\endgroup\$
4
\$\begingroup\$

MATL, 7 bytes

tV!UsE\

Outputs 0 if divisible, positive integer otherwise. Specifically, it outputs the remainder of dividing the number by twice the sum of its digits.

Try it online!

Explanation

t   % Implicit input. Duplicate
V!U % Convert to string, transpose, convert to number: gives column vector of digits
s   % Sum
E   % Times 2
\   % Modulus. Implicit display
\$\endgroup\$
4
\$\begingroup\$

05AB1E, 5 4 bytes

-1 byte thanks to Okx

SO·Ö

Try it online!

You can also remove the last Ö to get 0 for truthy and something else for falsy resulting in only 3 bytes but to me that just doesn't seem to appropriately fit the definition.

Explanation

SO·Ö
SO    # Separate the digits and sum them
  ·   # Multiply the result by two
   Ö  # Is the input divisible by the result?
\$\endgroup\$
2
  • \$\begingroup\$ You can golf it to 4 bytes by replacing %_ with Ö. \$\endgroup\$
    – Okx
    Commented Jul 3, 2017 at 13:24
  • \$\begingroup\$ This was exactly what I was about to post... lol \$\endgroup\$
    – Makonede
    Commented Nov 30, 2020 at 17:23
4
\$\begingroup\$

K (ngn/k), 15 14 bytes

{(2*+/10\x)!x}

Try it online!


0 is truthy

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Tacit but no shorter: !/|1(2*+/10\)\ \$\endgroup\$
    – doug
    Commented May 7, 2023 at 5:18
3
\$\begingroup\$

Japt, 7 4 bytes

Takes input as a string. Outputs 0 for true or a number greater than 0 for false, which, from other solutions, would appear to be valid. If not, let me know and I'll rollback.

%²¬x

Test it


Explanation

Implicit input of string U.
"390"

²

Repeat U twice.
"390390"

¬

Split to array of individual characters.
["3","9","0","3","9","0"]

x

Reduce by summing, automatically casting each character to an integer in the process.
24

%

Get the remainder of dividing U by the result, also automatically casting U to an integer in the process. Implicitly output the resulting integer.
6 (=false)

\$\endgroup\$
4
  • 2
    \$\begingroup\$ Your explanations usually use up a lot of vertical space, which I feel isn't needed. Either way, it's your answer. \$\endgroup\$
    – Okx
    Commented Jul 3, 2017 at 13:47
  • \$\begingroup\$ @Okx; I don't know how "usual" it can be when I only switched to this format a couple of days ago. \$\endgroup\$
    – Shaggy
    Commented Jul 3, 2017 at 13:51
  • 4
    \$\begingroup\$ I liked the explanation format. Was easy to follow, especially for this problem, as it was a linear reduction and moved down the page like a math problem. Just my two cents. \$\endgroup\$
    – Henry
    Commented Jul 3, 2017 at 14:34
  • 3
    \$\begingroup\$ This explaination format is a lot better than the usual format, especially for those who are not familiar with the languages. I wish other golfers using these golfing languages would do this too. \$\endgroup\$
    – Peter1807
    Commented Jul 3, 2017 at 14:48
3
\$\begingroup\$

C89, 55 53 bytes

(Thanks to Steadybox!

s,t;f(x){for(t=x,s=0;t;t/=10)s+=t%10;return x%(s*2);}

It takes a single input, x, which is the value to test. It returns 0 if x is evenly divisible by double the sum of its digits, or non-zero otherwise.

Try it online!

Ungolfed:

/* int */ s, t;
/*int */ f(/* int */ x)
{
    for (t = x, s = 0; t /* != 0 */; t /= 10)
        s += (t % 10);
    return x % (s * 2);
}

As you can see, this takes advantage of C89's implicit-int rules. The global variables s and t are implicitly declared as ints. (They're also implicitly initialized to 0 because they are globals, but we can't take advantage of this if we want the function to be callable multiple times.)

Similarly, the function, f, takes a single parameter, x, which is implicitly an int, and it returns an int.

The code inside of the function is fairly straightforward, although the for loop will look awfully strange if you're unfamiliar with the syntax. Basically, a for loop header in C contains three parts:

for (initialization; loop condition; increment)

In the "initialization" section, we've initialized our global variables. This will run once, before the loop is entered.

In the "loop condition" section, we've specified on what condition the loop should continue. This much should be obvious.

In the "increment" section, we've basically put arbitrary code, since this will run at the end of every loop.

The larger purpose of the loop is to iterate through each digit in the input value, adding them to s. Finally, after the loop has finished, s is doubled and taken modulo x to see if it is evenly divisible. (A better, more detailed explanation of the logic here can be found in my other answer, on which this one is based.)

Human-readable version:

int f(int x)
{
    int temp = x;
    int sum  = 0;
    while (temp > 0)
    {
        sum  += temp % 10;
        temp /= 10;
    }
    return x % (sum * 2);
}
\$\endgroup\$
3
  • \$\begingroup\$ You can save two bytes, if you use t instead of t>0 as the loop condition. \$\endgroup\$
    – Steadybox
    Commented Jul 4, 2017 at 12:33
  • \$\begingroup\$ Ah, of course! Good catch, @Steadybox. Not sure how I missed that, since testing against 0 is exactly what my asm implementation did, on which this answer was heavily based. \$\endgroup\$
    – Cody Gray
    Commented Jul 6, 2017 at 13:11
  • \$\begingroup\$ 45 \$\endgroup\$ Commented Nov 28, 2017 at 1:41
3
\$\begingroup\$

APL, 13 bytes

{⍵|⍨2×+/⍎¨⍕⍵}

Outputs 0 as a truthy value, and any other as falsy.

\$\endgroup\$
2
\$\begingroup\$

Brachylog, 8 bytes

ẹ+×₂;I×?

Try it online!

Explanation

ẹ+           Sum the digits
  ×₂         Double
    ;I×?     There is an integer I such that I×(double of the sum) = Input
\$\endgroup\$
2
\$\begingroup\$

Python 2, 34 32 bytes

-2 bytes thanks to @Rod

lambda n:n%sum(map(int,`n`)*2)<1

Try it online!

\$\endgroup\$
1
  • 6
    \$\begingroup\$ based on the example of "clearly distinguishable" provided in the question, I believe you can remove the <1. \$\endgroup\$
    – Wheat Wizard
    Commented Jul 3, 2017 at 13:34
2
\$\begingroup\$

Mathematica, 26 bytes

(2Tr@IntegerDigits@#)∣#&

No clue why has a higher precedence than multiplication...

\$\endgroup\$
2
\$\begingroup\$

PHP, 41 bytes

prints zero if divisible, positive integer otherwise.

<?=$argn%(2*array_sum(str_split($argn)));

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ You put the assignment in the header block. You might as well use $a=10, but you forgot to count that towards your byte count \$\endgroup\$
    – aross
    Commented Jul 5, 2017 at 9:34
  • \$\begingroup\$ @aross why should I count the input towards to my byte count. $argn is available with the -F (in this case) or -R option \$\endgroup\$ Commented Jul 5, 2017 at 10:48
  • \$\begingroup\$ Hm, interesting. I didn't know about -F. But that's not reflected in your TIO (does it support echoing from STDIN?). \$\endgroup\$
    – aross
    Commented Jul 5, 2017 at 11:53
  • \$\begingroup\$ @aross it works like your approach use only a file instead of code and the -Foption instead of -R php.net/manual/en/features.commandline.options.php If you found an better way to make the same in tio like in the commnd line let me know \$\endgroup\$ Commented Jul 5, 2017 at 12:03
2
\$\begingroup\$

Excel, 63 bytes

=MOD(A1,2*SUMPRODUCT(--MID(A1,ROW(OFFSET(A$1,,,LEN(A1))),1)))=0

Summing digits is the lengthy bit.

\$\endgroup\$
2
\$\begingroup\$

Perl 6, 19 bytes

{$_%%(2*.comb.sum)}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Husk, 9 8 bytes

Thanks to Leo for saving 1 byte.

Ṡ¦ȯ*2ṁis

Try it online!

Explanation

Ṡ¦ȯ         Test whether f(x) divides x, where f is the function obtained by
            composing the next 4 functions.
       s    Convert x to a string.
     ṁi     Convert each character to an integer and sum the result.
   *2       Double the result.
\$\endgroup\$
1
  • \$\begingroup\$ You can use ṁ to map and sum with a single command, saving one byte \$\endgroup\$
    – Leo
    Commented Jul 3, 2017 at 17:09
2
\$\begingroup\$

Haskell, 38 37 42 bytes

Thanks to Zgarb for golfing off 1 byte

f x=read x`mod`foldr((+).(*2).read.pure)0x

Try it online!

Takes input as a string; returns 0 if divisible and nonzero otherwise.

\$\endgroup\$
4
  • \$\begingroup\$ (:[]) can be pure. \$\endgroup\$
    – Zgarb
    Commented Jul 3, 2017 at 17:00
  • \$\begingroup\$ You will save 1 byte by replacing the lambda by function declaration \$\endgroup\$
    – bartavelle
    Commented Jul 4, 2017 at 6:37
  • \$\begingroup\$ @bartavelle: Pretty sure it's a wash. Example? \$\endgroup\$ Commented Jul 4, 2017 at 15:33
  • \$\begingroup\$ You're right, it is the exact same length. Not sure how that crossed my mind :/ \$\endgroup\$
    – bartavelle
    Commented Jul 4, 2017 at 15:43
2
\$\begingroup\$

Python 3, 35 bytes

lambda a:a%(sum(map(int,str(a)))*2)
\$\endgroup\$
4
  • \$\begingroup\$ Hello and welcome to the site. You can remove some whitespace here. Particularly around = and after the ) in int(c). In addition since sum can take a generator as an argument you can remove the [..] inside it. If you have any additional questions feel free to ping me. \$\endgroup\$
    – Wheat Wizard
    Commented Jul 4, 2017 at 15:58
  • \$\begingroup\$ int(c)for c in a could also be map(int,a), to save a few bytes. \$\endgroup\$
    – Wheat Wizard
    Commented Jul 4, 2017 at 16:52
  • \$\begingroup\$ This doesn't work - or rather, works backwards. Easily fixed with 4 extra bytes: lambda a:not a%(sum(map(int,str(a)))*2) \$\endgroup\$
    – osuka_
    Commented Nov 21, 2017 at 16:01
  • \$\begingroup\$ @osuka_ see bullet point one in the question description \$\endgroup\$
    – wrymug
    Commented Nov 21, 2017 at 16:08
2
\$\begingroup\$

TI-BASIC, 27 26 21 bytes

-5 thanks to @Oki

:fPart(Ans/sum(2int(10fPart(Ans10^(~randIntNoRep(1,1+int(log(Ans

This is made trickier by the fact that there is no concise way to sum integer digits in TI-BASIC. Returns 0 for True, and a different number for False.

Explanation:

:fPart(Ans/sum(2int(10fPart(Ans10^(-randIntNoRep(1,1+int(log(Ans
                               10^(-randIntNoRep(1,1+int(log(Ans #Create a list of negative powers of ten, based off the length of the input, i.e. {1,0.1,0.01}
                            Ans                                  #Scalar multiply the input into the list
                    10fPart(                                     #Remove everything left of the decimal point and multiply by 10
               2int(                                             #Remove everything right of the decimal point and multiply by 2
           sum(                                                  #Sum the resulting list
       Ans/                                                      #Divide the input by the sum
:fPart(                                                          #Remove everything left of the decimal, implicit print
\$\endgroup\$
1
  • 2
    \$\begingroup\$ 10^-randIntNoRep(1,1+int(log(Ans does the same as seq(10^(~A-1),A,0,log(Ans in fewer bytes as order doesnt matter (Assuming version 2.55MP) \$\endgroup\$
    – Oki
    Commented Jul 9, 2017 at 18:01
2
\$\begingroup\$

Java (OpenJDK 8), 40 bytes

i->i%(i+"").chars().map(k->k*2-96).sum()

Try it online!

Returns 0 as truthy value and a value greater than 0 as falsy value.

\$\endgroup\$
2
\$\begingroup\$

Add++, 11 bytes

L,EDEs;A@%!

Try it online!

First time I've used either a Lambda or ; in an Add++ answer

How it works

L,   - Create a lambda function. Example argument; 172
  ED - Push the digits;   STACK = [[1 7 2]]
  Es - Stack-clean sum;   STACK = [10]
  ;  - Double;            STACK = [20]
  A  - Push the argument; STACK = [20 172] 
  @% - Modulo;            STACK = [12]
  !  - Logical NOT;       STACK = [0]
\$\endgroup\$
2
\$\begingroup\$

Husk, 6 5 bytes

¦DΣd¹

Try it online!

-1 byte from Dominic Van Essen.

The existing answer doesn't use enough builtins, and Martin Ender is inactive, so I decided to post this.

\$\endgroup\$
2
  • \$\begingroup\$ 5 bytes... \$\endgroup\$ Commented Nov 30, 2020 at 16:24
  • \$\begingroup\$ @DominicvanEssen thanks! \$\endgroup\$
    – Razetime
    Commented Nov 30, 2020 at 17:10
2
\$\begingroup\$

Zsh, 37 bytes

for ((;i++<19;a+=2*s[i]))s=$1;((s%a))

Try it online!

Outputs by exit code - 0 is falsey, 1 is truthy.

Explanation:

for ((;i++<19;a+=2*s[i]))s=$1;((s%a))    # i implicitly starts at 0
                         s=$1;           # set s to the input
for ((;                ))                # loop
          <19;                           #  while i is less than 19 (*)
       i++                               #  increment i
                   s[i]                  #  take the i'th character of s
                 2*                      #  doubled
              a+=                        #  add to a
                                s%a      # remainder of s divided by a
                              ((   ))    # output 0 if it's non-zero, 1 if it's zero

(*19 is the length of the maximum integer zsh can handle)

\$\endgroup\$
2
\$\begingroup\$

Swift, 53 46 bytes

Takes in a String or Substring representing an integer in [1, 255].

{UInt8($0)!%($0.utf8.reduce(0){$0+$1-48}*2)<1}

Try it online!

Type information not included, since it could be either:

let f: (String) -> Bool = {UInt8($0)!%($0.utf8.reduce(0){$0+$1-48}*2)<1}
let g: (Substring) -> Bool = {UInt8($0)!%($0.utf8.reduce(0){$0+$1-48}*2)<1}

Swift Character is... weird. It's not a single byte, like in C (that's CChar), but it's also not a single Unicode codepoint (that's Unicode.Scalar). Rather, it represents an extended grapheme cluster. This makes certain oprations substantially more painful, but others substantially easier. For this reason, I access the string's utf8 property (which is a collection of UInt8).

String and Substring are collections of Character; however, they also have a lot more shared functionality than e.g. [Character] because they conform to StringProtocol, and are in fact the only types that conform to it. I thought StringProtocol would work as the input type, but then the type checker times out.

For 49 bytes, here's a version that accepts integers in [1, 2^31 - 1] or [1, 2^63 - 1] depending on the machine:

{Int($0)!%($0.utf8.reduce(0){$0+Int($1)-48}*2)<1}

Explanation/Ungolfed

{ (number: String) -> Bool in
    return
        UInt8(number)! // Convert String to UInt8, force-unwrap optional
            % (
                number.utf8 // Convert String to byte array
                    .reduce(0) { (prevResult: UInt8, nextChar: Character) -> UInt8 in
                        return prevResult + nextChar - 48
                        // Convert ASCII to number by subtracting 48; sum the results
                    } * 2
            ) == 0 // convert number to boolean
}
\$\endgroup\$
1
\$\begingroup\$

Braingolf, 13 12 bytes

VR.Mvd&+2*c%

Try it online!

Outputs 0 for truthy, any other number for falsey.

Explanation

VR.Mvd&+2*c%  Implicit input from command-line args
VR            Create stack2, return to stack1
  .M          Duplicate input to stack2
    vd        Switch to stack2, split into digits
      &+      Sum up all digits
        2*    Double
          c   Collapse stack2 back into stack1
           %  Modulus
              Implicit output of last item on stack
\$\endgroup\$
1
\$\begingroup\$

Japt, 7 bytes

vUì x*2

Returns 1 for true, 0 for false

Try it online!

Explanation

vUì x*2
v        // Return 1 if the input is divisible by:
 Uì      //   Input split into a base-10 array
    x    //   Sum the array
     *2  //   While mapped by *2
\$\endgroup\$
1
  • \$\begingroup\$ I came up with a few other 7 byte solutions for this, too (although, I don't think this was one of them) - I'm convinced there's a shorter solution, though. \$\endgroup\$
    – Shaggy
    Commented Jul 3, 2017 at 15:36
1
\$\begingroup\$

Haskell, 49 Bytes

f x=(==) 0.mod x.(*)2.sum.map(read.return).show$x

Usage

f 80

Try it online!

\$\endgroup\$
1
  • 3
    \$\begingroup\$ Tips: there is an extra space, return==pure, list comprehensions are often very compact : Try it online! \$\endgroup\$
    – bartavelle
    Commented Jul 3, 2017 at 16:41
1
\$\begingroup\$

Java, 66 bytes

-1 byte thanks to Olivier

a->{int i=0;for(int b:(""+a).getBytes())i+=b-48;return a%(i*2)<1;}

Ungolfed & explanation:

a -> {
    int i = 0;

    for(int b : (""+a).getBytes()) { // Loop through each byte of the input converted to a string
        i += b-48; // Subtract 48 from the byte and add it to i
    }

    return a % (i*2) < 1 // Check if a % (i*2) is equal to one
    // I use <1 here for golfing, as the result of a modulus operation should never be less than 0
}
\$\endgroup\$
5
  • \$\begingroup\$ Use int instead of byte to save... a byte. \$\endgroup\$ Commented Jul 3, 2017 at 14:42
  • \$\begingroup\$ @OlivierGrégoire Thanks. Didn't notice that. \$\endgroup\$
    – Okx
    Commented Jul 3, 2017 at 14:45
  • \$\begingroup\$ @Okx Need to change golfed code as well. \$\endgroup\$
    – Henry
    Commented Jul 3, 2017 at 14:48
  • \$\begingroup\$ Your (golfed) code gives incorrect values for 110, 111. Probably the a%i*2 that's parsed as (a%i)*2 since modulus and multiplication have the same order. \$\endgroup\$ Commented Jul 3, 2017 at 14:52
  • \$\begingroup\$ @OlivierGrégoire Ah, that sucks. \$\endgroup\$
    – Okx
    Commented Jul 3, 2017 at 14:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.