及时分箱


12

这项挑战中的任务是将数组的元素放入时间仓。输入将是一个非递减的正整数数组,该整数表示事件的时间,而整数则表示每个bin的大小。让我们从一个例子开始。我们称为输入数组A和输出数组O

`A = [1,1,1,2,7,10]` and `bin_size = 2`.

`O = [4,0,0,1,1]`.

为什么呢 使用a bin_size = 2,我们将具有以下间隔:在第一个间隔内(0,2], (2,4], (4,6], (6,8], (8,10]有四个项目,在第二个和第三个间隔(1,1,1,2)(0,2]没有一个7,在间隔中(6,8]一个10,在间隔中一个(8,10]

您的代码应考虑bin_size从开始的每个长度间隔,0并计算每个间隔中A有多少个数字。您应始终将区间的右端包括在bin中,因此在上面的示例2中将其包括在中4。您的代码应在输入和输出长度之和的线性时间内运行。

更多示例:

`A = [1,2,7,12,15]`  and `bin_size = 5`.

`O = [2, 1, 2]`.

`A = [1,2,7,12,15]`  and `bin_size = 3`.

`O = [2,0,1,1,1]`.

您可以假定输入和输出可以以您认为方便的任何格式给出。您可以使用任何喜欢的语言和库。


是否0允许输出尾随s?那么返回[2,0,1,1,1,0]而不是[2,0,1,1,1]
凯文·克鲁伊森

请不要尾随零。

2
对于最大数组值不是的倍数的情况该怎么办bin_size,我们应该真正处理这些吗?似乎大多数答案都可以,但是如果是这样,那么最好为此场景添加一个测试用例以防止混淆。
基里尔·L.18年

@KirillL。是的,也应该处理它们。

1
@GPS 0不是正整数。这不是意外:)

Answers:


9

R,48个字节

function(n,s)table(cut(n,0:ceiling(max(n)/s)*s))

在线尝试!

再次,table并做cut一个factor很好的装箱技巧。输出一个名为的vector,其中names表示间隔,以间隔符号表示,例如(0,5]

编辑:恢复到s不分割时可以使用的早期版本n


我的确不是R,但是在TIO上似乎format you [most likely do not] find convenient没有该table部分就输出a 。
我的代名词是monicareinstate,

@someone正是它在那里的原因。cut将向量分为间隔给定的因子,并table计算其输入中每个唯一值的出现次数。
朱塞佩

1
@某人啊,我明白了,我误解了你的评论。不,我认为那将是无效的,因为我们需要每个垃圾箱的数量。
朱塞佩

1
不完全测试,但我认为你可以保存几个字节reaplacing 0:ceiling(max(n)/s)*sseq(0,max(n)+s-1,s)。它至少对问题中的两个样本有效。
格雷戈尔·托马斯

1
@Gregor Hmm如果可行的话1:max(n/s+1)*s-s是另一个改进,因为两者是等效的
Giuseppe



3

Python 2,62个字节

I,s=input()
B=[0]*(~-I[-1]/s+1)
for i in I:B[~-i/s]+=1
print B

在线尝试!


1
首先:好的答案,我已经对其进行了+1处理(并在Java中创建了一个端口,因为它比我的端口要短得多)。但是,尾随零是不允许的(只是问问OP),因此I[-1]/s+1应该~-I[-1]/s+1改为。
凯文·克鲁伊森

@KevinCruijssen感谢您的通知!
Dead Possum

3

05AB1E,18个字节

θs/Å0¹vDyI/î<©è>®ǝ

在线尝试!


我不太了解05AB1E,但这似乎叫A.count max(A),所以运行时间在len(A)+ len(O)中不是线性的。那是正确的还是我做错了什么?
丹尼斯

@Dennis计数将是O(max(A)*max(A))...所以它在A的最大值上是二次的... OP指定它必须在...方面是线性的...究竟是什么?
Magic Octopus Urn

2
@MagicOctopusUrn 根据最新版本,您的代码应按输入和输出长度之和的线性时间运行
丹尼斯

2
@丹尼斯似乎相当武断。
Magic Octopus Urn

2
@MagicOctopusUrn这是我认为这个问题的唯一合理的线性时间定义。

2

APL + WIN,23个字节

提示屏幕输入箱,然后输入整数向量:

+⌿<\v∘.≤b×⍳⌈⌈/(v←⎕)÷b←⎕    

说明:

⎕ Prompt for input

⌈⌈/(v←⎕)÷b←⎕ divide the integers by bin size, take maximum and round up for number of bins

b×⍳ take number of bins from previous step and create a vector of bin upper boundaries

v∘.≤ apply outer product to generate boolean matrix where elements of vector ≤ boundaries

<\ switch off all 1's after first 1 in each row to filter multiple bin allocations

+⌿ sum columns for the result


2

Java 8,75字节

a->b->{var r=new int[~-a[a.length-1]/b+1];for(int i:a)r[~-i/b]++;return r;}

@DeadPossum的Python 2 Answer的端口,因此请确保对他的答案进行投票

说明:

在线尝试。

a->b->{          // Method with integer-array and integer parameters and no return-type
  var r=new int[~-a[a.length-1]/b+1];
                 //  Result integer-array of size `((last_item-1)/bin_length)+1`
  for(int i:a)   //  Loop over the input-array
    r[~-i/b]++;  //   Increase the value at index `(i+1)/bin_length` by 1
  return r;}     //  Return the result-array


2

JavaScript(ES6),60字节/ O(len(a)+ max(a)/ n)

@Neil节省了5个字节

以currying语法接受输入(a)(n)

a=>n=>[...a.map(x=>o[x=~-x/n|0]=-~o[x],o=[])&&o].map(n=>~~n)

在线尝试!

如果允许空元素,则仅为43个字节 / O(len(a))


[...o].map(n=>n|0)从第二个解决方案中获取较少字节的第一个输出。
尼尔

@Neil不知道为什么我要去做这么复杂的事情。:-/
Arnauld

2

Haskell63 75 70字节

l!n=l#[n,2*n..]
[]#_=[]
l#(b:i)|h<-length$takeWhile(<=b)l=h:drop h l#i

糟糕,这个较短的不是线性的,而是二次的;

l!n=l#[n,2*n..]
[]#_=[]
l#(b:i)=sum[1|a<-l,a<=b]:[a|a<-l,a>b]#i

在线尝试!


1

Pyth,23 22字节

Jm/tdeQhQK*]ZheJhXRK1J

在这里尝试

Jm/tdeQhQK*]ZheJhXRK1J
Jm/tdeQhQ                 Find the bin for each time and save them as J.
         K*]ZheJ          Create empty bins.
                 XRK1J    Increment the bins for each time within them.
                h         Take the first (because mapping returned copies).

1

红宝石53 50字节

编辑:-3字节,iamnotmaynard。

->a,b{(0..~-a.max/b).map{|i|a.count{|x|~-x/b==i}}}

在线尝试!


如果a.max不是的倍数b(例如f[[1,1,1,2,7,10],3]=> [4, 0, 1]但应给出[4, 0, 2]),则此方法不起作用。我尝试过相同的方法。
恢复莫妮卡– notmaynard

(或更确切地说[4, 0, 1, 1]
恢复莫妮卡-notmaynard,

嗯,这可以通过切换为float max range值来解决,但是我还将要求OP在任务描述中进行澄清。
基里尔·L.18年


很好,甚至更好,谢谢。
Kirill L.

1

这个难题本质上是计数排序。如果不先进行输入,就无法知道输出的长度。

C(clang),53字节

i,j;f(*A,l,b,*O){for(j=0;j<l;O[(A[j++]+b-1)/b-1]++);}

在线尝试!

此解决方案采用以下参数:用于输出的bin_size 存储的
A输入数组
l长度。必须足够长, 并以O返回输出。
b
O

这个解决方案有一个障碍:它不返回输出数组O的长度,因此调用者不知道要打印多少。

后续版本克服了这一障碍:

C(clang),79字节

i,j,k;f(*A,l,b,*O,*m){for(k=j=0;j<l;O[i=(A[j++]+b-1)/b-1]++,k=k>i?k:i);*m=++k;}

在线尝试!

它需要一个附加参数m并返回其中的长度O。它花费了我26个字节。


1

C(gcc)102 90 89 86字节

#define P!printf("%d ",k)
i,j,k;f(s){for(i=s;~scanf("%d",&j);k++)for(;j>i;i+=s)k=P;P;}

在线尝试!

感谢Kevin Cruijssen削减了12个字节,再加上ceilingcat减少了4个字节!


1
通过使用for循环删除90个字节int,并将更改==1>0
凯文·克鲁伊森

别客气。顺便说一句,只是一个注释,它当前无效(就像我现在删除的Java答案一样)。它必须及时运行O(n),所以您不能有任何嵌套的for循环。.(不过,您的C ++答案似乎还不错。所以我对那个++ 1了。:))
Kevin Cruijssen

它仍然是O(n)。内部循环将始终打印一个值,并且我们只打印总计(最大值+ 1)/ binsize值。
G. Sliepen '18

嗯,但是还不是O(n)通过遍历输入项的外部循环。即使内部循环仅循环2次,也已经高于O(n)。还是我误会了什么。.我必须承认- O时间并不是我真正的专长
。-凯文·克鲁伊森

1
但是,内部循环不会遍历所有输入元素,它只会遍历需要打印的许多输出值以“赶上”最新输入元素所对应的位置。如果输入向量包含大量重复项或值小于bin大小的值,则内部循环将根本不执行任何迭代。另一方面,如果输入向量非常稀疏,则内部循环将执行更多迭代,并打印0。因此,正确的是,代码以O((输入元素的数量)+(最后一个元素/容器的大小))的时间运行。这仍然是线性的。
G. Sliepen '18
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.