# Return the integers with square digit-sums

## Introduction and Credit

We all know and love our awesome rules to test whether a number is divisble by 11 or 3, which is just some clever sum over the digits of the number. Now this challenge takes this to a new level, by requiring you to compute the sum of the digits and then checking whether the result is a perfect integer square, neither of which operations usually can be done very short. As this property is also very hard to see when looking at a number, we want this to be done for entire lists of numbers so we can save human work. So this is your challenge now!

This was an assignment at my university functional programming course. This assignment is now closed and has been discussed in class and I have my professor's permission to post it here (I asked explicitely).

## Specification

### Input

Your input is a list of non-negative integers, in any standard I/O format.
You may choose the list format as your language needs it

### Output

The output is a list of integers, in any standard I/O format.

### What to do?

Filter out every integer from the input list for which the sum of the digits is not a a square (of an integer).
The order of the elements may not be changed, e.g. if you get [1,5,9] you may not return [9,1]

### Potential corner cases

0 is a non-negative integer and thus a valid input and 0 is also a valid integer root, e.g. 0 counts as an integer square.
The empty list is a valid input and output as well.

### Who wins?

This is code-golf so the shortest answer in bytes wins!
Standard rules apply of course.

## Test Cases

[1,4,9,16,25,1111] -> [1,4,9,1111]
[1431,2,0,22,999999999] -> [1431,0,22,999999999]
[22228,4,113125,22345] -> [22228,4,22345]
[] -> []
[421337,99,123456789,1133557799] -> []


### Step-by-Step Example

Example input: [1337,4444]
Handling first number:
Sum of the digits of 1337: 1+3+3+7=14
14 is not an integer square, thus will be dropped!
Handling second number:
Sum of the digits of 4444: 4+4+4+4=16
16 is an integer square because 4*4=16, can get into the output list!
Example output: [4444]

• Nice first challenge, and welcome to the site! – DJMcMayhem Jun 10 '16 at 14:14
• For future challenges note the sandbox. It's a place where we put challenges before we put them on the main site so hey can get reviewed and their content queried so they will (hopefully) get better received on main. Not that this is a bad question though (I actually quite like it) – Blue Jun 10 '16 at 14:16
• @muddyfish, I've read about this and considered posting there but decided not to do it, because I was confident, that there's nothing I could miss / do horribly wrong here :) Of course if I have even some doubt there could be something I miss I'll post there. – SEJPM Jun 10 '16 at 14:21
• While it is totally fine to avoid the sandbox, had you posted there I would have suggested that you make the challenge only about testing an individual integer. The interesting task is the test, wrapping that task with a filter isn't particularly interesting. All it seems to do is make the challenge substantially more difficult in esoteric languages that do not have arrays as types. That may sound a bit harsh, but this is still an excellent first post. Just saying that the sandbox is there because no matter how sure you are you didn't miss anything, you missed something. – FryAmTheEggman Jun 10 '16 at 14:29
• @FryAmTheEggman I can say for Mathematica that making this function listable complicates things in a slightly non-trivial way, so it's not exactly boring. – LLlAMnYP Jun 17 '16 at 13:42

## Pyke, 6 bytes

#s,DBq


Try it here!

#      - Filter list on truthiness:
s     -    digital_root(^)
,    -   sqrt(^)
Bq -  int(^) == ^


# Jelly, 8 7 bytes

1 byte thanks to @Sp3000.

DSÆ²ðÐf


Test suite.

### Explanation

DSÆ²ðÐf  Main monadic chain. Argument: z

Ðf  Filter for truthiness:
D            convert to base 10
S           sum
Æ²         is perfect square


# Javascript 66 bytes

a=>a.filter(b=>(e=Math.sqrt((b+"").split.reduce((c,d)=>c-+-d)))==(e|0))


Thanks for SergioFC for saving 7 bytes

• Can't you just use c+d instead of c-+-d? In addition you can use n%1==0 to test if the result is an int, so maybe you can save some bytes using b=>!(Math.sqrt((b+"").split.reduce((c,d)=>c-+-d))%1) to filter – sergioFC Jun 11 '16 at 22:21
• @sergioFC I can't change -+- to +, because they're strings – Bálint Jun 12 '16 at 12:34

# Pyth, 10 bytes

fsI@sjT;2Q


Test suite.

### Explanation

fsI@sjT;2Q

f        Q  Filter for the following in Q(input):
jT;        convert to base 10
s           sum
@    2       square-root
sI             is integer (is invariant under flooring)


# CJam, 14 bytes

Thanks to @FryAmTheEggman for saving one byte!

{{Ab:+mq_i=},}


Try it online!

This is an unnamed block that expects the input list on the stack and leaves the filtered list on it.

## Explanation

{    e# start a new block
Ab  e# convert to base 10 -> split number into digits
:+  e# sum th digits
mq  e# get the square root
_   e# duplicate the result
i   e# convert to integer
=   e# check if the converted square root and the original one are equal
}    e# end block
,    e# filter the input list


# PowerShell, 64 54 bytes

$args|?{!([math]::Sqrt(([char[]]"$_"-join'+'|iex))%1)}


Try it online!

-10 bytes thanks to mazzy

Takes input as command-line arguments (see examples below), which gets processed in PowerShell into the array $args. We pipe that to ? an alias for Where-Object (functions similar to filter) in order to select our output. Our selection is based on the .NET call [math]::Sqrt() of the digit-sum of the number is an integer with !(...%1). Integers will result in 0, which when noted becomes True while non-integer roots become False. As mentioned elsewhere "returning" an empty array is meaningless, as it's converted to $null as soon as it leaves scope, so the output for an empty input is nothing.

### Examples

PS C:\Tools\Scripts\golfing> .\return-integers-with-square-digit-sums.ps1 1 4 9 16 25 1111
1
4
9
1111

PS C:\Tools\Scripts\golfing> .\return-integers-with-square-digit-sums.ps1 1431 2 0 22 999999999
1431
0
22
999999999

PS C:\Tools\Scripts\golfing> .\return-integers-with-square-digit-sums.ps1 22228 4 113125 22345
22228
4
22345

PS C:\Tools\Scripts\golfing> .\return-integers-with-square-digit-sums.ps1

PS C:\Tools\Scripts\golfing> .\return-integers-with-square-digit-sums.ps1 1337 4444
4444


# Mathematica, 39 36 bytes

An anonymous function:

Select[AtomQ@√Tr@IntegerDigits@#&]


LLlAMnYP saved a byte. Thank you!

Martin Ender saved three more by replacing IntegerQ with AtomQ. Clever! (The result of √ will be exact, so it returns a compound expression like Sqrt[5] if its argument isn’t a square.)

• A byte to be saved by ...Digits@#& instead of ...Digits[#]& – LLlAMnYP Jun 17 '16 at 13:43

# Julia - 38 bytes

!X=filter(i->√sum(digits(i))%1==0,X)


It's pretty easy to see what this does. digits converts a number into a list of its digits, sum thus calculates the digit-sum, √ will then produce a whole number if the number is a square, otherwise there will be a fractional part. %1 will return only the fractional part, and if it's zero (==0), filter will keep it on the list, otherwise it gets filtered out.

Used as ![22228,4,113125,22345]

# Python 2, 53 bytes

lambda x:[n for n in x if sum(map(int,n))**.5%1==0]


Test it on Ideone.

• For f([1111111111111111]), it looks like repr(n) contains an 'L' and int('L') throws a ValueError. I feel like you need str(n) here? – Lynn Jun 10 '16 at 19:24
• Right, it won't work for long ints. I don't think that's different from a solution in a language with fixed-width integers though. – Dennis Jun 10 '16 at 19:27

# Jolf, 8 bytes

Try it here!

ψxd!iUuH


## Explanation

ψxd!iUuH
ψxd       filter the input according to the input
uH  digit sum of H (element)
U    sqrt of
!i     is an integer?


# MATLAB, 5243 42 bytes

@(x)x(~mod(sum(dec2base(x,10)'-48).^.5,1))


Creates an anonymous function named ans that can be called with an array as input: ans([22228,4,113125,22345]).

Online Demo. The online demo is in Octave which doesn't work for the empty input, but MATLAB does.

Explanation

We convert each element in the input array to base 10 which will yield a 2D character array where each row contains the digits of a number in the array. To convert these characters to numbers, we subtract 48 (ASCII for '0'). We then sum across the rows, take the square root, and determine whether each value is a perfect square ~mod 1. We then use this boolean to filter the input array.

# Perl 5, 42 bytes

41, plus 1 for -pe instead of -e

my$s;map$s+=$_,/./g;$_ x=sqrt$s==~~sqrt$s


Explanation:

• -p gets each input integer on a new line and assigns $_ to that string. • my$s initializes the variable $s to nothing, anew for each input integer. • map$s+=$_,/./g grabs each numeric character and numerically adds it to $s. (The newline becomes 0 when numified.)
• sqrt$s==~~sqrt$s tests whether $s has a nonintegral square root, and $_ x= makes $_ into itself or the empty string depending on that test. • -p prints $_

Thanks to Brad Gilbert b2gills for saving three bytes.

Also 41 plus 1:

my$s;s/./$s+=$&/ger;$_ x=sqrt$s==~~sqrt$s

• s/./$s+=$&/ger adds each numeric character to $s (and the newline is 0 as above) ## Javascript, 61 65 f= a=>a.filter(x=>(r=Math.sqrt(eval([...${x}].join+)))==~~r)

j=JSON.stringify;
console.log([
[1,4,9,16,25,1111],
[1431,2,0,22,999999999],
[22228,4,113125,22345],
[],
[421337,99,123456789,1133557799]
].map(x=>j(x)+' -> '+j(f(x))).join
)

# C, 143 141 bytes

• saved 2 bytes, @user6188402
i;q(char*n){double m=0;while(*n)m+=*n++-48;m=sqrt(m)-(int)sqrt(m);return !m;}s(n,s)char**n;{i=-1;while(++i<s)if(q(n[i]))printf("%s\n",n[i]);}


Ungolfed try online

int q(char*n)
{
double m=0;

while(*n) // sum digits
m+=*n++-48;

// get the decimal part of its square root
m=sqrt(m)-(int)sqrt(m);

// true if decimal part is zero
return !m;
}

// input is text, can be a file
void s(char**n, int s)
{
int i=-1;

while(++i<s) // for each number in input
if(q(n[i])) // if is square
printf("%s\n",n[i]); // output is terminal
}


# Clojure, 110 bytes

(fn[t](filter(fn[x](let[a(reduce +(*(count(str x))-48)(map int(str x)))](some #(=(* % %)a)(range(inc a)))))t))


Calculates the sum of number digits and then filters out those for which there doesn't exist a number which squared is equal to the sum.

You can see the result here – https://ideone.com/ciKOje

# Perl 6,  38  35 bytes

{.grep: {($/=sqrt [+] .comb)==$/.Int}}
{.grep: {($/=.comb.sum.sqrt)==$/.Int}}
{.grep: {($/=sqrt [+] .comb)==^$/}}
{.grep: {($/=.comb.sum.sqrt)==^$/}}

### Test:

#! /usr/bin/env perl6

use v6.c;
use Test;

my @tests = (
[1,4,9,16,25,1111] => [1,4,9,1111],
[1431,2,0,22,999999999] => [1431,0,22,999999999],
[22228,4,113125,22345] => [22228,4,22345],
[] => [],
[421337,99,123456789,1133557799] => [],
);

plan +@tests;

my &sq-digit-sum = {.grep: {($/=sqrt [+] .comb)==^$/}}

for @tests -> $_ ( :key($input), :value($expected) ) { is sq-digit-sum($input), $expected, .gist }  1..5 ok 1 - [1 4 9 16 25 1111] => [1 4 9 1111] ok 2 - [1431 2 0 22 999999999] => [1431 0 22 999999999] ok 3 - [22228 4 113125 22345] => [22228 4 22345] ok 4 - [] => [] ok 5 - [421337 99 123456789 1133557799] => []  # Haskell - 7060 59 bytes f=filter(\x->elem(sum.map(read.pure).show$x)$map(^2)[0..x])  Usage: > f [0..100] [0,1,4,9,10,13,18,22,27,31,36,40,45,54,63,72,79,81,88,90,97,100]  Quite straightforward; computes the sum of digits and checks if floor(sqrt(y))^2 == y Edit: Stole the idea of checking list of squares from C. Quilley • Interesting approach. I'm not sure the f= is required for this answer. – Michael Klein Jun 11 '16 at 19:24 ## JavaScript (ES7), 56 bytes a=>a.filter(n=>[...''+n].reduce((x,y)=>+x+ +y)**.5%1==0)  # Retina, 69 Because testing for perfect squares in retina. This can be modified for generalised integer square root calculation. .+$&a$& +\b\d$*b

\bb
$&: +(\bb+):(bb\1)$1 $2: G(:a|0$)
.*a



Input is a newline-separated list.

Try it online.

• Stage 1 - repeat the number on each line, and separate with a
• Stage 2 - convert each digit before the a to unary expressed as bs, separated with spaces
• Stage 3 - remove spaces - each unary now represents the digit sum
• Stage 4 and 5 - Use the fact that perfect squares may be expressed 1 + 3 + 5 + 7 + ... . Split each unary up accordingly
• Stage 6 - grep filter just the ones that exactly split into the above form
• Stage 7 - discard all but the original number
• I had a few ideas how to improve this, but ended up rewriting most of it. Nevertheless, this is still exactly your idea: duplicate input, expand digits in first half, filter squares in the form of sums of odd numbers, discard first half of remaining lines. The way I golfed the steps is via %-configuration, \G and forward references. Feel free to take it: retina.tryitonline.net/… :) – Martin Ender Jun 22 '16 at 15:44

## C#, 103 bytes

int[] f(int[] a){return a.Where(n=>Math.Sqrt((n+"").Select(m=>int.Parse(m+"")).Sum())%1==0).ToArray();}


Its really sad i have to turn chars and ints into strings all the time to work on them, i wish there was a better solution than adding an empty literal "" to cast into string.

any help on golfing this down appreciated

## Hoon, 78 bytes

|*
*
%+
skim
+<
|=
@ui
=(0 q:(sqt (roll (scan (slag 2 <+<>) (star dit)) add)))


++skim only keeps the elements of the list that the function returns yes for. We cast all the atoms in the list to @ui in the sample, for the sole reason that Urbit's integers have mandatory group seperators: if you try to cast 1.000 to a string, it will return "1.000" instead of "1000". <@ui1.000>, however, gives "0i1000", so we cast and then cut off the first two letters of the string.

We then parse the string with the parser combinator (star dit), which is like the [0-9]* regex but also converts the character to an atom. We fold over the resulting list with add.

We call sqt on the number. In Hoon, the only data types are atoms or tuples, so it returns two atoms intead of a float: the nearest perfect square root, and the remainder. We can then just test if the remainder is 0.

### TXR Lisp: 85 81 72 byte (op ...) denoting anon. function:

(op keep-if (opip tostring (mapcar chr-digit) (apply +) (= @1 [[dup *] (isqrt @1)])))
(op keep-if (opip @1 (mapcar chr-digit) (apply +) (= @1 [[dup *] (isqrt @1)])))
(op keep-if(opip@1(mapcar chr-digit)(apply +)(=@1[[dup *](isqrt@1)])))

$txr -i 1> (op keep-if(opip@1(mapcar chr-digit)(apply +)(=@1[[dup *](isqrt@1)]))) #<interpreted fun: lambda #:rest-0117> 2> [*1 '(1 4 9 16 25 1111)] (1 4 9 1111) 3> [*1 '(1431 2 0 22 999999999)] (1431 0 22 999999999) 4> [*1 ()] nil 5> [*1 '(22228 4 113125 22345)] (22228 4 22345) 6> [*1 '(421337 99 123456789 1133557799)] nil 7>  isqrt is integer square root. This will handle large integers; no floating-point hacks here. TXR Lisp is fundamentally a Lisp-2 dialect, like ANSI Common Lisp or Emacs Lisp. However, the square brackets [whatever ...] notation is syntactic sugar for the operator (dwim whatever ...) which evaluates using a form of Lisp-1 namespace semantics rather than Lisp-2: functions and variable bindings in one space rather than separate spaces. dwim is "deep"; it's not a macro transforming Lisp-2 to Lisp-2; it has visibility into the lexical environments to deliver the actual Lisp-1-like semantics. In [dup *], the dup combinator takes a binary function (or a function that can be used as binary), and returns a unary function which applies two copies of its argument to that function as two arguments; i.e [dup *] denotes a squaring function. op is a rich partial evaluation macro, and opip combines left-to-right pipeline with op: op pipe. (op mapcar +) curries the mapcar function. In (opip (mapcar +) ...),mapcaris similarly curried (theop is implicit), and part of a pipeline. The TXR Lisp REPL allows numbered references to prior results, modulo 100: *1 is the value produced in the most recent command line numbered 1, or 101, or 201, ... ## C: 113 111 — based on other C answer. This is a complete program with main. The input list is the argument list. Old style C is used, but with the C99 fmod function. q(char*n){double m=0;while(*n)m+=*n++-48;return!fmod(sqrt(m),1);}main(c,v)char**v;{while(*++v)if(q(*v))puts(*v);} q(char*n){double m=0;while(*n)m+=*n++-48;return!fmod(sqrt(m),1);}main(c,v)char**v;{while(*++v)q(*v)&&puts(*v);}  Run: $ gcc golf.c -o golf -lm
golf.c:1:1: warning: data definition has no type or storage class [enabled by default]
golf.c: In function ‘q’:
golf.c:1:52: warning: incompatible implicit declaration of built-in function ‘fmod’ [enabled by default]
golf.c:1:57: warning: incompatible implicit declaration of built-in function ‘sqrt’ [enabled by default]
$./golf 1 4 9 16 25 1111 1 4 9 1111$ ./golf
$./golf 421337 99 123456 1133557799$