写有理数作为质数的因数比


19

注意:此挑战已发布在沙盒上

介绍

这项挑战的灵感来自2009年Putnam B1,这是本科数学竞赛中的一个问题。问题如下:

证明每个正有理数都可以写成素数(不一定是素数)的阶乘乘积的商。例如,

$ \ frac {10} 9 = \ frac {2!\ cdot 5!} {3!\ cdot 3!\ cdot 3!}。$

挑战

您的挑战是采用一对相对质数为正的整数,它们代表正有理数(或仅是有理数本身)的分子和分母作为输入,并输出两个质数的列表(或数组等),以便输入的有理数等于第一个列表中素数阶乘的乘积与第二个列表中素数阶乘的乘积之比。

笔记

  • 第一个列表和第二个列表中可能没有任何素数;但是,素数在任意一个列表中可能会出现多次。
  • 可以假定每个输入(非严格地)在1到65535之间。但是,不能假设您需要输出的数字的阶乘将在此范围内。

输入和输出示例

以下是合法输入和输出的示例。

input=>output
10,9 => [2,5],[3,3,3]
2,1 => [2],[]
3,1 => [3],[2]
1,5 => [2,3,2],[5]     (elements of a list may be in any order)
3,2 => [3],[2,2]
6,1 => [3],[]

输入(2,2),(0,3),(3,0),(3,6)和(1,65536)是非法输入(即,您的程序不需要对它们进行任何特定操作)。以下是一些非法输出的示例:

1,2 => [2],[2,2] (2 is in both returned lists)
5,2 => [5],[2,4] (4 is not prime)
2,1 => [2],[1] (1 is not prime either)
3,2 => [3],[2] (3!/2! = 3, not 3/2)

计分

这是,因此以字节为单位的最低分数获胜!


如果存在多种表达答案的方式,是否需要给出某种程度的最小化有理数?例如10/9= [2*5]/[3*3]= [(2!/1!) * (5!/4!)] / [(3!/2!) * (3!/2!)]= [2! * 5! * 2! * 2!] / [3! * 3! * 1! * 4!]= (2! * 2! * 2! *5!) / (3! * 3! * 4!)
Digital Trauma

@DigitalTrauma否;但是,4不是质数,因此第二个无效。我相信(如果愿意,可以写一个证明)任何表示都是唯一的。
卡尔·希尔德克劳特

它是好拿输入的分数10/9,而不是对数字的109
Misha Lavrov

@MishaLavrov当然。我将编辑问题以反映这一点。
卡尔·希尔德克劳特

@CarlSchildkraut谢谢-是的,这有帮助-我以为我错过了一些东西
Digital Trauma

Answers:


5

05AB1E54 53 48 46 40 35 33 32 28字节

[D¿÷Z#DÓ€gZD<ØŠQ*DˆR!*]¯øεʒĀ

在线尝试!编辑:由于仅@ASCII,节省了2个字节。感谢@Emigna,节省了1 2 3 4字节。(我只需要再保存一个,就可以节省一半的原始字节数!)说明:

[       Begin an infinite loop
D¿÷     Reduce to lowest terms
Z#      Exit the loop if the (largest) value is 1
DÓ€g    Find the index of the largest prime factor of each value
Z       Take the maximum
D<ØŠ    Convert index back to prime and save for later
Q       Convert to an pair of which value had the largest prime factor
*       Convert to an pair with that prime factor and zero
Dˆ      Save the pair in the global array for later
R!*     Multiply the other input value by the factorial of the prime
]       End of infinite loop
¯ø      Collect all the saved primes
εʒĀ     Forget all the saved 0s

我喜欢“情感”脚本¦D
RedClover



5

数学,175 177 169 154 108个字节

Join@@@Table[x[[1]],{s,{1,-1}},{x,r@#},x[[2]]s]&@*(If[#==1,1,{p,e}=Last@(r=FactorInteger)@#;p^e#0[p!^-e#]]&)

在线尝试!

怎么运行的

这是两个功能的组合。第一个,不符合

If[# == 1,
  1,
  {p,e} = Last[FactorInteger[#]];
  p^e * #0[p!^-e * #]
]&

是一个递归函数,用于实际计算所需的因式分解。具体来说,给出合理的输入x,我们计算其阶乘应在分子和分母中的素数,并返回所有这些素数相乘在一起的分数。(例如,在输入时10/9 = 2!*5!/(3!*3!*3!),我们返回10/27 = 2*5/(3*3*3)。)

为此,我们在每一步都要处理最大的质因数:如果在x的因式分解中出现p e,请确保p!e发生在阶乘分解中,递归于x除以p!e

(以前,我有一个更聪明的策略,可以通过查看p之前的质数来避免大数,但是Mathematica可以轻松处理多达65521的数!所以没有意义。历史上可以找到的旧版本是更快:在我的计算机上,此版本在1.6秒内处理输入的时间为0.05秒。)

第二个函数将第一个函数的输出转换为素数列表。

Join @@@ 
  Table[x[[1]],
    {s,{1,-1}},
    {x,FactorInteger[#]},
    x[[2]]*s
  ]&

对于s=1(正幂)和s=-1(负幂),以及{prime,exponent}因式分解中的每个项r@#,我们重复素数prime exponent*s多次。

109 62字节的非竞争版本

If[#==1,∇1=1,{p,e}=Last@FactorInteger@#;(∇p)^e#0[p!^-e#]]&

与上述相同,但不是将输出作为列表提供,而是将输出作为表达式使用∇运算符(因为它没有内置含义)作为阶乘的代名词。因此,的输入10/9给出的输出(∇2*∇5)/(∇3)^3以表示(2!*5!)/(3!)^3

这很短,因为我们跳过了函数的第二部分。


+2字节:分配 f=First必须在正确的位置进行,以防止Mathematica烦恼。

-8个字节:修复了整数输出的错误,该错误实际上使代码更短。

-15个字节: FactorInteger返回排序后的输出,我们可以利用它。

-46字节:我们实际上并不需要聪明。


2

Python 2,220 202 195 183字节

g=lambda a,b:a and g(b%a,a)or b;n,d=input();m=c=()
while n+d>2:
 t=n*d;f=p=2
 while t>p:
	if t%p:p+=1;f*=p
	else:t/=p
 if n%p:c+=p,;n*=f
 else:m+=p,;d*=f
 t=g(n,d);n/=t;d/=t
print m,c

在线尝试!编辑:由于@ Mr.Xcoder,节省了18 25字节。@JonathanFrech节省了12个字节。



您可以在Python 2中进一步缩短它,因为您可以用缩进中的制表符替换多个空格
Xcoder先生,2017年


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.