返回带平方数和的整数


31

介绍和信誉

我们都知道并喜欢我们很棒的规则,可以测试数字是11还是3的整数倍,这只是数字位数的巧妙总和。现在,通过要求您计算数字的总和,然后检查结果是否为理想的整数平方,这一挑战将其推向了一个新的高度,这两个操作通常都无法在很短的时间内完成。由于在查看数字时也很难看到此属性,因此我们希望对整个数字列表都执行此操作,以节省人工。因此,这就是您的挑战!

这是我大学功能编程课程中的一项作业。这项作业现在已经关闭,并且已经在课堂上进行了讨论,我已经得到了我教授的允许在这里发布(我明确要求)。

规格

输入值

您的输入是采用任何标准I / O格式的非负整数列表。
您可以根据自己的语言选择列表格式

输出量

输出是任何标准I / O格式的整数列表。

该怎么办?

从输入列表中筛选出每个数字的总和不是平方(整数)的整数。
元素的顺序可能不会更改,例如,如果得到[1,5,9],则可能无法返回[9,1]

潜在的极端情况

0 一个非负整数,从而有效的输入和0也是有效的整数根,例如0计数为整数正方形。
空列表也是有效的输入和输出。

谁赢?

这是代码高尔夫球,因此最短的答案以字节为单位!
标准规则当然适用。

测试用例

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

分步示例

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]

11
不错的第一个挑战,欢迎光临本站!
DJMcMayhem

对于未来的挑战,请注意沙箱。在这里,我们可以在将挑战放到主站点上之前先提出挑战,以便可以对其进行审核并查询其内容,以便(希望)在主站点上得到更好的接待。但这并不是一个坏问题(我实际上很喜欢)
Blue Blue

@muddyfish,我已经读过有关此内容,并考虑过在此发布,但决定不这样做,因为我有信心,在这里我不会错过任何事情/做得很糟糕:)当然,如果我什至有疑问的话,可能会有些事情我想我会贴在那里。
SEJPM

12
虽然最好不要使用沙箱,但如果您将其发布在这里,我建议您仅在测试单个整数时就面临挑战。有趣的任务是测试,用过滤器包装该任务并不是特别有趣。似乎要做的就是使不具有数组类型的深奥语言面临的挑战更加困难。这听起来可能有点苛刻,但这仍然是出色的第一篇文章。只是说沙盒在那儿,是因为无论您有多确信,您都不会错过任何东西,而是会错过任何东西。
FryAmTheEggman

1
@FryAmTheEggman我可以为Mathematica说,使此函数可列出的方式使事情变得有些平凡,因此并不是很无聊。
LLlAMnYP'6

Answers:



5

Mathematica,39 36字节

匿名函数:

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

LLlAMnYP保存了一个字节。谢谢!

马丁·安德挽救了三个多替换IntegerQAtomQ。聪明!(的结果将是精确的,因此它将返回一个复合表达式,例如Sqrt[5]其参数不是平方。)


...Digits@#&代替...Digits[#]&
-LLlAMnYP

4

果冻,8 7字节

1个字节,感谢@ Sp3000

DSƲðÐf

测试套件。

说明

DSƲðÐf  Main monadic chain. Argument: z

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

4

Brachylog v2,8个字节

{ẹ+√ℤ&}ˢ

在线尝试!

说明

{ẹ+√ℤ&}ˢ
{     }ˢ  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

&意味着输出的元素与输入列表中的元素相同,但是如果块的输入不是一个平方数,则将输出错误,因此我们得到的输入列表中将丢弃非平方数之和的元素。

请注意,这里乍看起来似乎存在浮点误差问题(由于舍入,一些非常大的非平方整数具有整数平方根)。但是,Brachylog支持bignum算术,并且实际上在执行以下行为时考虑了此行为:一个完美平方的数字将其平方根报告为整数,而一个不是完美平方的数字(但足够接近其平方)平方根是整数)将其平方根报告为带有整数值的浮点数。方便地,仅允许前一种返回值,从而给后者带来断言失败。


3

Pyth,10个字节

fsI@sjT;2Q

测试套件。

说明

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)

3

CJam,14个字节

感谢@FryAmTheEggman节省了一个字节!

{{Ab:+mq_i=},}

在线尝试!

这是一个未命名的块,期望输入列表在堆栈上,并将过滤后的列表保留在堆栈上。

说明

{e#开始一个新块
 Ab e#转换为以10为底的数字->将数字拆分为数字
 :+ e#总和数字
 mq e#获取平方根
 _ e#复制结果
 ie#转换为整数
 = e#检查转换后的平方根与原始平方根是否相等
} e#结束块
,e#过滤输入列表

3

Haskell- 70 60 59字节

f=filter(\x->elem(sum.map(read.pure).show$x)$map(^2)[0..x])

用法:

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

非常简单;计算数字总和并检查floor(sqrt(y))^ 2 == y

编辑:从C. Quilley窃取了检查正方形列表的想法


2
有趣的方法。我不确定f=此答案是否必需。
Michael Klein

3

05AB1E,19 10字节

vySOtDï->—

说明

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

在线尝试

编辑:由于@Adnan,节省了9个字节


要获取每个数字的总和,您可以执行vySO并立即检查它是否为正方形。我得到这个5: tDï->。还有一个特殊的内置函数,y当等于时会打印1,即()。因此,那将是vySOtDï->—
阿德南(Adnan)2013年

@Adnan:我不敢相信我忘了S。我什至没有看过-因为任务说要以列表形式输出,但是我看到其他答案也在做,所以我认为没问题。
Emigna

是的,我认为默认情况下会接受以换行符分隔的项目,除非挑战明确表示不接受。
阿德南(Adnan)2013年

3

R57 55字节

Filter在向量上使用。假设32位整数,所以最多10位。

极端情况:返回NULL空向量和numeric(0)没有有效数字的向量。它们的长度均为零,因此应该可以接受。

-2感谢@Giuseppe

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

在线尝试!


3

PowerShell64 54字节

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

在线尝试!

-10字节归功于mazzy

将输入作为命令行参数(请参见下面的示例),在PowerShell中将其处理到array中$args。我们将其?通过管道传递给别名Where-Object(功能类似于filter),以便选择我们的输出。我们的选择基于.NET调用[math]::Sqrt(),该数字的总和是带有的整数!(...%1)。整数将导致0,当noted变为True而不是非整数根成为时,该值为0 False

如在其他地方提到的,“返回”一个空数组是没有意义的,因为它$null一旦离开范围就被转换为空数组,因此空输入的输出什么也不是。

例子

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

1
$n%1检查是否仅是int$args|?{!([math]::Sqrt(([char[]]"$_"-join'+'|iex))%1)}
mazzy

2

Python 2,76个字节

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

在这里尝试!

有些滥用eval来检查平方数,其余的则很少。
eval语句的计算结果为sum(map(int,n ))**.5==int(sum(map(int,n))**.5)


2

Oracle SQL 11.2,213字节

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

未打高尔夫球

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

2

Brachylog,26个字节

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

例:

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

说明

在这种情况下,有些事情效果太好了…… ~^[X:2]对于正数和负数X,该部分都是正确的,因此为了避免重复,我必须指定它X > 0

;.0部分是由于一个错误引起的(枚举不适用于整数0)。

  • 主谓词

    :1f.                Find all values of Input which satisfy predicate 1
    
  • 谓词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
    )
    

2

Python 2,53个字节

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

Ideone上进行测试


1
对于f([1111111111111111]),它看起来像repr(n)包含'L'int('L')引发ValueError。我觉得你需要str(n)在这里吗?
林恩

2
是的,它不会长期有效。我认为这与固定宽度整数语言的解决方案没有什么不同。
丹尼斯

2

J,33 27字节

感谢@miles 6个字节。

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

在在线口译员中,inv不存储。修改成^:_1代替。

用法

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

>>STDIN和<<STDOUT 在哪里。

略松一口

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)

先前的33字节版本

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

用法

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

>>STDIN和<<STDOUT 在哪里。

略松一口

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

1
您可以使用f&.gapply g,然后是f,然后使用的反数g来缩短*:@<.@%:<.&.%:节省2个字节。您可以重新排列它,并且仅使用floor获取#~[:(=<.)@%:+/"1@(10&#.inv)27个字节,其中invis ^:_1和已经定义。
2016年

2

Javascript 66字节

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

感谢SergioFC保存7个字节


您不能只使用c+d代替c-+-d吗?另外,您可以n%1==0用来测试结果是否为int,因此也许可以节省一些字节以b=>!(Math.sqrt((b+"").split``.reduce((c,d)=>c-+-d))%1)进行过滤
sergioFC16年

@sergioFC我无法改变- + -到+,因为他们琴弦
巴林特

2

Perl 5,42个字节

41,加1 -pe代替-e

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

说明:

  • -p在新行上获取每个输入整数并分配$_给该字符串。
  • my$s将变量初始化为$s空,对每个输入整数重新进行初始化。
  • map$s+=$_,/./g抓取每个数字字符并将其数字地添加到中$s。(换行后的数字变为0。)
  • sqrt$s==~~sqrt$s测试是否$s有一个非整数平方根,和$_ x=品牌$_入本身或根据该测试的空字符串。
  • -p 版画 $_

感谢Brad Gilbert b2gills节省了三个字节。

同样是41加1:

my$s;s/./$s+=$&/ger;$_ x=sqrt$s==~~sqrt$s
  • s/./$s+=$&/ger向其添加每个数字字符$s(如上所述,换行符为0)

2

JavaScript(Node.js),48字节

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

在线尝试!

说明

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

1

MATL,16 14 13字节

"@tV!UsX^1\?x

在线尝试!

说明

        % 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

1

朱莉娅-38个字节

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

很容易看出它的作用。digits将数字转换为数字列表,sum从而计算数字总和,如果数字为平方,则将产生整数,否则将有小数部分。%1将仅返回小数部分,如果其为零(==0),filter则将其保留在列表中,否则将被滤除。

用作 ![22228,4,113125,22345]



1

MATLAB,52 43 42字节

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

创建一个匿名函数ans,该函数可以使用数组作为输入来调用:ans([22228,4,113125,22345])

在线演示。在线演示位于Octave中,不适用于空输入,但MATLAB可以。

说明

我们将输入数组中的每个元素转换为以10为底的数字,这将产生2D字符数组,其中每一行都包含该数组中数字的数字。要将这些字符转换为数字,我们减去48(ASCII为'0')。然后,我们对各行求和,取平方根,然后确定每个值是否为一个理想平方~mod 1。然后,我们使用此布尔值过滤输入数组。


1

Clojure,110字节

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

计算数字位数的总和,然后滤除那些不存在平方等于该数字总和的数字。

您可以在这里查看结果– https://ideone.com/ciKOje


1

Perl 6的 38   35个字节

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

测试:

#! /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] => []

1

C,143141字节

  • 保存2个字节,@ 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]);}

取消高尔夫 在线尝试

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
}

1

视网膜,69

因为测试视网膜中的完美正方形。可以对广义整数平方根计算进行修改

。+
$&a $&
+`\ b \ d
$ * b 


\ bb
$&:
+`(\ bb +):( bb \ 1)
$ 1 $ 2:
G`(:a | 0 $)
。*一种

输入是用换行符分隔的列表。

在线尝试。

  • 第1阶段-重复每一行的数字,并用 a
  • 第2阶段-将s 之前的每个数字转换a为表示为bs的一元,并用空格分隔
  • 阶段3-删除空格-每个一元数现在代表数字总和
  • 第4阶段和第5阶段-使用一个事实,即理想平方可以表示为1 + 3 + 5 + 7 +...。相应地拆分每个一元
  • 第6阶段-grep过滤仅精确分解为上述形式的那些过滤器
  • 第7阶段-丢弃除原始号码以外的所有号码

我对如何改进它有一些想法,但最终重写了大部分。尽管如此,这仍然是您的主意:重复输入,在前半部分扩展数字,以奇数和的形式过滤正方形,丢弃剩余行的前半部分。我打高尔夫球的方式是通过%-configuration \G和正向引用。随时接受:retina.tryitonline.net/… :)
Martin Ender

1

Python,50个字节

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

如果n是数字输入列表


1
您好,欢迎光临本站!因为这是一场代码高尔夫比赛,例如谁可以编写最短的代码,所以我们要求所有提交的内容至少要打高尔夫球。我们在这里列出了python高尔夫技巧。就在我脑海中,您可以做的一个明显改进是删除所有多余的空格,并将变量重命名为每个字母一个。您也可以将输入作为函数参数或STDIN代替命令行参数。
DJMcMayhem

你还应该指定语言和字节数,这可算作,例如,
nicael

1
欢迎来到PPCG!除了其他人所说的以外,请注意,所有解决方案都必须是完整程序或可调用函数。到目前为止,您的所有答案都是摘要,它们假定输入存储在某个变量中,并且仅对结果进行求值,不幸的是使它们无效。有关可接受的I / O方法,请参阅此meta post
Martin Ender


1

K(oK)19 17 13字节

解:

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

在线尝试!

说明:

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

笔记:

  • -2字节,采用更智能的正方形识别方法
  • -4个字节,感谢ngn

1
您知道filter(func#list吗?
ngn

我没有,很好!
streetster

1

MathGolf5 4字节

gÅΣ°

在线尝试!

说明:

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

MathGolf仍在开发中,因此我认为隐式输入即将到来以减少第一个字节。好极了!


恭喜您,第一个MathGolf回答不是我!我已经与Emigna讨论了隐式输入,他给了我一些很棒的主意。即将到来,希望很快。
maxb
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.