自求和数字


12

将数字转换为数字总和

没有任何数字:我们需要最短的数字
没有数字:您只能使用数字中的数字

例如
你将被给定为输入的整数n>0

比方说n=27。你要表达27总和,使用仅数字 [2,7],在最短的可能的方式。您不必使用给定数字的所有数字!

所以27=2+2+2+7+7+7。然后我们取这些数字并计数[2,2,2,7,7,7]
的最终答案n=276

对于一个例子n=195,以获得最短的总和,我们必须使用以下数字:
[5,5,5,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]答案23

挑战

给定一个整数n>0,输出与之相加最小位数(包含在数字中)

测试用例

Input->Output

1->1  
2->1  
10->10  
58->8  
874->110  
1259->142  
12347->1765  
123456->20576  
3456789->384088  

这是最短的答案以字节为单位!


有没有数字不能合计/可以输入吗?
斯蒂芬

1
@Stephen他们都可以!

7
@Stephen因为每个数字都可以表示为d_0 + 10 * d_1 + 100 * d_2,等等...
geokavel

我们可以将输入作为字符串,字符数组或整数数组吗?
凯文·克鲁伊森

1
@KevinCruijssen字符串可以。char-array或integer-array不是。

Answers:


4

外壳,12个字节

Lḟo=⁰ΣṁΠḣ∞d⁰

快速处理两位数的数字。 在线尝试!

说明

Lḟo=⁰ΣṁΠḣ∞d⁰  Input is n, say n = 13.
          d⁰  Digits of n: [1,3]
         ∞    Repeat infinitely: [[1,3],[1,3],[1,3],[1,3]...
        ḣ     Prefixes: [[],[[1,3]],[[1,3],[1,3]],[[1,3],[1,3],[1,3]],...
      ṁ       Map and concatenate
       Π      Cartesian product: [[],[1],[3],[1,1],[3,1],[1,3],[3,3],[1,1,1],[3,1,1],...
 ḟo           Find the first element
     Σ        whose sum
   =⁰         equals n: [3,3,3,3,1]
L             Return its length: 5

2

Pyth,12个字节

lef!-TsM`Q./

在线尝试!

不幸的是,它在输入上的内存错误最大为58

说明

lef!-TsM`Q./
          ./    All lists of integers that sum to [the input]
  f             Filter for:
    -TsM`Q           Remove all occurrences of the digits in the input
   !                 Check if falsey (i.e. an empty list)
le              Length of the last occurrence, which is the shortest because all the
                filtered partitions share the same digit pool

您介意添加解释吗?
约拿(Jonah)

@Jonah添加了解释。
notjagan '17

1
谢谢。有趣的是,Pyth具有从本质上解决问题的原语./
约拿(Jonah)

12字节替代lef<.{TjQ;./
格式

2

Mathematica,78个字节

(t=1;While[(s=IntegerPartitions[x=#,t,IntegerDigits@x])=={},t++];Tr[1^#&@@s])&  

在5秒内找到最后一个测试用例


短一些:Length@IntegerPartitions[#, All, Sort@DeleteCases[0]@IntegerDigits@#, 1][[1]] &
库巴(Kuba)

2

R,78个字节

function(n){while(all(F-n)){F=outer(F,n%/%10^(0:nchar(n))%%10,"+")
T=T+1}
T-1}

在线尝试!(高尔夫版)

纯蛮力算法,因此它实际上并不能解决所有测试用例,我认为它尝试为最后一个测试用例分配40,000 GB ...

TR中的默认值是,1因此我们得到了一个一次性的错误,我们在返回步骤中进行了更正,但是我们也得到了F哪个默认值会得到0回报。

空洞的解释:

function(n){
 d <- n%/%10^(0:nchar(n))%%10   # digit list with a 0 appended at end
 d <- unique(d[d>0])            # filter zeros (not technically necessary)
                                # and get unique digits
 x <- 0                         # storage for sums
 i <- 0                         # counter for number of sums done
 while(!any(x==n)){             # until we find a combination
  x <- outer(x,d,"+")           # take all sums of x and d, store as x
  i <- i + 1}                   # increment counter
i}                              # return counter

在线尝试!(更少的高尔夫版本)


2

Python 2中,168个 155 144字节

这不是最短的可能是,但它是最好的,第一,而不是真正的坏,运行时明智的。

n=input()
g=sorted(set(n)-{0})[::-1]
def h(k):
 if k<0:return
 if`k`in g:return 1
 for d in g:
  f=h(k-int(d))
  if f:return 1+f
print h(int(n)) 

filter(None...是去除0的数字,这是我学会了做这个,而我能做到。

最大的问题是python堆栈框架,实际上不允许我在最大的输入上运行它。因此,这不是一个有效的解决方案,实际上,我一直在尝试提高递归限制,这只会导致段错误。这必须通过循环和堆栈来完成,或者要更加聪明才能在python中工作。

编辑:感谢caird和Chas Brown的13个字节!


您可以使用input并要求输入用引号引起来。
caird coinheringaahing

2
只要理论上成功,由于物理的限制而失败是完全可以接受的。
乔纳森·艾伦

替换为filter(None,sorted(map(int,set(n)))[::-1])可以节省9个字节sorted(set(map(int,n))-{0})[::-1](尽管None很高兴知道)。
Chas Brown

@ChasBrown在大多数情况下,您可以使用filter(len,...)列表和字符串以及filter(abs,...)整数和浮点数。
ovs '17


0

JavaScript(ES6),82个字节

f=(n,l=0,a=n,[c,...b]=a)=>n?1/c?Math.min(!+c|+c>n?1/0:f(n-c,l+1,a),f(n,l,b)):1/0:l
<input type=number oninput=o.textContent=f(this.value)><pre id=o>

将输入作为字符串。


您能解释一下为什么使用1/0吗?
扎卡里

1
@Zacharý我想要最短的总和,即最少的数字。导致无效解决方案的尝试绝不能计数,因此要排除它们,它们的得分为Infinity,这不会影响最小值。
尼尔

哦,没有意识到这是递归的。
扎卡里

@Zacharý f=开头是一个大提示,因为对于非递归lambda来说不需要它。
尼尔

0

Ruby,70个字节

->n{w,s=n.digits,0;s+=1while !w.product(*[w]*s).find{|x|x.sum==n};s+1}

非常慢,请尝试所有可能的组合来增加大小,直到找到解决方案为止。

感谢Dennis在TIO上使用Ruby 2.4。

在线尝试!


0

果冻,23字节

D;0ṗµḟ€0
ÇS€=µT
Çị1ĿL€Ṃ

在线尝试!

这是如此低效,由于时间限制> _ <,它无法在TIO上的第三个测试案例之后运行。

欢迎打高尔夫球!


0

Python 2中183个 176 172 166 161字节

def f(n,D=0,p=0,b=0):
	D=D or set(map(int,`n`))-{0}
	d=min(D);c=0;D=D-{d}
	q=[p+n/d,b][n%d>0]
	while c<min(D or{0}):q=b=f(n-c*d,D,p+c,b);c+=1
	return[q,b][q>b>0]

在线尝试!

比其他Python回答更长,但是987654321在TIO上不到一秒钟就完成了所有测试用例的组合。

利用以下事实:如果d1<d2是数字,则d2-1 d1总和中最多需要有个(因为的d2实例d1可以用的d1实例替换d2为较短的总和)。因此,按照升序对数字进行排序,最多只能9! = 362880考虑“ 总和” ;和最大递归深度为9(无论的值如何n)。


0

Haskell,91字节

f n=[read[c]|c<-show n,c>'0']#n!!0
s#n|n>0,x:m<-(s#).(n-)=<<s=[1+minimum(x:m)]|1<3=[0|n==0]

在线尝试!用法示例:f 58yields 8。快速输入两位数,输入大时则慢得惊人。

该函数f将输入数字n转换为数字列表,同时过滤出零。然后,此列表及其n自身将传递给该(#)函数,该函数返回单例列表。!!0返回此单例列表的元素。

(#)使用单例和空列表作为选项类型。鉴于输入n=58s=[5,8],这个想法是要减去所有的数字中sn,然后递归应用(#)及支票位导致的步骤,并返回一个最小的数加上这个最小的结果。第一部分由计算(s#).(n-)=<<s,与相同concat(map(s#)(map(n-)s))。因此,在我们的示例中,首先[58-5,58-8]计算,然后是或之后的[[5,8]#53,[5,8]#50]结果。结果在模式上匹配,以确保列表中至少有一个元素(否则失败),然后重新调整1的单例列表以及结果的最小值。如果[[7],[7]][7,7]concatx:mminimumn小于零或递归调用返回一个空列表,我们处于搜索失败的分支中,并且返回了一个空列表。如果n==0分支成功,[0]则返回。


Haskell,101个字节

f n=[d|d<-[9,8..1],show d!!0`elem`show n]#n!!0
s@(d:r)#n|n>=d,[x]<-s#(n-d)=[x+1]|1<3=r#n
s#n=[0|n==0]

在线尝试!一种更有效的方法,在一秒钟内检查所有测试用例。

这次,输入的数字列表按降序计算,这允许(#)尝试尽可能多地使用最大的数字,然后使用第二个最大的数字,以此类推,直到找到解决方案为止。以此方式找到的第一个解决方案也保证是最小的。

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.