我是不是对你没够好?


29

背景:

当前的“ 完美数字”挑战相当有缺陷和复杂,因为它要求您以涉及数字因子的复杂格式输出。这只是挑战的转贴。

挑战

通过任何标准输入格式给定正整数,请区分是否为完美整数。

理想数是一个等于其所有适当除数之和的数字(其正除数小于其自身)。例如,是一个正数,因为它的除数是,总和为,而不是一个正数,因为它的除数(1,2,3,4,6)总和为16,不是1261,2,36121,2,3,4,61612

测试用例:

Imperfect:
1,12,13,18,20,1000,33550335

Perfect:
6,28,496,8128,33550336,8589869056

规则

  • 如果存在内存或时间限制,您的程序不必完成较大的测试用例,但从理论上讲,如果有更多的内存/时间,它应该可以。
  • 通过任何允许的输出格式,输出可以是两个不同且一致的值。如果尚不清楚什么代表完美/不完美,请确保在您的答案中指定。

等等,真值是针对不完美的值,假值是针对不正确的值?
硕果累累

2
@ Tvde1适当的除数必须小于数字,否则除1完美数字外没有其他数字,因为每个数字都可以被1自身整除。的适当除数的总和10
Jo King

3
@Grimy只有您能证明这一点。祝好运!(尽管我想知道如何保存字节)
Jo King

1
所以不,太糟糕了。它将以约3倍的削减正则表达式ECMA答案的大小
Grimmy

3
“输出可以是两个不同且一致的值”-我们在这里可以不使用“真实vs虚假”(例如,对于使用零与非零的Python;包含内容的列表与空列表;及其组合)吗?
乔纳森·艾伦

Answers:



9

Neim,3个字节

𝐕𝐬𝔼

在线尝试!

(自从大约十五分钟前开始学习Neim以来,我实际上不知道如何一次运行所有测试用例,但是我确实进行了单独检查。)

打印0表示不完美,打印1表示完美。

𝐕      Pop an int from the stack and push its proper divisors,
       implicitly reading the int from a line of input as the otherwise absent top of the stack.
 𝐬     Pop a list from the stack and push the sum of the values it contains.
  𝔼    Pop two ints from the stack and push 1 if they are equal, 0 if they are not;
       implicitly reading the same line of input that was already read as the second int, I guess?
       Implicitly print the contents of the stack, or something like that.

2
我猜? ” “ 或类似的东西。 ” 当您甚至不确定自己写的是什么时,哈哈。;)但是,确实如此。我不知道Neim,但是像05AB1E一样,像这样隐式地使用输入并在末尾隐式地输出。
凯文·克鲁伊森

𝔼1个字节如何?Neim是否仅使用128个此类非标准字符?
kajacx

3
@kajacx Neim有其自己的代码页。因此,可以使用1个字节对代码页中存在的256个字符进行编码。
Xcoder先生

8

R33 29字节

!2*(n=scan())-(x=1:n)%*%!n%%x

在线尝试!

返回TRUE完美数字和FALSE不完美数字。


连续的2!s带给您什么?
CT大厅

@CTHall我看错了规格;它们最初映射到0(完美)到FALSE,非零映射到,TRUE但是我删除了其中一个以反转映射。这是一个非常有用的高尔夫技巧,从铸造numericlogical,往往会同which[
朱塞佩



6

Python 3,46个字节

lambda x:sum(i for i in range(1,x)if x%i<1)==x

在线尝试!

蛮力,将因素加总并检查是否相等。


2
将理解条件用作迭代变量的掩码将节省一个字节。
Jonathan Frech

由于您可以将不完整的数字返回真值,因此也lambda x:sum(i for i in range(1,x)if x%i<1)^x应该工作。
nedla2004

5

Python,45个字节

lambda n:sum(d*(n%d<1)for d in range(1,n))==n

True为了完美 False对于其他人(使用==-> 切换此选项!=

在线尝试!

如果我们可以使用“ truthy vs falsey”输出  44 42  41个字节(感谢ovs,则为-2):

f=lambda n,i=1:i/n or-~f(n,i+1)-(n%i<1)*i

(falsey(0))为完美;真(非零整数),否则


如果第二种输出格式有效,则可以42字节完成。
ovs

@ovs啊,做得很好。
乔纳森·艾伦

@ovs ..和另一个保存的-谢谢!
乔纳森·艾伦

5

八度,25字节

@(n)~mod(n,t=1:n)*t'==2*n

在线尝试!

说明

@(n)~mod(n,t=1:n)*t'==2*n

@(n)                        % Define anonymous function with input n
             1:n            % Row vector [1,2,...,n]
           t=               % Store in variable t
     mod(n,     )           % n modulo [1,2,...,n], element-wise. Gives 0 for divisors
    ~                       % Logical negate. Gives 1 for divisors
                  t'        % t transposed. Gives column vector [1;2;...;n]
                 *          % Matrix multiply
                      2*n   % Input times 2
                    ==      % Equal? This is the output value

4

JavaScript,38个字节

n=>eval("for(i=s=n;i--;)n%i||!(s-=i)")

在线尝试!

(TIO上的最后一个测试用例超时。)


@Arnauld只是忘记了f=从递归函数转换后删除。
tsh

出于好奇,为什么不使用递归版本?(这将是34个字节。)
Arnauld

@Arnauld,因为由于堆栈溢出,对于较大的测试用例,递归版本将完全失败。也许我需要一些默认为严格模​​式的环境才能使其正常工作。
tsh

2
足够公平,但是您的程序不必完成较大的测试用例(无论如何,我认为这是默认规则)。
Arnauld



3

TI-BASIC(TI-84),30 23字节

:2Ans=sum(seq(Ans/Xnot(remainder(Ans,X)),X,1,Ans,1

效率极低,但是可以。
减少字节数可以大大加快程序运行速度。
输入为Ans。程序完成后,
输出已进入Ans并自动打印输出。

说明:
(TI-BASIC没有评论,因此仅假设;发表评论)

:2Ans=sum(seq(Ans/Xnot(remainder(Ans,X)),X,1,Ans    ;Full program

 2Ans                                               ;double the input
          seq(                                      ;generate a list
                                         X,          ;using the variable X,
                                           1,        ;starting at 1,
                                             Ans     ;and ending at the input
                                                     ;with an implied increment of 1
              Ans/X                                 ;from the input divided by X
                   not(                ),           ;multiplied by the negated result of
                       remainder(Ans,X)              ;the input modulo X
                                                     ;(result: 0 or 1)
      sum(                                          ;sum up the elements in the list
     =                                              ;equal?

例:

6
            6
prgmCDGF2
            1
7
            7
prgmCDGF2
            0

注意: 使用[MEM] > [2] > [7](36个字节)中的值来评估程序的字节数,然后减去程序名称的长度CDGF2,(5个字节)和用于该程序的额外8个字节存储程序:

36-5-8 = 23个字节


3

Java(JDK),54个字节

n->{int s=0,d=0;for(;++d<n;)s+=n%d<1?d:0;return s==n;}

在线尝试!

尽管对于严格的数字匹配,以下内容将返回相同的值,但仅为40个字节。

n->n==6|n==28|n==496|n==8128|n==33550336

在线尝试!


规则说Your program doesn't have to complete the larger test cases, if there's memory or time constraints, but it should be theoretically able to if it were given more memory/time.
Jo King

@JoKing这是否意味着我根本不能使用Java int,而是可以使用Java BigInteger?因为Java具有BigIntegers,但是它永远不会有int超过31位的已签名,除了此处所表示的值外,它不能容纳任何其他值...
OlivierGrégoire

否,但是如果int类型不受限制,如果程序仍然可以工作
Jo King

1
@JoKing好的,我再次切换了两个解决方案以首先进行计算。
OlivierGrégoire

3

x86汇编,45 43字节。

6A 00 31 C9 31 D2 41 39  C1 7D 0B 50 F7 F9 58 85
D2 75 F1 51 EB EE 31 D2  59 01 CA 85 C9 75 F9 39
D0 75 05 31 C0 40 EB 02  31 C0 C3

说明(英特尔语法):

PUSH $0          ; Terminator for later
XOR ECX, ECX        ; Clear ECX
.factor:
    XOR EDX, EDX    ; Clear EDX
    INC ECX
    CMP ECX, EAX    ; divisor >= input number?
    JGE .factordone ; if so, exit loop.
    PUSH EAX        ; backup EAX
    IDIV ECX        ; divide EDX:EAX by ECX, store result in EAX and remainder in EDX
    POP EAX         ; restore EAX
    TEST EDX, EDX   ; remainder == 0?
    JNZ .factor     ; if not, jump back to loop start
    PUSH ECX        ; push factor
    JMP .factor     ; jump back to loop start
.factordone:
XOR EDX, EDX        ; clear EDX
.sum:
    POP ECX         ; pop divisor
    ADD EDX, ECX    ; sum into EDX
    TEST ECX, ECX   ; divisor == 0?
    JNZ .sum        ; if not, loop.
CMP EAX, EDX        ; input number == sum?
JNE .noteq          ; if not, skip to .noteq
    XOR EAX, EAX    ; clear EAX
    INC EAX         ; increment EAX (sets to 1)
JMP .return         ; skip to .return
.noteq:
    XOR EAX, EAX    ; clear EAX
.return:
RETN

输入应在中提供EAX
函数集EAX,以1完美和0不完善。

编辑:通过替换MOV EAX, $1XOR EAX, EAX和减少字节数INC EAX


1
我使用宏程序集,所以我不确定,但是注释“;除数>输入数字”对我来说是“;除数> =输入数字”
RosLuP

大会易于操作的一个可以减少指令长度将所有在一条线上,使用缩进和评论每10个20汇编指令....
RosLuP

@RosLuP我已修复代码中的注释(谢谢),但是我不知道您对第二个注释的含义。
Fayti1703

3

迷宫,80字节

?::`}:("(!@
perfect:
{:{:;%"}
+puts; "
}zero: "
}else{(:
"negI"  _~
""""""{{{"!@

拉丁字符perfect puts zero else neg I实际上只是注释*。
即,如果输入是完美的,0则打印a,否则打印-1

在线尝试!


*所以这个这个工作也...

?::`}:("(!@               ?::`}:("(!@
       :                  BEWARE :
{:{:;%"}                  {:{:;%"}
+    ; "                  +LAIR; "
}    : "                  } OF : "
}    {(:                  }MINO{(:
"    "  _~                "TAUR"  _~
""""""{{{"!@              """"""{{{"!@

怎么样?

将一个正整数作为输入n并将一个累加器变量-n放在辅助堆栈上,然后对每个整数执行从除n-1到(包括)与1除法运算的整数的除法测试n。如果累加器变量非零-1,则一旦完成,将输出a,否则输出a 0

?::`}:(执行开始时,仅执行一次:

?::`}:(                                                      Main,Aux
?       - take an integer from STDIN and place it onto Main  [[n],[]]
 :      - duplicate top of Main                            [[n,n],[]]
  :     - duplicate top of Main                          [[n,n,n],[]]
   `    - negate top of Main                            [[n,n,-n],[]]
    }   - place top of Main onto Aux                       [[n,n],[-n]]
     :  - duplicate top of Main                          [[n,n,n],[-n]]
      ( - decrement top of Main                        [[n,n,n-1],[-n]]

下一条指令"No是空操作,但我们有3条相邻指令,因此我们根据Main顶部的值进行分支,零将我们向前,而非零将我们向右。

如果输入是1我们,则前进,因为Main的顶部为零:

(!@                                                          Main,Aux
(   - decrement top of Main                             [[1,1,-1],[-1]]
 !  - print top of Main, a -1
  @ - exit the labyrinth

但是,如果输入大于1我们右转,因为Main的顶部非零:

:}                                                           Main,Aux
:  - duplicate top of Main                         [[n,n,n-1,n-1],[-n]]
 } - place top of Main onto Aux                        [[n,n,n-1],[-n,n-1]]

此时,我们有一个三邻分支,但我们知道n-1它不是零,所以我们右转...

"%                                                           Main,Aux
"  - no-op                                             [[n,n,n-1],[-n,n-1]]
 % - place modulo result onto Main                   [[n,n%(n-1)],[-n,n-1]]
   - ...i.e we've got our first divisibility indicator n%(n-1), an
   -    accumulator, a=-n, and our potential divisor p=n-1:
   -                                                 [[n,n%(n-1)],[a,p]]

我们现在在的另一个三邻分支机构%

如果的结果为%非零,我们将减除我们的潜在除数p=p-1,然后将累加器保留a为:

;:{(:""}"                                                    Main,Aux
;          - drop top of Main                                [[n],[a,p]]
 :         - duplicate top of Main                         [[n,n],[a,p]]
  {        - place top of Aux onto Main                  [[n,n,p],[a]]
           - three-neighbour branch but n-1 is non-zero so we turn left
   (       - decrement top of Main                     [[n,n,p-1],[a]]
    :      - duplicate top of Main                 [[n,n,p-1,p-1],[a]]
     ""    - no-ops                                [[n,n,p-1,p-1],[a]]
       }   - place top of Main onto Aux                [[n,n,p-1],[a,p-1]]
        "  - no-op                                     [[n,n,p-1],[a,p-1]]
         % - place modulo result onto Main           [[n,n%(p-1)],[a,p-1]]
           - ...and we branch again according to the divisibility
           -    of n by our new potential divisor, p-1

...但是,如果的结果%为零(仅当时为第一次通过n=2),我们直接继续将除数添加到累加器中,然后a=a+p递减潜在的除数p=p-1

;:{:{+}}""""""""{(:""}                                       Main,Aux
;                      - drop top of Main                    [[n],[a,p]]
 :                     - duplicate top of Main             [[n,n],[a,p]]
  {                    - place top of Aux onto Main      [[n,n,p],[a]]
   :                   - duplicate top of Main         [[n,n,p,p],[a]]
    {                  - place top of Aux onto Main  [[n,n,p,p,a],[]]
     +                 - perform addition            [[n,n,p,a+p],[]]
      }                - place top of Main onto Aux      [[n,n,p],[a+p]]
       }               - place top of Main onto Aux        [[n,n],[a+p,p]]
        """""""        - no-ops                            [[n,n],[a+p,p]]
                       - a branch, but n is non-zero so we turn left
               "       - no-op                             [[n,n],[a+p,p]]
                {      - place top of Aux onto Main      [[n,n,p],[a+p]]
                       - we branch, but p is non-zero so we turn right
                 (     - decrement top of Main         [[n,n,p-1],[a+p]]
                  :    - duplicate top of Main     [[n,n,p-1,p-1],[a+p]]
                   ""  - no-ops                    [[n,n,p-1,p-1],[a+p]]
                     } - place top of Main onto Aux    [[n,n,p-1],[a+p,p-1]]

在这一点上,如果p-1仍然非零,我们向左转:

"%                                                           Main,Aux
"  - no-op                                             [[n,n,p-1],[a+p,p-1]]
 % - modulo                                          [[n,n%(p-1)],[a+p,p-1]]
   - ...and we branch again according to the divisibility
   -    of n by our new potential divisor, p-1

...但是如果p-1为零,我们会直接:进入迷宫的第二行(您之前已经看过所有说明,所以我不再赘述它们,只是给出效果):

:":}"":({):""}"%;:{:{+}}"""""""{{{                           Main,Aux
:                                  -                   [[n,n,0,0],[a,0]]
 "                                 -                   [[n,n,0,0],[a,0]]
                                   - top of Main is zero so we go straight
                                   -  ...but we hit the wall and so turn around
  :                                -                 [[n,n,0,0,0],[a,0]]
   }                               -                   [[n,n,0,0],[a,0,0]]
                                   - top of Main is zero so we go straight
    ""                             -                   [[n,n,0,0],[a,0,0]]
      :                            -                 [[n,n,0,0,0],[a,0,0]]
       (                           -                [[n,n,0,0,-1],[a,0,0]]
        {                          -              [[n,n,0,0,-1,0],[a,0]]
                                   - top of Main is zero so we go straight
                                   -  ...but we hit the wall and so turn around
         (                         -             [[n,n,0,0,-1,-1],[a,0]]
          :                        -          [[n,n,0,0,-1,-1,-1],[a,0]]
           ""                      -          [[n,n,0,0,-1,-1,-1],[a,0]]
             }                     -             [[n,n,0,0,-1,-1],[a,0,-1]]
                                   - top of Main is non-zero so we turn left
              "                    -             [[n,n,0,0,-1,-1],[a,0,-1]]
               %                   - (-1)%(-1)=0     [[n,n,0,0,0],[a,0,-1]]
                ;                  -                   [[n,n,0,0],[a,0,-1]]
                 :                 -                 [[n,n,0,0,0],[a,0,-1]]
                  {                -              [[n,n,0,0,0,-1],[a,0]]
                   :               -           [[n,n,0,0,0,-1,-1],[a,0]]
                    {              -         [[n,n,0,0,0,-1,-1,0],[a]]
                     +             -           [[n,n,0,0,0,-1,-1],[a]]
                      }            -              [[n,n,0,0,0,-1],[a,-1]]
                       }           -                 [[n,n,0,0,0],[a,-1,-1]]
                        """""""    -                 [[n,n,0,0,0],[a,-1,-1]]
                                   - top of Main is zero so we go straight
                               {   -              [[n,n,0,0,0,-1],[a,-1]]
                                {  -           [[n,n,0,0,0,-1,-1],[a]]
                                 { -         [[n,n,0,0,0,-1,-1,a],[]]

现在,它{具有三个相邻的指令,所以...

...如果a为零,那将是完美的n,那么我们继续:

"!@                                                          Main,Aux
"   -                                        [[n,n,0,0,0,-1,-1,a],[]]
    - top of Main is a, which is zero, so we go straight
 !  - print top of Main, which is a, which is a 0
  @ - exit the labyrinth

...如果a为非零值(对于非完美值)n,那么我们向左转:

_~"!@                                                        Main,Aux
_     - place a zero onto Main             [[n,n,0,0,0,-1,-1,a,0],[]]
 ~    - bitwise NOT top of Main (=-1-x)   [[n,n,0,0,0,-1,-1,a,-1],[]]
  "   -                                   [[n,n,0,0,0,-1,-1,a,-1],[]]
      - top of Main is NEGATIVE so we turn left
   !  - print top of Main, which is -1
    @ - exit the labyrinth


2

Javascript,62

n=>n==[...Array(n).keys()].filter(a=>n%a<1).reduce((a,b)=>a+b)

解释(尽管很简单)

n=> //return function that takes n
  n== //and returns if n is equal to
    [...Array(n).keys()] //an array [0..(n-1)]...
      .filter(a=>n%a<1) //where all of the elements that are not divisors of n are taken out...
      .reduce((a,b)=>a+b) //summed up

感谢Jo King的改进!




2

C(gcc),41个字节

f(n,i,s){for(i=s=n;--i;s-=n%i?0:i);n=!s;}

在线尝试!

1: 0
12: 0
13: 0
18: 0
20: 0
1000: 0
33550335: 0
6: 1
28: 1
496: 1
8128: 1
33550336: 1
-65536: 0 <---- Unable to represent final test case with four bytes, fails

让我知道最后一个案例的失败是否是一个问题。



2
“通过任何允许的输出格式,输出可以是两个不同且一致的值。” 您不会返回任何两个不同的值。
OlivierGrégoire

2
@OlivierGrégoire幸运的是,可以通过用感叹号替换空间来轻松解决问题!
尼尔

1
@Neil更好的是,它可以用固定n=!s;而不是return!s;节省5个字节来固定。

@OlivierGrégoire啊,我忘了这一点。此外,还使用改进的代码更新了。我尝试了类似的方法,但是我做的那个白痴很s=s可能已经对它进行了优化。
马科斯


2

第四(gforth),45字节

: f 0 over 1 ?do over i mod 0= i * - loop = ;

在线尝试!

说明

循环从1到n-1的每个数字,将所有完美地除以n的值相加。如果sum等于n,则返回true

代码说明

: f                \ start word definition
  0 over 1         \ create a value to hold the sum and setup the bounds of the loop
  ?do              \ start a counted loop from 1 to n. (?do skips if start = end)
    over           \ copy n to the top of the stack
    i mod 0=       \ check if i divides n perfectly
    i * -          \ if so, use the fact that -1 = true in forth to add i to the sum
  loop             \ end the counted loop
  =                \ check if the sum and n are equal
;                  \ end the word definition

2

Pyth,9 13字节

qsf!%QTSt

在线尝试!

谢谢评论员对高尔夫的帮助

查找输入的所有因素,对其求和,然后将其与原始输入进行比较。


q0可以用替换一些高尔夫球!,并SQ产生范围[1-Q],因此[1-Q)可以使用生成范围StQ。由于Qs现在位于程序的末尾,因此它们都可以省略。精简版,9字节qsf!%QTSt
Sok

1

批次,81个字节

@set s=-%1
@for /l %%i in (1,1,%1)do @set/as+=%%i*!(%1%%%%i)
@if %s%==%1 echo 1

注意到n作为一个命令行参数并输出1,如果它是一个完美的数目。蛮力法,从总和开始,-n以便它可以将n自己包括在循环中。


1

木炭,13字节

Nθ⁼θΣΦθ∧ι¬﹪θι

在线尝试!链接是详细版本的代码。输出-完美数字。使用蛮力。说明:

Nθ              Numeric input
     Φθ         Filter on implicit range
        ι       Current value (is non-zero)
       ∧        Logical And
           θ    Input value
          ﹪     Modulo
            ι   Current value
         ¬      Is zero
    Σ           Sum of matching values
  ⁼             Equals
   θ            Input value


1

Pyth,8个字节

qs{*MPyP

在这里在线尝试。

qs{*MPyPQQ   Implicit: Q=eval(input())
             Trailing QQ inferred
       PQ    Prime factors of Q
      y      Powerset
     P       Remove last element - this will always be the full prime factorisation
   *M        Take product of each
  {          Deduplicate
 s           Sum
q        Q   Is the above equal to Q? Implicit print

1

视网膜0.8.2,44字节

.+
$*
M!&`(.+)$(?<=^\1+)
+`^1(1*¶+)1
$1
^¶+$

在线尝试!使用蛮力,因此链接仅包括速度更快的测试用例。说明:

.+
$*

转换为一元。

M!&`(.+)$(?<=^\1+)

匹配输入的所有因子。这使用重叠模式,在Retina 0.8.2中,它要求所有匹配项都必须在不同的位置开始,因此,匹配项实际上是从原始输入开始以降序返回的。

+`^1(1*¶+)1
$1

从输入中减去适当的因子。

^¶+$

测试结果是否为零。



1

cQuents,8字节

?#N=U\zN

在线尝试!

说明

?           Mode query: return whether or not input is in sequence
 #          Conditional: iterate N, add N to sequence if condition is true
  N=         Condition: N == 
    U    )                   sum(                  )
     \z )                        proper_divisors( )
       N                                         N
        ))    implicit
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.