TransWikia.com

Am I a Self Number?

Code Golf Asked by Sok on December 10, 2021

A self number (also called a Colombian or Devlali number) is a natural number, x, where the equation n + <digit sum of n> = x has no solutions for any natural number n. For example, 21 is not a self number, as n = 15 results in 15 + 1 + 5 = 21. On the other hand, 20 is a self number, as no n can be found which satisfies such an equality.

As this definition references the digit sum, it is base dependent. For the purposes of this challenge, we will only be considering base 10 self numbers, which are sequence A003052 in the OEIS. Binary (A010061) and base 100 (A283002) self numbers have also been calalogued.

The Challenge

Given a positive integer x as input, output a truthy value if x is a self number in base 10, and a falsey value otherwise. For clarification of truthy and falsey values, refer to this meta post on the subject.

You may write a full program or function, and input and output may be provided on any of the usual channels. Standard loopholes are, of course, banned.

This is , so the shorter your answer (in bytes) the better!

Test cases

Truthy:

1
3
5
7
9
20
31
86
154
525

Falsey:

2
4
6
8
10
15
21
50
100
500

Sandbox link

Leaderboards

Here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language.

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

# Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

# Ruby, <s>104</s> <s>101</s> 96 bytes

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

# Perl, 43 + 2 (-p flag) = 45 bytes

You can also make the language name a link which will then show up in the leaderboard snippet:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes
var QUESTION_ID=159881,OVERRIDE_USER=41020;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<hd>s*([^n,]*[^s,]),.*?(d+)(?=[^nd<>]*(?:<(?:s>[^n<>]*</s>|[^n<>]+>)[^nd<>]*)*</hd>)/,OVERRIDE_REG=/^Overrides*header:s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

34 Answers

Perl 5 -apl -MList::Util=sum,all, 28 bytes

$_=all{"@F"-sum/./g,$_}1..$_

Try it online!

Answered by Xcali on December 10, 2021

Scala, 44 42 bytes

x=>0 to x forall(n=>x!=(n/:s"$n")(_+_-48))

Try it online

Answered by HALP DA MODS 11'D MY NAM on December 10, 2021

Io, 81 bytes

Io doesn't allow split("") or list-based base conversion. Therefore I need to do a terrible chain of type conversions...

method(n,Range 1 to(n)map(i,i+i asString asList map(asNumber)sum)indexOf(n)==nil)

Try it online!

Answered by user92069 on December 10, 2021

J, 20 bytes

#@-.i.+1#.10#.inv i.

Try it online!

                  i.     Range [0,n-1]
          10#.inv        To base 10
       1#.               Sum the digits
    i.+                  Plus the corresponding number
  -.                     Remove from the input, leaves an empty list if it was a self number.
#@                       An empty list is truthy, so return the length instead.

Answered by FrownyFrog on December 10, 2021

Pyt, 7 bytes

ĐřĐŚ+∈¬

Try it online!

If swapping truthy/falsy values is allowed, then the ¬ at the end can be dropped for 6 bytes.

Explanation:

        Implicit input
Đ       Duplicate input
ř       Get [1,2,...,input]
Đ       Duplicate the top of the stack
Ś       Get the sum of the digits of each element in the array
+       Add the top two items on the stack element-wise
∈       Is the input in the list?
¬       Negate the top of the stack
        Implicit print

Answered by mudkip201 on December 10, 2021

Stax, 8 bytes

Å8avj╒Éπ

Run and debug it

Explanation

ASCII equivalent:

{cE+|+x=f!
{       f     Filter [1..input] with block
 cE           Decimal digits of current value
   +|+        Sum of digits and the current value
      x=      Equals input
         !    Logical not, maps empty array to 1 and non-empty array to 0

fcE+|+x= is a Stax program that outputs all numbers whose sum of digits added to itself equals the input. For example for 101 the output would be 91 and 100, each on a separate line.

Run and debug it

Answered by Weijun Zhou on December 10, 2021

Elixir, 66 65 bytes

fn a->!Enum.any?1..a,fn b->a==b+Enum.sum Integer.digits b end end

Try it online!

Answered by Okx on December 10, 2021

Add++, 27 18 bytes

L,RFBDB+B]ARz€b+Ae

Try it online!

Answered by caird coinheringaahing on December 10, 2021

Kotlin, 48 bytes

x->(1..x).all{v->"$v".sumBy{it.toInt()-48}+v!=x}

Try it online!

Explanation:

(1..x)      // Range of numbers from 1 to x
.all{v->    // Function expression that checks if ALL values evaluate to tru
"$v"        // Convert the value into a string
.sumBy{it.toInt()-48} // For each character, get the ASCII char value, subtract 48 in order to get it back to the numerical value, and then sum it up
+v          // Add the original number
!=x}        // Ensure that it does not equal the input

Answered by Makotosan on December 10, 2021

Japt -d!, 6 bytes

N¥U+ìx

Try it


Original, 8 bytes

Returns the input number for truthy or 0 for falsey. If only the empty array were falsey in JavaScript, this could be 7 bytes.

ÂNkUÇ+ìx

Try it


Explanation

             :Implicit input of integer U
   UÇ        :Generate the range [0,U) and pass each Z through a function
      ì      :  Digits of Z
       x     :  Reduce by addition
     +       :  Add to Z
  k          :Remove the elements in that array
 N           :From the array of inputs
            :Bitwise NOT NOT (~~), casts an empty array to 0 or a single element array to an integer 

Alternative

Ç+ìxÃe¦U

Try it

             :Implicit input of integer U
Ç            :Generate the range [0,U) and pass each Z through a function
  ì          :  Digits of Z
   x         :  Reduce by addition
 +           :  Add to Z
    Ã        :End function
     e       :Every
      ¦U     :  Does not equal U

Answered by Shaggy on December 10, 2021

Bash + GNU Coreutils, 91 Bytes

Returns truthy or falsy.

e=1;for((i=1;i<=$1;i++));{ [ $(bc<<<`grep -o . <<<$i|tr 'n' +`$i) -eq $1 ]&&e=0; };exit $e

Answered by rexkogitans on December 10, 2021

Retina, 24 bytes

.+
*

$.`¶$`
d
*
D`
.z

Try it online!

Could be 18 bytes with input given in unary, but the other Retina answer uses decimal as well, so I figured using decimal would make for a fairer comparison.

Explanation

.+
*

Convert input to unary, using _ as the unary digit.


$.`¶$`

At each position in the string (i.e. beginning, end, and between every pair of characters), insert: $.`, the length of the prefix (or the zero-indexed position of the match), , a linefeed, $`, the prefix itself (i.e. a unary representation of the zero-indexed position). E.g. if the input was 3 and we'd have the unary representation ___, then this would result in:

0
_1
__2
___3
___

In other words, we get one line for each number from 0 to the input (inclusive), which holds both a unary and a decimal representation of that number.

d
*

We convert each digit to unary, which effectively computes the digit sum on each line and adds it to the number itself (all in unary).

D`

Deduplicate lines. This doesn't actually delete duplicate lines but just clears them to empty lines. So if any number from 0 to the input plus its digit sum is equal to the input, the last line will get cleared. Otherwise, the last line remains in place.

.z

Check whether there's still a character on the last line. We can't use $, because that also matches in front of a trailing linefeed (which is exactly where we don't want to look).

Answered by Martin Ender on December 10, 2021

Haskell, 46 bytes

f x=and[x/=n+sum[read[d]|d<-show n]|n<-[1..x]]

Try it online!

Answered by user1472751 on December 10, 2021

Attache, 31 20 bytes

${0={Sum@_+_=x}~1:x}

Try it online!

{Sum@_+_=x} performs the check, ~1:x counts how many occurrences of that check are in the range from 1 to x, and 0= asserts that there are no such elements.


Attache, 30 bytes

None##`=#{_+Sum=>Digits!_}@1&`:

Try it online!

Explanation

This is a composition (##) of two functions:

  • None
  • `=#{_+Sum=>Digits!_}@1&`:

This means that whatever the second function returns, None will ensure it contains no truthy values

The second function is a fork (#) of two functions:

  • `=
  • {_+Sum=>Digits!_}@1&`:

This means that, given an input n, this fork checks for equality with n and each member of this second function.

This second function is also a composition (@) of two functions, being {_+Sum=>Digits!_}, which sums the digits of the input and adds it to the input and applies this function to each member of the range from 1 to n (1&`:).

In summary, this checks that no (None) element added to its digits ({_+Sum=>Digits!_}) from 1 to n (1&`:) is equal to (`=) n.

Answered by Conor O'Brien on December 10, 2021

Brachylog, 12 bytes

¬{⟦∋Iẹ+;I+?}

Try it online!

Explanation

¬{         }    Fails if succeeds, suceeds if fails:
  ⟦∋I             I ∈ [0, ..., Input]
    Iẹ+           The sum of the elements (i.e. digits) of I...
       ;I+?       ... with I itself results in the Input

Answered by Fatalize on December 10, 2021

Pyth, 8 bytes

!/m+sjdT

Test suite.

If swapping truthy / falsy values is allowed, then we can drop the ! and get 7 bytes instead. One of Sok's suggestions helped me golf 2 bytes.

Explanation

!/m+sjdT – Full program. Takes an input Q from STDIN, outputs either True or False.
  m      – Map over the range [0 ... Q) with a variable d.
     jdT – Convert d to base 10.
    s    – Sum.
   +     – And add the sum to d itself.
 /       – Count the occurrences of Q in the result.
!        – Negate. Implicitly output the result.

Answered by Mr. Xcoder on December 10, 2021

Ruby, 38 bytes

->x{(1..x).all?{|n|n+n.digits.sum!=x}}

Try it online!

Answered by Kirill L. on December 10, 2021

Python 2, 70 66 Bytes

lambda x:[i for i in range(x)if i+sum([int(j)for j in`i`])==x]==[]

EDIT: -4 thanks to @user56656

Answered by sonrad10 on December 10, 2021

Java (JDK 10), 84 bytes

i->{for(int n=i;i-->1;)i|=((""+i).chars().map(x->x-48).sum()+i^n)-1>>-1;return~i<0;}

Try it online!

Explanation

i->{                                    // IntPredicate
  for(int n=i;i-->1;)                   //  for each number below n
    i|=(                                //   keep the sign of
      (""+i).chars().map(x->x-48).sum() //    sum of digits
      +i                                //    plus the number
      ^n                                //    xor n (hoping for a zero)
     )-1>>-1;                           //    changing that into a negative number if equals to zero
  return~i<0;                           //  return i>=0
}

Credits

Answered by Olivier Grégoire on December 10, 2021

Jelly, 6 bytes

ḟDS+Ɗ€

For input n, this returns [n] if n is a self number, [] if not.

Try it online!

How it works

ḟDS+Ɗ€  Main link. Argument: n

     €  Call the link to the left for each k in [1, ..., n].
    Ɗ     Drei; combine the three links to the left into a monadic chain.
 D          Decimal; map k to the array of its digits in base 10.
  S         Take the sum.
   +        Add k to the sum of the k's digits.
ḟ       Filterfalse; promote n to [n], then remove all elements that appear in the
        array to the right.
        This returns [n] if the array doesn't contain n, [] if it does.

Answered by Dennis on December 10, 2021

Octave, 37 bytes

@(n)sum(dec2base(t=1:n,10)'-48,1)+t-n

Port of my MATL answer.

Try it online!

Answered by Luis Mendo on December 10, 2021

APL (Dyalog), 14 bytes

~⊢∊⍳+(+/⍎¨∘⍕)¨∘⍳

Try it online!

How?

               ⍳   range
     (  ⍎¨∘⍕)      digits
     (+/    )      digit sums
   ⍳+              vectorized addition with the range
 ⊢∊                is the input included?
~                  negate

Answered by Uriel on December 10, 2021

J, 28, 24, 22 21 bytes

-1 byte thanks to Conor O'Brien

-2 byts thanks to ngn

$@-.(+1#.,.&.":)"+@i.

Try it online!

Explanation:

i. a list 0 .. n-1

( )"+ for each item in the list

.,.&.": convert it to a list of digits,

1# find their sum

+ and add it to the item

$@-. exclude the list from the argument and find the shape

Answered by Galen Ivanov on December 10, 2021

Perl 5 -a, 34 bytes

#!/usr/bin/perl -a
say!grep{s/./$_+=$&/reg;/@F/}1..$_

Try it online!

Answered by Ton Hospel on December 10, 2021

Haskell, 63 58 bytes

s 0=0
s x=x`mod`10+s(x`div`10)
f n=all(x->x+s x/=n)[1..n]

Try it online!

Answered by Cristian Lupascu on December 10, 2021

MATL, 11 bytes

t:tFYA!Xs+-

The output is a non-empty array, which is truthy if all its entries are non-zero, and falsy if it contains one or more zeros.

Try it online! Or verify all test cases, including truthiness/falsihood test.

Explanation

Consider input n = 10 as an example.

t       % Implicit input, n. Duplicate
        % STACK: 10, 10
:       % Range
        % STACK: 10, [1 2 3 4 5 6 7 8 9 10]
t       % Duplicate
        % STACK: 10, [1 2 3 4 5 6 7 8 9 10], [1 2 3 4 5 6 7 8 9 10]
FYA!    % Convert to base 10 digits and transpose
        % STACK: 10, [1 2 3 4 5 6 7 8 9 10], [0 0 0 0 0 0 0 0 0 1
                                              1 2 3 4 5 6 7 8 9 0]
Xs      % Sum of each column
        % STACK: 10, [1 2 3 4 5 6 7 8 9 10], [1 2 3 4 5 6 7 8 9 1]
+       % Add, element-wise
        % STACK: 10, [2 4 6 8 10 12 14 16 18 11]
-       % Subtract, element-wise
        % STACK: [8 6 4 2 0 -2 -4 -6 -8 -1]
        % Implicit display

Answered by Luis Mendo on December 10, 2021

C (gcc), 70 67 65 bytes

i,r,d,j;f(n){for(r=i=n;d=j=--i;r*=d!=n)for(;j;j/=10)d+=j%10;i=r;}

Try it online!

To shave off another 2 bytes, the truthy value returned is no longer 1, but the number itself.

Answered by gastropner on December 10, 2021

Retina, 55 bytes

.+
*
Lv`_+
_+
$&$.&
^_+
$&¶$&
d
*
Cms`^(_+)b.*¶1b
0

Try it online! Link includes test cases. Explanation:

.+
*

Convert input x to unary.

Lv`_+

Create a range from x down to 1.

_+
$&$.&

Suffix the decimal value of each n to its unary value.

^_+
$&¶$&

Make a copy of x.

d
*

Convert each decimal digit of n to unary, thus adding the digits to the existing copy of n.

Cms`^(_+)b.*¶1b

Check whether x appears in any of the results.

0

Invert the result.

Answered by Neil on December 10, 2021

Octave, 49 47 44 bytes

@(x)arrayfun(@(k)k+sum(num2str(k)-48)-x,1:x)

Try it online!

Explanation:

Trying to do the operation on a range is cumbersome and long, since num2str returns a string with spaces as separators if there are more than input number. Subtracting 48 would therefore give something like: 1 -16 -16 2 -16 -16 3 -16 -16 4 for an input range 1 ... 4. Getting rid of all the -16 takes a lot of bytes.

Therefore, we'll do this with a loop using arrayfun. For each of the numbers k = 1 .. x, where x is the input, we add k and its digit sum, and subtract x. This will return an array of with the result of that operation for each of the numbers in k. If any of the numbers in the array is a zero, the number is not a self number.

For inputs 20 and 21, the outputs are:

20:  -18, -16, -14, -12, -10, -8, -6, -4, -2, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 2
21:  -19, -17, -15, -13, -11, -9, -7, -5, -3, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 1, 3

There are only non-zero elements for input 20, and at least one non-zero element for input 21. That means that 20 is a self number, and 21 is not.

Octave treats an array with at least one zero as false, as can be seen in the TIO-link.

Answered by Stewie Griffin on December 10, 2021

05AB1E, 8 bytes

LD€SO+ÊW

Try it online! or as a Test suite

Explanation

L          # push range [1 ... input]
 D         # duplicate
  €S       # split each number into a list of digits
    O      # sum digit lists
     +     # add (n + digitSum(n))
      Ê    # check for inequality with input
       W   # min

Answered by Emigna on December 10, 2021

Perl 6, 39 33 bytes

{!grep $_,map {$_+[+] .comb},^$_}

Try it out!

A bare block with implicit single parameter, called thus:

say {!grep $_,map {$_+[+] .comb},^$_}(500);
> False
say {!grep $_,map {$_+[+] .comb},^$_}(525);
> True

Since n + digits(n) >= n, we can just calculate the Colombian number for all the numbers up to our query value and see if any of them match. So this calculates the Colombian number for a given input:

{$_ + [+] .comb}

Which we apply to all the values up to our target:

(^$_).map({$_+[+] .comb})

But we only care whether any of them match, not what those values are, so as pointed out by @nwellenhof, we can grep:

grep $_, map {$_+[+] .comb}, ^$_

The rest is just coercion to bool and wrapping in a block.

39 bytes

{!((^$_).map({$_+[+] .comb}).any==$_)}

TIO test link provided by @Emigna

@nwellenhof pointed out that using grep would save 6 bytes!

Answered by Phil H on December 10, 2021

Pari/GP, 32 bytes

n->!sum(i=1,n,i+sumdigits(i)==n)

Try it online!

Answered by alephalpha on December 10, 2021

JavaScript (ES6), 52 51 bytes

Saved 1 byte thanks to @l4m2

Returns 0 or 1.

n=>(g=k=>k?eval([...k+'k'].join`+`)-n&&g(k-1):1)(n)

Try it online!

Answered by Arnauld on December 10, 2021

Python 3, 60, 56, 55, 54 bytes

lambda x:{x}-{n+sum(map(int,str(n)))for n in range(x)}

Try it online!

-4 using all inverse instead of any
-1 by changing != to ^ by @jonathan-allan
-1 by using sets by @ovs

Answered by Rick Rongen on December 10, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP