使用+和*查找一个数以获得数字


28

介绍

您的目标是找到最少的数量,您需要将该数量相加或相乘才能获得输入值,这是A005245

输入值

一个正整数Ñ

输出量

必须加/乘以得到N的最小数目。

样本输入

7

样本输出

6

说明

1+ 1+ 1)*(1+ 1)+ 1= 7

因为这需要6一个,所以输出是6

测试用例

 1  1
 2  2
 3  3
 5  5
10  7
20  9
50 12

由于这是一个挑战,因此最少的字节数将获胜。



9
欢迎来到编程难题和Code Golf!作为第一个挑战,这是可以的,但是下一次,请在发布挑战之前使用沙盒,以便获得反馈!
betseg

4
我建议对此进行修改,以明确指出您正在寻找所需的最少数量。否则,仅输出原始数字并声明它是您需要加在一起的数字即可。
粗野的

2
f(x) != x.primeFactorisation().sum()除了1之外,还有其他示例吗?
jrtapsell

1
@jrtapsell:是的。$ f(7)= 6 $的给定示例为1。对于任何(足够大的)素数$ p $,您可以将$ p-1 $分解并加一个。您也许可以做得更好。
罗斯·米利肯

Answers:


17

Python 2中74 70个字节

f=lambda n:min([n]+[f(j)+min(n%j*n+f(n/j),f(n-j))for j in range(2,n)])

在线尝试!

备用版本,59字节(未验证)

f=lambda n:min([n]+[f(j)+f(n/j)+f(n%j)for j in range(2,n)])

这至少可以工作到n = 1,000,000,但是我尚未证明它对所有正数n都有效

在线尝试!


抱歉,如果我缺少一些简单的东西,但是尝试每一个可行的表达式树并不是很明显。特别是,我们有外层n=a*j+bb<j,但我们可能需要b>=j
xnor

嗯,只有b>=j和和都失败b>=a。但是您是对的,这不会发生并不明显。
丹尼斯

有趣的是,没有高达1,000,000的反例,我想知道它是否真的总是有效。我最好的一个反以为会是什么形式的a*b+c*da,b,c,d所有求和表达式都是非常有效的。
xnor

10

果冻16 14字节

感谢Dennis节省了2个字节!

ÆḌḊ,Ṗ߀€+U$FṂo

在线尝试!


逻辑说明

给定数字n

  • 如果是1,答案是1。除此以外:

表示形式是a + ba × b,其中ab是表达式。

考虑所有可能的值ab

  • 如果表示形式为a + b,则ab都在范围内[1 .. n-1]
  • 如果表示形式为a × ba并且bn大于的适当除数1

在这两种情况下,都将[[<proper divisors of n larger than 1>], [1, 2, ..., n-1]]计算列表(ÆḌḊ,Ṗ),将当前链接映射到每个数字߀€,将正确的线对加在一起(+U$)并获得最小值(FṂo)。

代码说明

ÆḌḊ,Ṗ߀€+U$FṂo   Main link. Assume n = 10.
ÆḌ       Proper divisors. [1,2,5]equeue, remove the first element. [2,5]
   ,Ṗ    Pair with op. Auto convert n = 10 to range 
         [1,2,3,4,5,6,7,8,9,10] and remove the last element
         10, get [1,2,3,4,5,6,7,8,9].

߀€      Apply this link over each element.
   +U$   Add with the Upend of itself.

FṂ       Flatten and get the inimum element.
  o      Logical or with n.
         If the list is empty, minimum returns 0 (falsy), so logical or
         convert it to n.

5

JavaScript(ES6),108 96字节

f=n=>n<6?n:Math.min(...[...Array(n-2)].map((_,i)=>Math.min(f(++i)+f(n-i),n%++i/0||f(i)+f(n/i))))

效率很低;Array(n>>1)略微加快了速度,但花费了一个字节。说明:n%++i如果i不是一个因素,n%++i/0则为非零;如果不是一个因素,则为非零Infinity(因此是真实的,并且绝对也不是最小的);如果i是一个因素,NaN则为非零(因此是虚假的)i。编辑:从@ edc65得到启发,保存了12个字节。


我尝试在后台运行此程序,以查看它是否确实可以计算,f(50)但是很遗憾,Windows Update在完成之前重新启动了PC。
尼尔,

您是否尝试过在阵列上进行单步行走?
edc65

@ edc65抱歉,但是我不清楚您的建议以及原因。
尼尔,

我看到2张地图,每张都扫描a阵列。您不能将两个lambda中的评估值合并,然后取最小值吗?
edc65

@ edc65嗯,是的,出于某种原因,我认为嵌套min不会便宜,但是我可以替换(i+=2)另一个,++i所以我总共节省了12个字节,谢谢!
尼尔,


4

Pari / GP,213字节

编辑:我被殴打了

f(n)={d;n<6&return(n);if(n<=#a,a[n]&return(a[n]),a=vector(n));for(i=1,n-1,a[i]||a[i]=f(i));a[n]=min(vecmin(vector(n\2,k,a[k]+a[n-k])),if(isprime(n),n,vecmin(vector((-1+#d=divisors(n))\2,i,a[d[i+1]]+a[d[#d-i]]))))}

在线尝试!




1

Perl 5,-p 78字节

旧式计数中的79个字节(+1用于-p

Perl必须$在所有标量访问中使用额外的事实,这确实会损害高尔夫中进行大量算术运算的时间。

此方法与已发布的其他方法大体相同(尝试乘法和加法以建立目标数,以最便宜的价格)。但是,它不会重复递归递减,因此可以用于较大的输入。

它还没有尝试通过加法或乘法来最小化构建数字的成本,因为perl 5没有内置min函数,而且数值排序也很繁琐(从仍然在代码中的排序可以看出)。相反,我只是假设数字是否是我要使用乘法的目标因素。这是安全的,因为,例如如果3是的因素12(因此它总结的成本312/3)以后在循环会考虑9=12-3这将不会是一个因素,所以9+3具有相同的成本3+9将得到反正尝试。但是,这可能对目标无效<= 4(仅对1和有效2)。添加$_到列表中以最大程度地减少此问题。不幸的是,因为我已经初始化了,所以在基本情况下实际上并不需要它@; 具有正确的起始值,因此它花费3个字节。

#!/usr/bin/perl -p
($_)=sort{$a-$b}$_,map{$;[$_]+$;[$'%$_?$'-$_:$'/$_]}//..$_ for@;=0..$_;$_=pop@

在线尝试!

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.