Geben Sie die Ganzzahlen mit quadratischen Ziffernsummen zurück

31

Einführung und Kredit

Wir alle kennen und lieben unsere großartigen Regeln, um zu testen, ob eine Zahl durch 11 oder 3 teilbar ist. Dies ist nur eine clevere Summe über den Ziffern der Zahl. Diese Herausforderung bringt dies auf ein neues Niveau, indem Sie die Summe der Ziffern berechnen und dann prüfen müssen, ob das Ergebnis ein perfektes ganzzahliges Quadrat ist, wobei keine der beiden Operationen normalerweise sehr kurz ausgeführt werden kann. Da diese Eigenschaft auch bei der Betrachtung einer Zahl sehr schwer zu erkennen ist, möchten wir, dass dies für ganze Zahlenlisten durchgeführt wird, um menschliche Arbeit zu sparen. Das ist jetzt also Ihre Herausforderung!

Dies war eine Aufgabe in meinem Kurs für funktionale Programmierung an der Universität. Diese Aufgabe ist jetzt abgeschlossen und wurde im Unterricht besprochen. Ich habe die Erlaubnis meines Professors, sie hier zu posten (ich habe ausdrücklich darum gebeten).

Spezifikation

Eingang

Ihre Eingabe ist eine Liste nicht negativer Ganzzahlen in einem beliebigen Standard-E / A-Format.
Sie können das Listenformat so wählen, wie es Ihre Sprache benötigt

Ausgabe

Die Ausgabe ist eine Liste von Ganzzahlen in jedem Standard-E / A-Format.

Was ist zu tun?

Filtern Sie jede Ganzzahl aus der Eingabeliste heraus, für die die Summe der Ziffern kein Quadrat (einer Ganzzahl) ist.
Die Reihenfolge der Elemente darf nicht geändert werden, z. B. wenn Sie erhalten [1,5,9], können Sie nicht zurückkehren[9,1]

Mögliche Eckfälle

0 ist eine nicht negative Ganzzahl und somit eine gültige Eingabe, und 0 ist auch eine gültige Ganzzahlwurzel, z. B. zählt 0 als ganzzahliges Quadrat.
Die leere Liste ist auch eine gültige Eingabe und Ausgabe.

Wer gewinnt?

Das ist Code-Golf, also gewinnt die kürzeste Antwort in Bytes!
Es gelten selbstverständlich Standardregeln.

Testfälle

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

Schritt-für-Schritt-Beispiel

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]
SEJPM
quelle
11
Schöne erste Herausforderung und willkommen auf der Seite!
DJMcMayhem
Beachten Sie für zukünftige Herausforderungen den Sandkasten . Es ist ein Ort, an dem wir Herausforderungen stellen, bevor wir sie auf die Hauptseite stellen, damit sie überprüft und ihre Inhalte abgefragt werden können, damit sie (hoffentlich) besser auf der Hauptseite aufgenommen werden. Nicht, dass dies eine schlechte Frage ist (ich mag es eigentlich ziemlich)
Blue
@muddyfish, ich habe darüber gelesen und darüber nachgedacht, dort etwas zu posten, habe mich aber dagegen entschieden, weil ich überzeugt war, dass ich hier nichts vermissen / fürchterlich falsch machen könnte :) Natürlich, wenn ich auch nur einen Zweifel habe, könnte es etwas geben Ich vermisse, dass ich dort posten werde.
SEJPM
12
Obwohl es völlig in Ordnung ist, den Sandkasten zu meiden, hätte ich vorgeschlagen, dass Sie bei der Herausforderung nur eine einzelne Ganzzahl testen. Die interessante Aufgabe ist der Test. Das Umhüllen dieser Aufgabe mit einem Filter ist nicht besonders interessant. Alles, was es zu tun scheint, ist, die Herausforderung in esoterischen Sprachen, die keine Arrays als Typen haben, wesentlich zu erschweren. Das hört sich vielleicht etwas hart an, ist aber immer noch ein hervorragender erster Beitrag. Ich sage nur, dass der Sandkasten da ist, denn egal wie sicher Sie sind, Sie haben nichts verpasst, Sie haben etwas verpasst.
FryAmTheEggman
1
@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

Antworten:

10

Pyke, 6 bytes

#s,DBq

Try it here!

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

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.)

Lynn
quelle
A byte to be saved by ...Digits@#& instead of ...Digits[#]&
LLlAMnYP
4

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
Leaky Nun
quelle
4

Brachylog v2, 8 bytes

{ẹ+√ℤ&}ˢ

Try it online!

Explanation

{ẹ+√ℤ&}ˢ
{     }ˢ  Map the following operation over {the input}, discarding elements that error:
 ẹ         Split into a list of digits
  +        Sum that list
   √       Take its square root
    ℤ      Assert that the result is an integer
     &     Return to the original value

The & means that the elements output are the same as those in the input list, but the will error out if the block's input isn't a square number, so we get the input list with elements with non-square digit sums discarded.

Note that there might at first seem to be a floating point inaccuracy issue here (some very large non-square integers have integer square roots due to rounding). However, Brachylog supports bignum arithmetic, and actually has this behaviour factored into its implementation of : a number which is a perfect square will have its square root reported as an integer, whereas a number which is not a perfect square (but close enough that its square root is integral) will have its square root reported as a float with an integral value. Conveniently, only permits the former sort of return value, giving an assertion failure for the latter.

ais523
quelle
3

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)
Leaky Nun
quelle
3

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
Denker
quelle
3

Haskell - 70 60 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

Démon
quelle
2
Interesting approach. I'm not sure the f= is required for this answer.
Michael Klein
3

05AB1E, 19 10 bytes

vySOtDï->—

Explanation

vy                     # for each int in list
  SO                   # digit sum
    tDï-               # difference between sqrt() and int(sqrt())
        >              # increase by 1 giving 1 (true) when equal
         —             # print current int in list if truthy

Try it online

Edit: Saved 9 bytes thanks to @Adnan

Emigna
quelle
For getting the sum of digits for each, you can do vySO and check immediately if it's square or not. I got this to 5: tDï->. There also is a special builtin that prints y when equal to 1, which is (). So, that would be vySOtDï->—.
Adnan
@Adnan: I can't believe I forgot about S. I didn't even look at — since the task said to output as a list, but I see other answers are doing the same so I assume it's OK.
Emigna
Yeah, items separated with newlines are accepted by default I think, unless the challenge explicitly said not to.
Adnan
3

R, 57 55 bytes

Use Filter on the vector. Assumes 32 bit integers so 10 digits max.

Corner cases: returns NULL for the empty vector and numeric(0) for a vector with no valid numbers. These both have length zero so should be acceptable.

-2 thanks to @Giuseppe

Filter(function(n)!sum(n%/%10^(0:10)%%10)^.5%%1,scan())

Try it online!

J.Doe
quelle
3

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
AdmBorkBork
quelle
1
$n%1 checks if int only $args|?{!([math]::Sqrt(([char[]]"$_"-join'+'|iex))%1)}
mazzy
2

Python 2, 76 bytes

lambda l:filter(lambda n:eval(("sum(map(int,`n`))**.5==int("*2)[:-6]+")"),l)

Try it here!

Some abuse of eval to check for a square number, rest is pretty unspectacular.
The eval statement evaluates to sum(map(int,n))**.5==int(sum(map(int,n))**.5)

Denker
quelle
2

Oracle SQL 11.2, 213 bytes

WITH v AS(SELECT a,SQRT(XMLQUERY(REGEXP_REPLACE(a,'(\d)','+\1')RETURNING CONTENT).GETNUMBERVAL())s FROM(SELECT TRIM(COLUMN_VALUE)a FROM XMLTABLE(('"'||REPLACE(:1,',','","')||'"'))))SELECT a FROM v WHERE s=CEIL(s);

Un-golfed

WITH v AS
(  
  SELECT a,SQRT(XMLQUERY( 
                   REGEXP_REPLACE(a,'(\d)','+\1')  -- Add a + in front of each digit 
                   RETURNING CONTENT
               ).GETNUMBERVAL())s                  -- Evaluate the expression generated by the added +
  FROM 
  (SELECT TRIM(COLUMN_VALUE)a FROM XMLTABLE(('"'||REPLACE(:1,',','","')||'"'))) -- Split string on ','
)
SELECT a FROM v WHERE s=CEIL(s) -- Is a square if square has no decimal part
Jeto
quelle
2

Brachylog, 26 bytes

:1f.
e.(:ef+~^[X:2]h>0;.0)

Example:

?- run_from_file('code.brachylog',[1431:2:0:22:999999999],Z).
Z = [1431, 0, 22, 999999999]

Explanation

This is a situation where something works a bit too well... the ~^[X:2] part is true for both positive and negative X, so to avoid duplicates I have to specify that X > 0.

The ;.0 part is here due to a bug (enumerate doesn't work on the integer 0).

  • Main predicate

    :1f.                Find all values of Input which satisfy predicate 1
    
  • Predicate 1

    e.                  Unify output with an element of the input
    (
      :ef               Find all elements of Output (i.e. all digits)
         +              Sum the digits
          ~^[X:2]       True if that sum is the result of X², whatever X is
                 h>0    Impose that X > 0
    ;                   OR
      .0                True if Output is 0
    )
    
Fatalize
quelle
2

Python 2, 53 bytes

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

Test it on Ideone.

Dennis
quelle
1
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
2
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
2

J, 33 27 bytes

6 bytes thanks to @miles.

#~[:(=<.)@%:+/"1@(10&#.inv)

In online interpreters, inv is not instored. Change that to ^:_1 instead.

Usage

>> f =: #~[:(=<.)@%:+/"1@(10&#.inv)
>> f 1 4 9 16 25 1111 0
<< 1 4 9 1111 0

Where >> is STDIN and << is STDOUT.

Slightly ungolfed

to_base_10 =: 10&#.^:_1
sum        =: +/"1
sqrt       =: %:
floor      =: <.
itself     =: ]
equals     =: =
of         =: @
is_integer =: equals floor
test       =: is_integer of sqrt
copies_of  =: #
f =: copies_of~ [: test (sum of to_base_10)

Previous 33-byte version

(]=*:@<.@%:)@(+/"1@(10#.^:_1]))#]

Usage

>> f =: (]=*:@<.@%:)@(+/"1@(10#.^:_1]))#]
>> f 1 4 9 16 25 1111 0
<< 1 4 9 1111 0

Where >> is STDIN and << is STDOUT.

Slightly ungolfed

to_base_10 =: 10#.^:_1]
sum        =: +/"1
sqrt       =: %:
floor      =: <.
square     =: *:
itself     =: ]
equals     =: =
of         =: @
test       =: itself equals square of floor of sqrt
copies_of  =: #
f =: (test of (sum of to_base_10)) copies_of itself
Leaky Nun
quelle
1
You can use f&.g to apply g, then f, and then the inverse of g to shorten *:@<.@%: to <.&.%: saving 2 bytes. You can rearrange it and use only floor to get #~[:(=<.)@%:+/"1@(10&#.inv) for 27 bytes where inv is ^:_1, and is already defined.
miles
2

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

Bálint
quelle
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
@sergioFC I can't change -+- to +, because they're strings
Bálint
2

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)
msh210
quelle
2

JavaScript (Node.js), 48 bytes

a=>a.filter(b=>eval([...b+""].join`+`)**.5%1==0)

Try it online!

Explanation

a =>                                  // lambda function taking one argument
    a.filter(                         // filter the list
        eval(                         // begin eval
            [...b+""]                 // convert number to array of digits 
                .join`+`              // join them with + sign
            )                         // close eval. we achieved sum of all digits of number
        **.5                          // square root of number
        %1==0                         // check for perfect square
    )                                 // end filter and return value
Any3nymous user
quelle
1

MATL, 16 14 13 bytes

"@tV!UsX^1\?x

Try it Online!

Explanation

        % Implicitly grab input
"       % For each number in the input
  @t    % Get this element and duplicate
  V     % Convert to it's string representation
  !     % Transpose the string so each digit is on it's own row
  U     % Convert each row to a number (separates the digits)
  s     % Compute the sum of the digits
  X^    % Compute the square root
  1\    % mod with 1 to determine if the square root is an integer
  ?x    % If there is a remainder, then remove this element from the stack
        % Implicitly display the stack contents
Suever
quelle
1

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]

Glen O
quelle
1

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?
Conor O'Brien
quelle
1

MATLAB, 52 43 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.

Suever
quelle
1

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

cliffroot
quelle
1

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] => []
Brad Gilbert b2gills
quelle
1

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
}
Khaled.K
quelle
1

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
Digital Trauma
quelle
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
1

Python, 50 bytes

filter(lambda x:sum(map(int,str(x)))**0.5%1==0,in)

If n is input list of numbers

Swadhikar C
quelle
1
Hello, and welcome to the site! Since this is a code-golf competition, e.g. who can write the shortest code, we require all submissions to be at at least somewhat golfed. We have a list of python golfing tips here. Just off the top of my head, one obvious improvement you could do is to remove all the extra whitespace, and rename your variables to one letter each. You could also take input as function arguments or STDIN instead of command line arguments.
DJMcMayhem
You should also specify the language and the byte count, which could be counted, for example, there.
nicael
1
Welcome to PPCG! In addition to what the others said, please note that all solutions must be either full programs or callable functions. So far, all of your answers have been snippets which assume that the input is stored in some variable and just evaluate to the result, which unfortunately makes them invalid. For acceptable I/O methods, see this meta post.
Martin Ender
1

K (oK), 19 17 13 bytes

Solution:

(~1!%+/.:'$)#

Try it online!

Explanation:

(~1!%+/.:'$)# / the solution
(          )# / apply function to list
          $   / convert to string
       .:'    / value (.:) each (')
     +/       / sum
    %         / square-root
  1!          / modulo 1
 ~            / not

Notes:

  • -2 bytes with smarter way of identifying squares
  • -4 bytes thanks to ngn
streetster
quelle
1
you know about filter (func#list)?
ngn
I did not, very nice!
streetster
1

MathGolf, 5 4 bytes

gÅΣ°

Try it online!

Explanation:

gÅ    Filter by the next two instructions
  Σ   The digit sum
   °  Is a perfect square?

MathGolf is still in development, so I assume implicit input is coming soon to shave off that first byte. Yay!

Jo King
quelle
Congratulations on the first MathGolf answer not by me! I've discussed implicit input with Emigna, and he gave me some great ideas. It's coming, hopefully soon.
maxb