伪析因


39

有时在数学问题或谜语中会出现一个相当奇怪的数字。伪因子(N)是数字1到N的最小(即最低)公倍数;换句话说,它是最低的数字,其中包含从1到N的所有数字。

例如pseudofactorial(7)= 3 * 4 * 5 * 7,与7相同!除了2和6已删除,因为它们包含在其他术语中。

编写一个程序来计算pseudofactorial(N),并且一如既往地以最短的代码为准。

这是供您使用的简短列表。可以在OEIS中的A003418下找到更多测试用例。

阶乘:

  1. 1个
  2. 2
  3. 6
  4. 24
  5. 120
  6. 720
  7. 5040

伪因子:

  1. 1个
  2. 2
  3. 6
  4. 12
  5. 60
  6. 60
  7. 420

6
我不确定我是否理解为什么26并从倍数列表中将其删除。能否请您阐明规则?
Maltysen

2
@ Mattysen,psuedofactorial(N)是将数字1到N作为因子的最小数字(这些数字的最小公倍数)。那是技术定义,但是我写的方式有点暗示它类似于阶乘。
托尼·露丝


4
欢迎来到编程难题和代码高尔夫球!这是一个不错的第一个挑战!
Alex A.

1
您的第一个挑战达到了HNQ的最高水平。真好!
Daniel M.

Answers:




8

C(x86),52个字节

d(n,k,b,t){for(b=k=1;b;++k)for(t=n,b=0;t;b+=k%t--);}

从1开始检查数字。对于每个数字,将其除以从n到1的所有数字,然后将余数相加。总和为0时停止。

用法:

main()
{
    printf("%d\n", d(7)); // outputs 420
}

它如何返回值(没有return语句)并不明显。

x86的调用约定表示该函数必须在eax寄存器中返回其值。方便地,除法指令idiv期望在中输入eax,并在eax(商)和edx(余数)中输出结果。最后的迭代分裂k1,所以eax将包含正确的价值函数退出的时候。

这仅适用于的优化(在调试模式下,输出421)。


如果不声明n,k,b和t的类型,该如何摆脱呢?
托尼·露丝

C具有default-int规则-默认情况下,所有省略的类型都是int默认值(包括返回值)。如果函数参数使用所谓的“旧式”语法声明,则适用于该函数参数。具有显式定义类型的声明为int d(n,k,b,t) int n,k,b,t; {...}
anatolyg,2016年

如果您利用调用约定的优势,则应将其真正标记为“ C(cdecl)”而不是仅标记为“ C”
Steve Cox 2016年

@SteveCox两者cdeclstdcall用同样的方法为返回值,所以我想x86就足够了
anatolyg

7

Haskell,20个字节

f x=foldr1 lcm[1..x]

用法示例:map f [1..7]-> [1,2,6,12,60,60,420]

lcmHaskell把戏。


6

Python + SymPy,45个字节

import sympy
lambda n:sympy.lcm(range(1,n+1))

相当不言自明。


Python 2,57 54字节

i=r=input();exec't=r\nwhile r%i:r+=t\ni-=1;'*r;print r

Ideone测试

这个怎么运作

输入存储在变量ir中

exec执行以下代码r次。

t=r
while r%i:r+=t
i-=1

ir变为1时,我们将r的初始值(存储在t中)加到r本身所需的次数上,以创建i的倍数。结果显然是t的倍数。

r的最终值因此是[1,...,n]范围内所有整数的倍数,其中n是输入。


1
在不使用第三方库或exec技巧的情况下,有一个78字节的解决方案:from fractions import*;lambda n:reduce(lambda x,y:x*y/gcd(x,y),range(1,n+1),1) 使用的事实lcm(x,y) = x*y/gcd(x,y)
Bakuriu

6

Python,46个字节

g=lambda n,c=0:n<1or(c%n<1)*c or g(n,c+g(n-1))

寻找多cg(n-1)直接。我之前曾有过这种方法会错误地将0查找为任何东西的倍数,但是由于0为Falsey,因此or短路或(c%n<1)*c也会跳过c==0


50个字节:

g=lambda n,i=1:n<1or(i*n%g(n-1)<1)*i*n or g(n,i+1)

类似于Dennis的解决方案,但作为递归函数。有计算g(n-1),外观为最小倍数i*nn这也是倍数g(n-1)。真的很慢

感谢Dennis通过查看n而不是的倍数获得了4个字节g(n-1)


5

J,9个字节

[:*./1+i.

直截了当的方法。创建数字范围[0, ..., n-1],然后将每个,然后使用LCM对其进行缩减。

用法

   f =: [:*./1+i.
   f 7
420


4

Mathematica,13个字节

LCM@@Range@#&

这不就是只相当于撰写LCMRange@*
Maltysen

1
LCM操作逐元素的列表,这将通过被传递Range,这意味着这将只返回LCM(X为)X从1到Ñ。此外,还有一个缺失&,它将关闭匿名功能。像LCM@@Range@#&13字节的东西会工作。
英里



3

八度,27字节

@(x)lcm(1,num2cell(1:x){:})

创建一个可以作为调用的匿名函数ans(N)

在线演示

说明

该解决方案产生的所有数字之间的列表1x1:x它们),转换成与单元阵列num2cell。然后,{:}索引创建一个逗号分隔列表,该列表lcm作为多个输入参数传递给该列表,以计算最小公倍数。lcm因为lcm始终需要至少两个输入参数,所以始终将1作为第一个参数传递。


1
因此,lcm在Octave中接受2个以上的输入!有趣
Luis Mendo

@LuisMendo Yup 2+
Suever



2

JavaScript(ES6),92 88 80 74 69字节:

谢谢@ConorOBrien和@Neil

y=>(g=(a,b)=>b?g(b,a%b):a,[...Array(y)].map((_,i)=>y=y*++i/g(y,i)),y)

b?g(b,a%b):a保存一个字节。
尼尔

y*++i/g(y,i)保存更多的字节。
尼尔

1

05AB1E,20字节

Lpvyi¹LÒN>¢àN>*ˆ}}¯P

说明

Lpv                    # for each item in isprime(range(1,N)): N=7 -> [0,1,1,0,1,0,1]
   yi                  # if prime
     ¹LÒN>¢            # count occurrences of the prime 
                         in the prime-factorization of range(1,N):
                         p=2 -> [0,1,0,2,0,1,0]
           àN>*ˆ       # add max occurrence of that prime multiplied by the prime 
                         to global array: N=7 -> [4,3,5,7]
                }}     # end if/loop
                  ¯P   # get product of global array

在线尝试


1

Minkolang 0.15,12个字节

我有两个 12字节的解决方案,并且都包括了它们。

1n[i1+4$M]N.

在这里尝试!

说明

1               Push 1
 n              Take number from input
  [             For loop that repeats n times
   i1+          Push loop counter + 1
      4$M       Pop b, a and push lcm(a,b)
         ]      Close for loop
          N.    Output as number and stop.

尽可能简单。


11nLd[4$M]N.

在这里尝试!

说明

11              Push two 1s
  n             Take number from input
   L            Pop b, a and push range from a to b, inclusive
    d           Duplicate top of stack (n)
     [4$M]      Pop b, a and push lcm(a,b), n times
          N.    Output as number and stop.

由此可以得出第三个解决方案:删除a 1d在current之后添加a d。在这两种情况下,都需要额外的数字,因为for循环运行太多次,而使其运行时间减少了两个字节(1-恰好在之前[)。



1

GameMaker语言,60字节

for(b=k=1;b;++k){b=0for(t=argument0;t;b+=k mod t--)}return k

基于anatolyg答案的逻辑。


1

PHP,61 52 48字节

@ user59178节省了9个字节,通过合并循环节省了4个字节。

由于function关键字的存在,PHP中的递归非常繁琐。所以我使用迭代。
并以一些“小”技巧,我现在甚至击败了Arnauld的JS

while(++$k%++$i?$i>$argv[1]?0:$i=1:$k--);echo$k;

从命令行参数获取输入。用运行-r

分解

while(++$k%++$i?    # loop $i up; if it does not divide $k
    $i>$argv[1]?0       # break if $i (smallest non-divisor of $k) is larger than input
    :$i=1               # while not, reset $i and continue loop with incremented $k
    :$k--);         # undo increment while $i divides $k
echo$k;         # print $k

不打高尔夫球

实际上这是两个循环:

while($i<=$argv[1]) # loop while $i (smallest non-divisor of $k) is not larger than input
    for($k++,       # loop $k up from 1
        $i=0;$k%++$i<1;);   # loop $i up from 1 while it divides $k
echo$k;             # print $k

注意:复制自我的答案


1

AWK,42个字节

{for(x=n=1;n<=$1;)if(x%n++){x++;n=1}$0=x}1

命令行用法:

awk '{for(x=n=2;n<=$1;)if(x%n++){x++;n=2}$0=x}1' <<< NUM

我没有看到一个AWK解决方案,并且昨天刚发布了一个重复的问题,所以我认为我应该把它放在一起。19在我的盒子上或更大的盒子上求解起来相当慢,但它可以工作。




0

Hoon,67个字节

|*
*
(roll (gulf 1 +<) |=({a/@ b/_1} (div (mul a b) d:(egcd a b))))

创建列表[1..n],然后用lcm折叠在列表上。不幸的是,Hoon stdlib没有一个我可以使用的预构建版本:/



0

QBIC35 32字节

把我带到这里。

:{p=0[a|~q%b|p=1]]~p=0|_Xq\q=q+1

说明:

:        Get cmd line param as number 'a'
{        Start an infinite DO loop
p=0      Sets a flag that shows if divisions failed
[a|      FOR (b=1; b<=a; b++)
~q%b     IF 'q' (which starts at 1 in QBIC) is not cleanly divisible by 'b'
|p=1     THEN Set the flag
]]   Close the FOR loop and the IF, leave the DO open
~p=0     IF 'q' didn't get flagged
|_Xq     THEN quit, printing 'q'
\q=q+1   ELSE raise 'q', redo
         [DO Loop implicitly closed by QBIC]

这是一个qb没有明确划分时会停止测试的版本。此外,测试顺序b的反对q在假设相反,较高b的将是难以除以(取234例如:如果%2=0%4可能!0,反之没有那么多...)。

:{p=0[a,2,-1|~q%b|p=1┘b=2]]~p=0|_Xq\q=q+1



0

8th,23个字节

1 ' lcm rot 2 swap loop

该代码将结果伪伪数留在TOS上

用法和示例

ok> 7 1 ' lcm rot 2 swap loop .
420

或更清楚

ok> : pseudofact 1 ' n:lcm rot 2 swap loop ;

ok> 7 pseudofact .
420
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.