将数组放入垃圾箱


12

在这个简单的挑战中,将为您提供L非负整数的输入数组,以及数量b大于0但不超过的长度的bin L。您的代码必须返回一个新数组M,该数组的长度为b,并且已对该数组进行分箱L。用示例最容易解释。

L = [1,0,5,1]然后b = 2返回M = [1,6]

L = [0,3,7,2,5,1]然后b = 3返回M = [3,9,6]

到目前为止,如此简单。但是,在这个问题b上并不一定要分开len(L)。在这种情况下,最后一个垃圾箱将只有更少的数字可以组成。

除可能的最后一个垃圾箱外,每个垃圾箱必须具有相同数量的数字,以构成其总数。最后一个垃圾箱所贡献的号码不得超过其他垃圾箱。在其他规则的约束下,最后一个bin必须具有尽可能多的数字。

L = [0,3,7,2,5,1]然后b = 4返回M = [3,9,6,0]M = [10,8,0,0]是不可接受的输出,因为第三个bin的名称编号不包含在bin 1和中2

L = [0,3,7,2,5]然后b = 2返回M = [10,7]M = [3, 14]不是可接受的输出,因为最后一个bin会有3贡献的元素,但是第一个只有2

L = [1,1,1,1,1,1,1]然后b = 3返回M = [3,3,1]

作为最后一条规则,您的代码必须在线性时间内运行。

您可以使用任何喜欢的语言或库,并且可以假定以您认为方便的任何方式提供了输入。


事实证明,有些输入无法解决。例如[1,1,1,1,1]b=4。您的代码可以输出任何喜欢的输入。


6
我认为再增加一些测试用例会更好。
乔纳森·弗雷希

5
your code must run in linear time-我会发现任何自然不遵循这种算法的算法
Uriel'Mar

2
@Uriel对于奇怪的代码高尔夫球答案可能没有任何限制:)

4
@Lembik虽然以什么方式不允许这种对代码高尔夫球挑战有益的潜在怪异方法?
乔纳森·弗雷希

@JonathanFrech取决于OP的偏好:)

Answers:


5

APL(Dyalog),19字节

{+/⍺(⌈⍺÷⍨≢⍵)⍴⍵,⍺⍴0}

在线尝试!

我们将b的零附加到数组上,然后将其重整⌈⍺÷⍨≢⍵(的长度L÷b⌉)的相等部分,并对它们求和,如中所示,⍺⍴0,因为任何数量大于b的空白点(不是原始数组的一部分)-1将至少填充b-1个其他块中的元素,这使得最后一组的平衡点与其余部分的最大b-1相差。我们使用b> b-1,因为它是代码高尔夫球。

例如,具有15个元素且b = 3的L不会被分组为

x x x x x x
x x x x x x
x x x 0 0 0

而是作为(请注意最右边的2如何x“填充”最左边的零)

x x x x x
x x x x x
x x x x x

16个元素的数组将填充23-1)个空白点,例如

x x x x x x
x x x x x x
x x x x 0 0


3

R75 71 70 63字节

function(L,b)colSums(matrix(L[1:(ceiling(sum(L|1)/b)*b)],,b),T)

在线尝试!

这会填充LNA直到长度为的倍数b,然后将的列总和L作为具有b列的矩阵,从而删除NA值。

解释为基于堆栈的语言:

function(L,b){
      (ceiling(sum(L|1)/b*b)  # push the next multiple of b >= length(L), call it X
    1:..                      # push the range 1:X
  L[..]                       # use this as an index into L. This forces L
                              # to be padded to length X with NA for missing values
        matrix(..,,b)         # create a matrix with b columns, using L for values
                              # and proceeding down each column, so
                              # matrix(1:4,,2) would yield [[1,3],[2,4]]
colSums(.., na.rm = T)        # sum each column, removing NAs


非常好,快捷!R编码器的兴起...

2
@Lembik我很幸运能跳进TNB,在您说“我将把它发布为挑战”和您实际上在发布它之间。
朱塞佩

1
哦,看起来“ length [<-”也会像我们最喜欢的伙伴“ [<-””一样返回。没有保存字节以降低可读性:function(L,b)colSums(matrix("length<-"(L,ceiling(length(L)/b)*b),,b),T)
Vlo

1
@Vlo no bytes saved for less readability可能是R打高尔夫球的座右铭...虽然我认为那sum(L|1)是从保存的字节length(L)
朱塞佩

3

MATL,6个字节

vi3$es

在线尝试!验证所有测试用例

说明

考虑输入4[0,3,7,2,5,1]作为一个例子。

v       % Vertically concatenate stack contents. Gives the empty array, []
        % STACK: []
i       % Input b
        % STACK: [], 4
        % Implicitly input L at the bottom of the stack
        % STACK: [0,3,7,2,5,1], [], 4
3$e     % 3-input reshape. This reshapes L with [] rows and b columns, in
        % column-major order (down, then across). [] here means that the
        % number of rows is chosen as needed to give b columns. Padding
        % with trailing zeros is applied if needed
        % STACK: [0 7 5 0;
                  3 2 1 0]
s       % Sum of each column
        % STACK: [3 9 6 0]
        % Implicitly display

1
我认为这是最令人印象深刻的答案。




2

Java 10、96 89 86字节

a->b->{int r[]=new int[b],i=0,n=a.length;for(;i<n;)r[i/((n+b-1)/b)]+=a[i++];return r;}

在这里在线尝试。

在这里找到了一种较短的书写方式i/(n/b+(n%b==0?0:1) i/((n+b-1)/b)

感谢OlivierGrégoire打高尔夫球3个字节。

非高尔夫版本:

input -> bins -> { // input is int[] (original array), bins is int (number of bins)
    int result[] = new int[bins], // resulting array, initialized with all 0
    i = 0, // for iterating over the original array
    n = a.length; // length of the original array
    for(; i < n ;) // iterate over the original array
        result[i / ((n + bins - 1) / bins)] += input[i++]; // add the element to the right bin; that's bin n/bins if bins divides n, floor(n/bins)+1 otherwise
    return result;
}


@OlivierGrégoire谢谢!
OOBalance

1

灵药,98字节

fn l,b->Enum.map Enum.chunk(l++List.duplicate(0,b-1),round Float.ceil length(l)/b),&Enum.sum/1 end

在线尝试!

最好的长生不老药可以分成长度为n的部分。而且它不能将ceil除法很好地作为整数,因此我们进行float除法,将其四舍五入。不幸的是,唯一的方法是产生浮点数,因此我们再次将其四舍五入为整数。


您的某些输出的长度错误。

@Lembik修复了它。
Okx

1

Perl 6的 52个51  50字节

52字节:测试

->\L,\b{L.rotor(:partial,ceiling L/b)[^b].map: &sum}

51字节:测试

{@^a.rotor(:partial,ceiling @a/$^b)[^$b].map: &sum}

50个字节:尝试一下

{map &sum,@^a.rotor(:partial,ceiling @a/$^b)[^$b]}

47字节无竞争测试

{@^a.rotor(:partial,ceiling @a/$^b)[^$b]».sum}

这是不竞争的,因为».sum它允许并行执行计算。因此,它可能不是线性时间。


展开:

{  # bare block with two placeholder parameters 「@a」 and 「$b」

  map                   # for each sublist

    &sum,               # find the sum


    @^a                 # declare and use first parameter

    .rotor(             # break it into chunks

      :partial,         # include trailing values that would be too few otherwise

      ceiling @a / $^b # the number of elements per chunk

    )[ ^$b ]           # get the correct number of chunks if it would be too few

}

1

木炭,22字节

NθAηW﹪Lηθ⊞η⁰E⪪η÷LηθIΣι

在线尝试!链接是详细版本的代码。说明:

Nθ

输入b

Aη

输入L

W﹪Lηθ⊞η⁰

0L直到其L长度可被整除b

E⪪η÷LηθIΣι

L的长度除以该长度b并分成L该长度的各个部分,然后将每个部分相加并转换为字符串,以便在单独的行上隐式输出。



1

C(clang),58个字节

i;f(*L,l,b,*m){b=l/b+!!(l%b);for(i=0;i<l;m[i++/b]+=L[i]);}

在线尝试!

f()采用如下参数
L::指向输入数组的指针:输入数组的
l长度
b:箱数
m:指向接收新数组的缓冲区的指针

以下是@ 60字节的可重入版本:

f(*L,l,b,*m){b=l/b+!!(l%b);for(int i=0;i<l;m[i++/b]+=L[i]);}

1

PHP,88字节

function($a,$b){return array_map(array_sum,array_chunk($a,~-count($a)/$b+1))+[$b-1=>0];}

匿名函数,采用数组和整数,返回数组

唯一的高尔夫潜力这不得不被替换ceil(count($a)/$b))(count($a)-1)/$b+1和缩写(count($a)-1)~-count($a)。结果浮点数在array_chunk调用中隐式转换为整数。

在线尝试

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.