代码块


18

代码块

这是一个假设的情况是星期五晚上,你已经邀请了平时的高尔夫哥们参加自己喜欢的爱好:打高尔夫球的代码。但是,由于这是一项耗费人心的工作,因此您需要为团队筹集一些大脑食物,以便您可以尽可能多地打高尔夫球。

现在,每个人最喜欢的小吃是鸡块,但是有一个问题:没有一包能满足每个人的需求的零食。因此,由于您已经处于打高尔夫球的状态,因此您决定创建一个程序,该程序可以弄清楚您必须购买哪些包才能满足每个人的金块需求。

鸡块包装的大小无处不在,并且取决于您在世界上居住的地方,标准大小也有所变化。但是,最近的[服务金块的地方]库存以下尺寸的金块包装:

4, 6, 9, 10, 20, 40

现在,您可能会注意到无法订购某些组合的矿块。例如,11掘金是不可能的,因为没有组合是11完全相等的。但是,您可以43通过获取1包20,1包10,1包9和1包来制作4

20 + 10 + 9 + 4 = 43 (597)

597每个项在哪里平方并加在一起(提示:最佳解决方案将其作为最大值)。当然,还有其他制造方法43,但是如您所知,每包的金块越多,每个金块的价格越便宜。因此,理想情况下,您要购买数量最少的包装,并以最大的数量购买,以最大程度地降低成本。

任务

您应该创建一个程序函数,该程序函数采用与每个人的要求相对应的整数列表。然后,您应该计算并打印出最具成本效益的α订单,以购买鸡肉块。成本效益最高的α阶是每个数量的平方和最高的组合。如果是绝对没有办法买掘金完美,你必须打印一个falsy值,如0FalseImpossible!,或无论是在您的语言版本。

I / O示例:

[2 7 12 4 15 3] => [20 10 9 4]
     1, 1, 2, 1 => False
  6 5 5 5 5 5 9 => 40
      [6, 4, 9] => 9 10
              1 => 0
            199 => 40, 40, 40, 40, 20, 10, 9
              2 => Impossible!

是前400个理想解决方案的列表。请注意,这些格式并未按照我的期望进行格式化,每个tuple都以形式出现(N lots of M)

规则

  1. 没有标准漏洞。
  2. 不使用内置函数来完成全部或大部分任务,例如FrobeniusSolve在Mathematica中。

α-为了举例说明,您也可以通过做43来做4 + 6 + 6 + 9 + 9 + 9 = 43 (319),但这不是最佳选择,因此输出不正确,因为平方和小于我在引言中提到的组合。本质上,较高的平方和=较低的成本=最具成本效益的。


有时间/内存限制吗?
丹尼斯2015年

@Dennis没有时间或内存限制。
卡德2015年

4
实际上是星期四。
mbomb007

4
@ mbomb007敏锐的观察力:P我已经调整了简介。
卡德2015年

2
我需要以某种方式使用鸡的mcnugget定理 ...
拉伸疯子

Answers:


7

Pyth,26 25字节

e+Zo.aNf!-TCM"  
("./sQ

请注意,有一些不可打印的字符。在线尝试:演示。它相当慢(但不比我的26字节解决方案慢)。

说明:

                          implicit: Q = input list
                     sQ   sum(Q)
                   ./     generate all integer partitions
       f                  filter for partitions T, which satisfy:
             "   ("          string containing chars with the ASCII-values of 4,6,9,10,20,40
           CM                convert each char to the ASCII-value
         -T                  remove this numbers from T
        !                    and check, if the resulting list is empty
    o                      order the remaining subsets N by:
     .aN                      the vector length of N (sqrt of sum of squares)
  +Z                       insert 0 at the beginning
 e                         print the last element

Pyth,32个字节

e+Zo.aNfqsTsQysm*]d/sQdCM"  
(

请注意,有一些不可打印的字符。在线尝试:演示 此版本速度更快。它会[6,7,8]在大约一秒钟的时间内找到输入的解决方案,并[30]在大约90秒内找到输入的解决方案。

说明:

                                 implicit: Q = input list
                          "...(  the string containing chars with the ASCII-values of 4,6,9,10,20,40
                        CM       convert each char to the ASCII-value
                m                map each number d to:
                  ]d                create the list [d]
                 *  /sQd            and repeat it sum(Q)/d times
               s                 unfold
              y                  generate all subsets
        f                        filter for subsets T, which satisfy:
         qsTsQ                      sum(Q) == sum(T)
    o                            order the remaining subsets N by:
     .aN                            the vector length of N (sqrt of sum of squares)
  +Z                             insert 0 at the beginning
 e                               print the last element

为什么用平方和的平方根而不是平方和的平方根呢?
mbomb007

1
@ mbomb007,因为没关系。如果a> b,则sqrt(a)> sqrt(b),反之亦然。并且使用该.a方法比平方和求和要短s^R2
雅库布2015年

5

Perl中,175 153

sub f{my$n=$_[0];if(!$n){return 1;}foreach$o(40,20,9,10,6,4){if($n>=$o&&f($n-$o)){print"$o ";return 1;}}return 0;}$n+=$_ for@ARGV;if(!f($n)){print":(";}

从程序参数中获取输入。打印:(如果找不到理想的解决方案。

非高尔夫代码:

sub f
{
    my $n = $_[0];
    if(!$n)
    {
        return 1;
    }
    foreach $o(40,20,9,10,6,4)
    {
        if($n>=$o&&f($n-$o))
        {
            print "$o ";
            return 1;
        }
    }
    return 0;
}

$n += $_ for @ARGV;
if(!f($n))
{
    print ":(";
}

PS:这可能是第一个不需要10分钟即可完成的条目1 2;)

在这里查看。


祝贺到目前为止看来最快的程序!它可能也比我的参考程序快:P我在您的文章底部添加了一个ideone链接,以便人们可以看到输出。
卡德2015年

您的代码可能会产生错误的输出。输入18应打印9 9,而不是4 4 10
丹尼斯

还有其他不正确的输出。如果我没有记错的话,你可以通过交换顺序解决所有问题910
丹尼斯

@丹尼斯,谢谢,解决了!
Thomas Oltmann 2015年

3

CJam,45 29 28字节

q~:+_[40K9A6Z)U]m*_::+@#=0-p

请注意,此方法非常慢且占用大量内存。

CJam解释器中在线尝试。

它可以以5个字节为代价大大加快速度:

q~:+_40/4+[40K9A6Z)U]m*_::+@#=0-p

输入总和的复杂度仍然是指数级的,但这可以在几秒钟内使用在线解释器处理多达159个测试案例,而使用Java解释器处理多达199个测试案例。

CJam解释器中在线尝试。

理念

最优采购(正方形的最大总和)是一个有效的购买(正确数量的熔核的),其具有尽可能多的40的作为可能的,那么多达20的作为可能的,那么多达9的作为可能的(例如,9 9是优选以上10 4 4)等为10的,6的和4的。

在这种方法中,我们生成数组[40 20 9 10 6 4 0]N个副本的笛卡尔积,其中N是所需的块数。N是我们必须购买的数量的(坏)上限。在代码的加速版本中,我们改用N / 40 + 4

由于数组的排序方式,笛卡尔积将以向量[40 ... 40]开头,并以向量[0 ... 0]结束。我们计算具有正确总和(也将具有最佳平方和)的第一个向量的索引,检索对应的数组元素,删除用作占位符的零并打印结果。

如果找不到向量,索引将为-1,因此我们检索[0 ... 0],它将打印一个空数组。

q~                            e# Read from STDIN and evaluate the input.
  :+                          e# Push N, the sum of all elements of the resulting array.
     [40K9A6Z)U]              e# Push B := [40 20 9 10 6 4 0].
    _           m*            e# Push B**N, the array of all vectors of dimension N
                              e# and coordinates in B.
                  _::+        e# Copy and replace each vector by its sum.
                      @#      e# Get the first index of N.
                        =     e# Retrieve the corresponding element.
                         0-p  e# Remove 0's and print.

这可能是少数情况下,手工解决方案比完成代码更快的情况之一。无论如何,都不错:)
Kade

2

朱莉娅126字节

r->(t=filter(i->all(j->j[4,6,9,10,20,40],i),partitions(sum(r)));show(!isempty(t)&&collect(t)[indmax(map(k->sum(k.^2),t))]))

这将创建一个未命名函数,该函数接受数组作为输入,并根据是否存在解决方案将数组或布尔值打印到STDOUT。要给它起个名字,例如f=n->...

取消+说明:

function f(r)
    # Nugget pack sizes
    packs = [4, 6, 9, 10, 20, 40]

    # Filter the set of arrays which sum to the required number of nuggets
    # to those for which each element is a nugget pack
    t = filter(i -> all(j -> jpacks, i), partitions(sum(r)))

    # Print the boolean false if t is empty, otherwise print the array of
    # necessary nugget packs for which the sum of squares is maximal
    show(!isempty(t) && collect(t)[indmax(map(k -> sum(k.^2), t))])
end

例子:

julia> f([1])
false

julia> f([2,7,12,4,15,3])
[20,10,9,4]

1

Python 3-265个字符

import itertools as i
n=list(map(int,input().split(',')));m=[]
for f in range(1,9):
 for j in range(6*f):
  for x in i.combinations((4,6,9,10,20,40,)*f,j+1):
   if sum(n)==sum(x):m.append(x)
if m!=[]:v=[sum(l**2for l in q)for q in m];print(m[v.index(max(v))])
else:print(0)

显示间距:

import itertools as i
n=list(map(int,input().split(',')));m=[]
for f in range(1,5):
 for j in range(6*f):
\tfor x in i.combinations((4,6,9,10,20,40,)*f,j+1):
\t if sum(n)==sum(x):m.append(x)
\t\tif m!=[]:v=[sum(l**2for l in q)for q in m];print(m[v.index(max(v))])
else:print(0)

通过所有测试用例

注意:我不知道这是否会通过所有情况,因为它太慢了……但是应该 ……


现在看来,这没什么问题,我将对其进行测试,然后看看。到家后,我将添加一个参考的,无高尔夫球程序,该程序用于生成要点中的列表。虽然我没有安排时间,但我相信所有情况下都需要8到12分钟的时间。
卡德,2015年

@ Vioz-太好了!:D
Beta Decay 2015年

看起来我可能是错的,在测试36之后,它会遇到大约4000万个组合(准确地说是40,007,602个),然后才遇到MemoryError错误。但是,这可能是我的工作机器的一个限制,因为它只有4GB的内存。
卡德2015年

@ Vioz- Hm ...好吧,我对我的手机进行测试毫无希望...
Beta Decay 2015年

1
@undergroundmonorail如果只使用一次,则对于<= 4个字符,直接导入会更好(甚至5个中断)。但是,如果您多次使用它,那from blah import*总是最好的。我唯一想到的就是,如果您有多个imports,这是唯一可以想到as的实际位置。
Sp3000

1

JavaScript中,261 256 261

d="length";function g(a){for(z=y=0;y<a[d];z+=+a[y++]);return z}x=[40,20,10,9,6,4];l=prompt().split(",");o=g(l);p=[];for(i=0;i<x[d];i++)r=g(p),s=r+x[i],(s<o-3||s==o)&&p.push(x[i]),(i==x[d]-1||40<o-r)&&r+x[i]<o-3&&(i=-1,0==i||o-r<p[p[d]-1]&&p.pop());g(p)==o&&p||0

我不确定这是否可以正常工作,但我肯定会遗漏一些东西。

不过,它似乎并不慢,直到立即123456输出为止[40 x 3086, 10, 6]

说明:

遍历金块大小(从大到大)

  • 如果堆栈加金块大小的总和小于目标-3->将其压入堆栈
  • 如果剩余数量超过40->重置循环计数器
  • 如果在达到最后一个块大小时堆栈的总和大于目标->弹出最后一个元素,请重置循环计数器
  • 如果堆栈的总和相加,则将其返回,否则返回0

199 | 1构建的堆栈如下所示

i | stack
0   [40]
0   [40, 40]
0   [40, 40, 40]
0   [40, 40, 40, 40]
0   [40, 40, 40, 40]
1   [40, 40, 40, 40, 20]
2   [40, 40, 40, 40, 20, 10]
3   [40, 40, 40, 40, 20, 10, 9]
4   [40, 40, 40, 40, 20, 10, 9]
5   [40, 40, 40, 40, 20, 10, 9]
==> [40, 40, 40, 40, 20, 10, 9]

对于1

i | stack
0   []
1   []
2   []
3   []
4   []
5   []
==> 0

1
您的方法似乎无法检查是否可以实现目标。11打印[6]18打印[10, 4]
丹尼斯

@Dennis嘿,谢谢你指出这一点。昨天已经很晚了。固定为5个字符。[10,4]因为我缺少一对parens,所以打印了18张。检查的确是错误的,我只是检查结果集中是否至少有一个元素,而不是是否总结正确。我不知道我当时
C5H8NNaO4 2015年
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.