硬币问题


20

背景

虚构的高尔夫国家的官方货币是foo,并且流通的硬币只有三种:3foos,7foos和8foos。可以看到,使用这些硬币不可能支付一定的金额,例如4 foos。然而,可以形成所有足够大的数量。您的工作是找到硬币无法形成的最大数量(在这种情况下为5个foos),这就是硬币问题

输入项

您的输入是一个正整数列表,代表正在流通的硬币价值。对此有两点保证:L = [n1, n2, ..., nk]

  • 的元素的GCD L为1。
  • L 不包含数字1。

它可能未分类和/或包含重复项(请考虑特别版硬币)。

输出量

由于GCD L为1,所以每个足够大的整数m都可以表示为其元素的非负线性组合。换句话说,我们有

 m = a1*n1 + a2*n2 + ... + ak*nk 

对于一些整数。您的输出是无法以这种形式表示的最大整数。提示一下,已知输出总是小于,如果和是(reference)的最大和最小元素。ai ≥ 0(n1 - 1)*(nk - 1)n1nkL

规则

您可以编写完整的程序或函数。最低字节数获胜,并且不允许出现标准漏洞。如果您的语言对此具有内置操作,则可能无法使用。对时间或内存效率没有任何要求,只是您应该能够在发布答案之前评估测试用例。

在我发布此挑战后,用户@vihan指出Stack Overflow有一个完全相同的副本。基于此元讨论,此挑战将不会被删除。但是,我要求所有基于SO版本的答案都应引用原文,并赋予其社区Wiki状态,如果原始作者希望在此处发布其答案,则将其删除。

测试用例

[3, 7, 8] -> 5
[25, 10, 16] -> 79
[11, 12, 13, 14, 13, 14] -> 43
[101, 10] -> 899
[101, 10, 899] -> 889
[101, 10, 11] -> 89
[30, 105, 70, 42] -> 383
[2, 51, 6] -> 49

5
FrobeniusNumber在Mathematica中。
alephalpha

3
本文中找到了一种更好的上限方法,(p - 1)(q - 1)方法将上限确定为,其中pq是集合中最小和最大的元素。
orlp 2015年

2
运行时间或内存使用量是否有限制?
丹尼斯

1
Stack Overflow上有一个这样的代码高尔夫球问题而回
Downgoat

1
我有一个13字节的Pyth解决方案,可以[2,3]在合理的时间内完成,无其他操作。[2,5]将在内存中创建大约一百万个Python列表。
isaacg 2015年

Answers:


4

Pyth,23个字节

ef!fqTs.b*NYQY^UTlQS*FQ

这非常慢,因为它会检查所有值,直到所有硬币的乘积。这是一个几乎相同的版本,但是1)将硬币的集合减少为彼此不可分割的硬币,以及2)仅检查不超过(max(coins) - 1) * (min(coins) - 1)(47字节)的值:

=Qu?.A<LiHdG+GHGQYef!fqTs.b*NYQY^UTlQS*thSQteSQ

说明

                   S            range 1 to
                    *FQ         product of input
 f                             filter by
               UT                range 0 to T 
              ^  lQ              cartesian power by number of coins
   f                            filter by
      s.b*NYQY                   sum of coin values * amounts
    qT                           equals desired number T
  !                             nothing matching that filter
e                             take last (highest) element

8

Perl,60 54 51字节

50字节代码+ 1字节命令行

$.*=$_,$r.=1x$_."|"}{$_=$.while(1x$.--)=~/^($r)+$/

稍后将进行打高尔夫球并发表说明。基本方法是让正则表达式引擎通过字符串匹配来完成艰苦的工作。例如,它将构建类似于以下内容的正则表达式^(.{3})*(.{7})*(.{8})*$和匹配针对长度的串n,其中n从输入端的产物下降,直到它匹配失败。

请注意,这将随着参数数量的增加而呈指数级降低。

用法:从STDIN(分隔新行)中读取参数,例如:

printf "101\n10" | perl -p entry.pl

3

R84 78字节

要任意输入互质数, 一种1个一种2Frobenius的数量

a=scan();max((1:(b<-min(a)*max(a)))[-colSums(combn(outer(a,0:b),sum(!!a)))])

在线尝试!

因为它总是小于极限值的乘积 一种一世的。那么就需要合并该范围内的所有可能组合(以及更多)。感谢Cole Beck提出outer不带“ *”的建议,以及colSums而不要使用“ apply(...,2,sum)”。

更快但更长(两个字节)的版本仅考虑max(a)

a=scan();max((1:(min(a)*(b<-max(a))))[-apply(combn(outer(a,0:b,"*"),sum(!!a)),2,sum)])

稍短的版本(78个字节)最经常需要太日志或太多空间上运行在线试用

a=scan();max((1:(b<-prod(a)))[-apply(combn(outer(a,0:b,"*"),sum(!!a)),2,sum)])

1

Python2,188个 187字节

def g(L):
 M=max(L);i=r=0;s=[0]*M;l=[1]+s[1:]
 while 1:
    if any(all((l+l)[o:o+min(L)])for o in range(M)):return~-s[r]*M+r
    if any(l[(i-a)%M]for a in L):l[i]=1
    else:r=i
    s[i]+=1;i=(i+1)%M

第二个缩进在SO上呈现为4个空格,这些空格应为制表符。

实际上,这里描述的是一种“快速”的解决方案,而不是蛮力的,使用了“ Wilf方法” 。


1

的Javascript ES6,120 130 126 128 127 125个字符

f=a=>`${r=[1|a.sort((a,b)=>a-b)]}`.repeat(a[0]*a[a.length-1]).replace(/./g,(x,q)=>r[q]|a.map(x=>r[q+x]|=r[q])).lastIndexOf(0)

备用126个字符的版本:

f=a=>{r=[1];a.sort((a,b)=>a-b);for(q=0;q<a[0]*a[a.length-1];++q)r[q]?a.map(x=>r[q+x]=1):r[q]=0;return r.join``.lastIndexOf(0)}

测试:

"[3, 7, 8] -> 5\n\
[25, 10, 16] -> 79\n\
[11, 12, 13, 14, 13, 14] -> 43\n\
[101, 10] -> 899\n\
[101, 10, 899] -> 889\n\
[101, 10, 11] -> 89\n\
[30, 105, 70, 42] -> 383\n\
[2, 51, 6] -> 49".replace(/(\[.*?\]) -> (\d+)/g, function (m, t, r) {
  return f(JSON.parse(t)) == r
})

1
您可以替换forEach(map(
Ypnypn
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.